diff --git a/lib/client/client-handshake.c b/lib/client/client-handshake.c index f3593e6e..ff98dc02 100644 --- a/lib/client/client-handshake.c +++ b/lib/client/client-handshake.c @@ -710,11 +710,22 @@ lws_client_connect_via_info(struct lws_client_connect_info *i) * not even be able to get ahold of an ah at this point. */ - /* -1 means just use latest supported */ - if (i->ietf_version_or_minus_one != -1 && i->ietf_version_or_minus_one) - v = i->ietf_version_or_minus_one; + if (!i->method) { /* ie, ws */ + /* allocate the ws struct for the wsi */ + wsi->ws = lws_zalloc(sizeof(*wsi->ws), "client ws struct"); + if (!wsi->ws) { + lwsl_notice("OOM\n"); + goto bail; + } + + /* -1 means just use latest supported */ + if (i->ietf_version_or_minus_one != -1 && + i->ietf_version_or_minus_one) + v = i->ietf_version_or_minus_one; + + wsi->ws->ietf_spec_revision = v; + } - wsi->ietf_spec_revision = v; wsi->user_space = NULL; wsi->state = LWSS_CLIENT_UNCONNECTED; wsi->pending_timeout = NO_PENDING_TIMEOUT; diff --git a/lib/client/client-parser.c b/lib/client/client-parser.c index 0e42dac3..bc391cba 100644 --- a/lib/client/client-parser.c +++ b/lib/client/client-parser.c @@ -34,7 +34,7 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) struct lws_tokens eff_buf; unsigned char *pp; - if (wsi->u.ws.rx_draining_ext) { + if (wsi->ws->rx_draining_ext) { assert(!c); eff_buf.token = NULL; eff_buf.token_len = 0; @@ -51,35 +51,35 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) switch (wsi->lws_rx_parse_state) { case LWS_RXPS_NEW: /* control frames (PING) may interrupt checkable sequences */ - wsi->u.ws.defeat_check_utf8 = 0; + wsi->ws->defeat_check_utf8 = 0; - switch (wsi->ietf_spec_revision) { + switch (wsi->ws->ietf_spec_revision) { case 13: - wsi->u.ws.opcode = c & 0xf; + wsi->ws->opcode = c & 0xf; /* revisit if an extension wants them... */ - switch (wsi->u.ws.opcode) { + switch (wsi->ws->opcode) { case LWSWSOPC_TEXT_FRAME: - wsi->u.ws.rsv_first_msg = (c & 0x70); - wsi->u.ws.continuation_possible = 1; - wsi->u.ws.check_utf8 = lws_check_opt( + wsi->ws->rsv_first_msg = (c & 0x70); + wsi->ws->continuation_possible = 1; + wsi->ws->check_utf8 = lws_check_opt( wsi->context->options, LWS_SERVER_OPTION_VALIDATE_UTF8); - wsi->u.ws.utf8 = 0; + wsi->ws->utf8 = 0; break; case LWSWSOPC_BINARY_FRAME: - wsi->u.ws.rsv_first_msg = (c & 0x70); - wsi->u.ws.check_utf8 = 0; - wsi->u.ws.continuation_possible = 1; + wsi->ws->rsv_first_msg = (c & 0x70); + wsi->ws->check_utf8 = 0; + wsi->ws->continuation_possible = 1; break; case LWSWSOPC_CONTINUATION: - if (!wsi->u.ws.continuation_possible) { + if (!wsi->ws->continuation_possible) { lwsl_info("disordered continuation\n"); return -1; } break; case LWSWSOPC_CLOSE: - wsi->u.ws.check_utf8 = 0; - wsi->u.ws.utf8 = 0; + wsi->ws->check_utf8 = 0; + wsi->ws->utf8 = 0; break; case 3: case 4: @@ -94,45 +94,45 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) lwsl_info("illegal opcode\n"); return -1; default: - wsi->u.ws.defeat_check_utf8 = 1; + wsi->ws->defeat_check_utf8 = 1; break; } - wsi->u.ws.rsv = (c & 0x70); + wsi->ws->rsv = (c & 0x70); /* revisit if an extension wants them... */ if ( #ifndef LWS_NO_EXTENSIONS !wsi->count_act_ext && #endif - wsi->u.ws.rsv) { + wsi->ws->rsv) { lwsl_info("illegal rsv bits set\n"); return -1; } - wsi->u.ws.final = !!((c >> 7) & 1); + wsi->ws->final = !!((c >> 7) & 1); lwsl_ext("%s: This RX frame Final %d\n", __func__, - wsi->u.ws.final); + wsi->ws->final); - if (wsi->u.ws.owed_a_fin && - (wsi->u.ws.opcode == LWSWSOPC_TEXT_FRAME || - wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME)) { + if (wsi->ws->owed_a_fin && + (wsi->ws->opcode == LWSWSOPC_TEXT_FRAME || + wsi->ws->opcode == LWSWSOPC_BINARY_FRAME)) { lwsl_info("hey you owed us a FIN\n"); return -1; } - if ((!(wsi->u.ws.opcode & 8)) && wsi->u.ws.final) { - wsi->u.ws.continuation_possible = 0; - wsi->u.ws.owed_a_fin = 0; + if ((!(wsi->ws->opcode & 8)) && wsi->ws->final) { + wsi->ws->continuation_possible = 0; + wsi->ws->owed_a_fin = 0; } - if ((wsi->u.ws.opcode & 8) && !wsi->u.ws.final) { + if ((wsi->ws->opcode & 8) && !wsi->ws->final) { lwsl_info("control msg can't be fragmented\n"); return -1; } - if (!wsi->u.ws.final) - wsi->u.ws.owed_a_fin = 1; + if (!wsi->ws->final) + wsi->ws->owed_a_fin = 1; - switch (wsi->u.ws.opcode) { + switch (wsi->ws->opcode) { case LWSWSOPC_TEXT_FRAME: case LWSWSOPC_BINARY_FRAME: - wsi->u.ws.frame_is_binary = wsi->u.ws.opcode == + wsi->ws->frame_is_binary = wsi->ws->opcode == LWSWSOPC_BINARY_FRAME; break; } @@ -141,31 +141,31 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) default: lwsl_err("unknown spec version %02d\n", - wsi->ietf_spec_revision); + wsi->ws->ietf_spec_revision); break; } break; case LWS_RXPS_04_FRAME_HDR_LEN: - wsi->u.ws.this_frame_masked = !!(c & 0x80); + wsi->ws->this_frame_masked = !!(c & 0x80); switch (c & 0x7f) { case 126: /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) + if (wsi->ws->opcode & 8) goto illegal_ctl_length; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; break; case 127: /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) + if (wsi->ws->opcode & 8) goto illegal_ctl_length; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; break; default: - wsi->u.ws.rx_packet_length = c; - if (wsi->u.ws.this_frame_masked) + wsi->ws->rx_packet_length = c; + if (wsi->ws->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; else { @@ -182,16 +182,16 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) break; case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->u.ws.rx_packet_length = c << 8; + wsi->ws->rx_packet_length = c << 8; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; break; case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->u.ws.rx_packet_length |= c; - if (wsi->u.ws.this_frame_masked) + wsi->ws->rx_packet_length |= c; + if (wsi->ws->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; else { - if (wsi->u.ws.rx_packet_length) + if (wsi->ws->rx_packet_length) wsi->lws_rx_parse_state = LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; else { @@ -208,56 +208,56 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) return -1; } #if defined __LP64__ - wsi->u.ws.rx_packet_length = ((size_t)c) << 56; + wsi->ws->rx_packet_length = ((size_t)c) << 56; #else - wsi->u.ws.rx_packet_length = 0; + wsi->ws->rx_packet_length = 0; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; break; case LWS_RXPS_04_FRAME_HDR_LEN64_7: #if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 48; + wsi->ws->rx_packet_length |= ((size_t)c) << 48; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; break; case LWS_RXPS_04_FRAME_HDR_LEN64_6: #if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 40; + wsi->ws->rx_packet_length |= ((size_t)c) << 40; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; break; case LWS_RXPS_04_FRAME_HDR_LEN64_5: #if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 32; + wsi->ws->rx_packet_length |= ((size_t)c) << 32; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; break; case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 24; + wsi->ws->rx_packet_length |= ((size_t)c) << 24; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; break; case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 16; + wsi->ws->rx_packet_length |= ((size_t)c) << 16; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; break; case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 8; + wsi->ws->rx_packet_length |= ((size_t)c) << 8; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; break; case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->u.ws.rx_packet_length |= (size_t)c; - if (wsi->u.ws.this_frame_masked) + wsi->ws->rx_packet_length |= (size_t)c; + if (wsi->ws->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; else { - if (wsi->u.ws.rx_packet_length) + if (wsi->ws->rx_packet_length) wsi->lws_rx_parse_state = LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; else { @@ -268,32 +268,32 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) break; case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->u.ws.mask[0] = c; + wsi->ws->mask[0] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; break; case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->u.ws.mask[1] = c; + wsi->ws->mask[1] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; break; case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->u.ws.mask[2] = c; + wsi->ws->mask[2] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; break; case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->u.ws.mask[3] = c; + wsi->ws->mask[3] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; - if (wsi->u.ws.rx_packet_length) + if (wsi->ws->rx_packet_length) wsi->lws_rx_parse_state = LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; else { @@ -304,17 +304,17 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - assert(wsi->u.ws.rx_ubuf); + assert(wsi->ws->rx_ubuf); - if (wsi->u.ws.rx_draining_ext) + if (wsi->ws->rx_draining_ext) goto drain_extension; - if (wsi->u.ws.this_frame_masked && !wsi->u.ws.all_zero_nonce) - c ^= wsi->u.ws.mask[(wsi->u.ws.mask_idx++) & 3]; + if (wsi->ws->this_frame_masked && !wsi->ws->all_zero_nonce) + c ^= wsi->ws->mask[(wsi->ws->mask_idx++) & 3]; - wsi->u.ws.rx_ubuf[LWS_PRE + (wsi->u.ws.rx_ubuf_head++)] = c; + wsi->ws->rx_ubuf[LWS_PRE + (wsi->ws->rx_ubuf_head++)] = c; - if (--wsi->u.ws.rx_packet_length == 0) { + if (--wsi->ws->rx_packet_length == 0) { /* spill because we have the whole frame */ wsi->lws_rx_parse_state = LWS_RXPS_NEW; goto spill; @@ -325,11 +325,11 @@ int lws_client_rx_sm(struct lws *wsi, unsigned char c) * supposed to default to context->pt_serv_buf_size */ if (!wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_ubuf_head != wsi->context->pt_serv_buf_size) + wsi->ws->rx_ubuf_head != wsi->context->pt_serv_buf_size) break; if (wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_ubuf_head != wsi->protocol->rx_buffer_size) + wsi->ws->rx_ubuf_head != wsi->protocol->rx_buffer_size) break; /* spill because we filled our rx buffer */ @@ -342,14 +342,14 @@ spill: * layer? If so service it and hide it from the user callback */ - switch (wsi->u.ws.opcode) { + switch (wsi->ws->opcode) { case LWSWSOPC_CLOSE: - pp = (unsigned char *)&wsi->u.ws.rx_ubuf[LWS_PRE]; + pp = (unsigned char *)&wsi->ws->rx_ubuf[LWS_PRE]; if (lws_check_opt(wsi->context->options, LWS_SERVER_OPTION_VALIDATE_UTF8) && - wsi->u.ws.rx_ubuf_head > 2 && - lws_check_utf8(&wsi->u.ws.utf8, pp + 2, - wsi->u.ws.rx_ubuf_head - 2)) + wsi->ws->rx_ubuf_head > 2 && + lws_check_utf8(&wsi->ws->utf8, pp + 2, + wsi->ws->rx_ubuf_head - 2)) goto utf8_fail; /* is this an acknowledgement of our close? */ @@ -363,8 +363,8 @@ spill: } lwsl_parser("client sees server close len = %d\n", - wsi->u.ws.rx_ubuf_head); - if (wsi->u.ws.rx_ubuf_head >= 2) { + wsi->ws->rx_ubuf_head); + if (wsi->ws->rx_ubuf_head >= 2) { close_code = (pp[0] << 8) | pp[1]; if (close_code < 1000 || close_code == 1004 || @@ -384,7 +384,7 @@ spill: wsi->protocol->callback, wsi, LWS_CALLBACK_WS_PEER_INITIATED_CLOSE, wsi->user_space, pp, - wsi->u.ws.rx_ubuf_head)) + wsi->ws->rx_ubuf_head)) return -1; if (lws_partial_buffered(wsi)) @@ -401,8 +401,8 @@ spill: * immediately afterwards */ lws_write(wsi, (unsigned char *) - &wsi->u.ws.rx_ubuf[LWS_PRE], - wsi->u.ws.rx_ubuf_head, + &wsi->ws->rx_ubuf[LWS_PRE], + wsi->ws->rx_ubuf_head, LWS_WRITE_CLOSE); wsi->state = LWSS_RETURNED_CLOSE_ALREADY; /* close the connection */ @@ -410,13 +410,13 @@ spill: case LWSWSOPC_PING: lwsl_info("received %d byte ping, sending pong\n", - wsi->u.ws.rx_ubuf_head); + wsi->ws->rx_ubuf_head); /* he set a close reason on this guy, ignore PING */ - if (wsi->u.ws.close_in_ping_buffer_len) + if (wsi->ws->close_in_ping_buffer_len) goto ping_drop; - if (wsi->u.ws.ping_pending_flag) { + if (wsi->ws->ping_pending_flag) { /* * there is already a pending ping payload * we should just log and drop @@ -426,30 +426,30 @@ spill: } /* control packets can only be < 128 bytes long */ - if (wsi->u.ws.rx_ubuf_head > 128 - 3) { + if (wsi->ws->rx_ubuf_head > 128 - 3) { lwsl_parser("DROP PING payload too large\n"); goto ping_drop; } /* stash the pong payload */ - memcpy(wsi->u.ws.ping_payload_buf + LWS_PRE, - &wsi->u.ws.rx_ubuf[LWS_PRE], - wsi->u.ws.rx_ubuf_head); + memcpy(wsi->ws->ping_payload_buf + LWS_PRE, + &wsi->ws->rx_ubuf[LWS_PRE], + wsi->ws->rx_ubuf_head); - wsi->u.ws.ping_payload_len = wsi->u.ws.rx_ubuf_head; - wsi->u.ws.ping_pending_flag = 1; + wsi->ws->ping_payload_len = wsi->ws->rx_ubuf_head; + wsi->ws->ping_pending_flag = 1; /* get it sent as soon as possible */ lws_callback_on_writable(wsi); ping_drop: - wsi->u.ws.rx_ubuf_head = 0; + wsi->ws->rx_ubuf_head = 0; handled = 1; break; case LWSWSOPC_PONG: lwsl_info("client receied pong\n"); - lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE], - wsi->u.ws.rx_ubuf_head); + lwsl_hexdump(&wsi->ws->rx_ubuf[LWS_PRE], + wsi->ws->rx_ubuf_head); if (wsi->pending_timeout == PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) { @@ -468,7 +468,7 @@ ping_drop: default: - lwsl_parser("Reserved opc 0x%2X\n", wsi->u.ws.opcode); + lwsl_parser("Reserved opc 0x%2X\n", wsi->ws->opcode); /* * It's something special we can't understand here. @@ -476,16 +476,16 @@ ping_drop: * state machine. */ - eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE]; - eff_buf.token_len = wsi->u.ws.rx_ubuf_head; + eff_buf.token = &wsi->ws->rx_ubuf[LWS_PRE]; + eff_buf.token_len = wsi->ws->rx_ubuf_head; if (lws_ext_cb_active(wsi, LWS_EXT_CB_EXTENDED_PAYLOAD_RX, &eff_buf, 0) <= 0) { /* not handled or failed */ lwsl_ext("Unhandled ext opc 0x%x\n", - wsi->u.ws.opcode); - wsi->u.ws.rx_ubuf_head = 0; + wsi->ws->opcode); + wsi->ws->rx_ubuf_head = 0; return 0; } @@ -501,10 +501,10 @@ ping_drop: if (handled) goto already_done; - eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE]; - eff_buf.token_len = wsi->u.ws.rx_ubuf_head; + eff_buf.token = &wsi->ws->rx_ubuf[LWS_PRE]; + eff_buf.token_len = wsi->ws->rx_ubuf_head; - if (wsi->u.ws.opcode == LWSWSOPC_PONG && !eff_buf.token_len) + if (wsi->ws->opcode == LWSWSOPC_PONG && !eff_buf.token_len) goto already_done; drain_extension: @@ -524,15 +524,15 @@ drain_extension: goto already_done; } - if (wsi->u.ws.check_utf8 && !wsi->u.ws.defeat_check_utf8) { - if (lws_check_utf8(&wsi->u.ws.utf8, + if (wsi->ws->check_utf8 && !wsi->ws->defeat_check_utf8) { + if (lws_check_utf8(&wsi->ws->utf8, (unsigned char *)eff_buf.token, eff_buf.token_len)) goto utf8_fail; /* we are ending partway through utf-8 character? */ - if (!wsi->u.ws.rx_packet_length && wsi->u.ws.final && - wsi->u.ws.utf8 && !n) { + if (!wsi->ws->rx_packet_length && wsi->ws->final && + wsi->ws->utf8 && !n) { lwsl_info("FINAL utf8 error\n"); utf8_fail: lwsl_info("utf8 error\n"); @@ -579,7 +579,7 @@ utf8_fail: return 1; already_done: - wsi->u.ws.rx_ubuf_head = 0; + wsi->ws->rx_ubuf_head = 0; break; default: lwsl_err("client rx illegal state\n"); diff --git a/lib/client/client.c b/lib/client/client.c index 4a5c23fa..86a14183 100644 --- a/lib/client/client.c +++ b/lib/client/client.c @@ -41,7 +41,7 @@ lws_handshake_client(struct lws *wsi, unsigned char **buf, size_t len) lws_rxflow_cache(wsi, *buf, 0, (int)len); return 0; } - if (wsi->u.ws.rx_draining_ext) { + if (wsi->ws->rx_draining_ext) { #if !defined(LWS_NO_CLIENT) if (wsi->mode == LWSCM_WS_CLIENT) m = lws_client_rx_sm(wsi, 0); @@ -474,7 +474,7 @@ lws_http_transaction_completed_client(struct lws *wsi) { lwsl_debug("%s: wsi %p\n", __func__, wsi); /* if we can't go back to accept new headers, drop the connection */ - if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { + if (wsi->http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { lwsl_info("%s: %p: close connection\n", __func__, wsi); return 1; } @@ -485,7 +485,7 @@ lws_http_transaction_completed_client(struct lws *wsi) /* otherwise set ourselves up ready to go again */ wsi->state = LWSS_CLIENT_HTTP_ESTABLISHED; wsi->mode = LWSCM_HTTP_CLIENT_ACCEPTED; - wsi->u.http.rx_content_length = 0; + wsi->http.rx_content_length = 0; wsi->hdr_parsing_completed = 0; /* He asked for it to stay alive indefinitely */ @@ -568,7 +568,7 @@ lws_client_interpret_server_handshake(struct lws *wsi) * */ - wsi->u.http.connection_type = HTTP_CONNECTION_KEEP_ALIVE; + wsi->http.connection_type = HTTP_CONNECTION_KEEP_ALIVE; p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP); if (wsi->do_ws && !p) { lwsl_info("no URI\n"); @@ -577,7 +577,7 @@ lws_client_interpret_server_handshake(struct lws *wsi) } if (!p) { p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP1_0); - wsi->u.http.connection_type = HTTP_CONNECTION_CLOSE; + wsi->http.connection_type = HTTP_CONNECTION_CLOSE; } if (!p) { cce = "HS: URI missing"; @@ -697,17 +697,17 @@ lws_client_interpret_server_handshake(struct lws *wsi) } if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - wsi->u.http.rx_content_length = + wsi->http.rx_content_length = atoll(lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)); lwsl_notice("%s: incoming content length %llu\n", __func__, (unsigned long long) - wsi->u.http.rx_content_length); - wsi->u.http.rx_content_remain = - wsi->u.http.rx_content_length; + wsi->http.rx_content_length); + wsi->http.rx_content_remain = + wsi->http.rx_content_length; } else /* can't do 1.1 without a content length or chunked */ if (!wsi->chunked) - wsi->u.http.connection_type = + wsi->http.connection_type = HTTP_CONNECTION_CLOSE; /* @@ -1063,14 +1063,14 @@ check_accept: if (!n) n = context->pt_serv_buf_size; n += LWS_PRE; - wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */, + wsi->ws->rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */, "client frame buffer"); - if (!wsi->u.ws.rx_ubuf) { + if (!wsi->ws->rx_ubuf) { lwsl_err("Out of Mem allocating rx buffer %d\n", n); cce = "HS: OOM"; goto bail2; } - wsi->u.ws.rx_ubuf_alloc = n; + wsi->ws->rx_ubuf_alloc = n; lwsl_info("Allocating client RX buffer %d\n", n); #if !defined(LWS_WITH_ESP32) @@ -1287,9 +1287,9 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt) p += sprintf(p, "\x0d\x0a"); #endif - if (wsi->ietf_spec_revision) + if (wsi->ws->ietf_spec_revision) p += sprintf(p, "Sec-WebSocket-Version: %d\x0d\x0a", - wsi->ietf_spec_revision); + wsi->ws->ietf_spec_revision); /* prepare the expected server accept response */ diff --git a/lib/ext/extension-permessage-deflate.c b/lib/ext/extension-permessage-deflate.c index d26f63af..80a98f66 100644 --- a/lib/ext/extension-permessage-deflate.c +++ b/lib/ext/extension-permessage-deflate.c @@ -174,7 +174,7 @@ lws_extension_callback_pm_deflate(struct lws_context *context, case LWS_EXT_CB_PAYLOAD_RX: lwsl_ext(" %s: LWS_EXT_CB_PAYLOAD_RX: in %d, existing in %d\n", __func__, eff_buf->token_len, priv->rx.avail_in); - if (!(wsi->u.ws.rsv_first_msg & 0x40)) + if (!(wsi->ws->rsv_first_msg & 0x40)) return 0; #if 0 @@ -229,8 +229,8 @@ lws_extension_callback_pm_deflate(struct lws_context *context, * ...then put back the 00 00 FF FF the sender stripped as our * input to zlib */ - if (!priv->rx.avail_in && wsi->u.ws.final && - !wsi->u.ws.rx_packet_length) { + if (!priv->rx.avail_in && wsi->ws->final && + !wsi->ws->rx_packet_length) { lwsl_ext("RX APPEND_TRAILER-DO\n"); was_fin = 1; priv->rx.next_in = trail; @@ -239,7 +239,7 @@ lws_extension_callback_pm_deflate(struct lws_context *context, n = inflate(&priv->rx, Z_NO_FLUSH); lwsl_ext("inflate ret %d, avi %d, avo %d, wsifinal %d\n", n, - priv->rx.avail_in, priv->rx.avail_out, wsi->u.ws.final); + priv->rx.avail_in, priv->rx.avail_out, wsi->ws->final); switch (n) { case Z_NEED_DICT: case Z_STREAM_ERROR: @@ -257,8 +257,8 @@ lws_extension_callback_pm_deflate(struct lws_context *context, * being a FIN fragment, then do the FIN message processing * of faking up the 00 00 FF FF that the sender stripped. */ - if (!priv->rx.avail_in && wsi->u.ws.final && - !wsi->u.ws.rx_packet_length && !was_fin && + if (!priv->rx.avail_in && wsi->ws->final && + !wsi->ws->rx_packet_length && !was_fin && priv->rx.avail_out /* ambiguous as to if it is the end */ ) { lwsl_ext("RX APPEND_TRAILER-DO\n"); diff --git a/lib/ext/extension.c b/lib/ext/extension.c index d4c227d2..a8855a56 100644 --- a/lib/ext/extension.c +++ b/lib/ext/extension.c @@ -245,7 +245,7 @@ lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len) * extension recreated it: * need to buffer this if not all sent */ - wsi->u.ws.clean_buffer = 0; + wsi->ws->clean_buffer = 0; /* assuming they left us something to send, send it */ @@ -258,7 +258,7 @@ lws_issue_raw_ext_access(struct lws *wsi, unsigned char *buf, size_t len) } /* always either sent it all or privately buffered */ - if (wsi->u.ws.clean_buffer) + if (wsi->ws->clean_buffer) len = n; } diff --git a/lib/handshake.c b/lib/handshake.c index 74396f55..df2a5c23 100644 --- a/lib/handshake.c +++ b/lib/handshake.c @@ -154,9 +154,9 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len) case LWSS_HTTP_ISSUING_FILE: goto read_ok; case LWSS_HTTP_BODY: - wsi->u.http.rx_content_remain = - wsi->u.http.rx_content_length; - if (wsi->u.http.rx_content_remain) + wsi->http.rx_content_remain = + wsi->http.rx_content_length; + if (wsi->http.rx_content_remain) goto http_postbody; /* there is no POST content */ @@ -169,13 +169,13 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len) case LWSS_HTTP_BODY: http_postbody: //lwsl_notice("http post body\n"); - while (len && wsi->u.http.rx_content_remain) { + while (len && wsi->http.rx_content_remain) { /* Copy as much as possible, up to the limit of: * what we have in the read buffer (len) * remaining portion of the POST body (content_remain) */ - body_chunk_len = min(wsi->u.http.rx_content_remain, len); - wsi->u.http.rx_content_remain -= body_chunk_len; + body_chunk_len = min(wsi->http.rx_content_remain, len); + wsi->http.rx_content_remain -= body_chunk_len; len -= body_chunk_len; #ifdef LWS_WITH_CGI if (wsi->cgi) { @@ -207,7 +207,7 @@ http_postbody: #endif buf += n; - if (wsi->u.http.rx_content_remain) { + if (wsi->http.rx_content_remain) { lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT, wsi->context->timeout_secs); break; diff --git a/lib/header.c b/lib/header.c index 6a4cbeed..564b0751 100644 --- a/lib/header.c +++ b/lib/header.c @@ -108,8 +108,8 @@ int lws_add_http_header_content_length(struct lws *wsi, if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH, (unsigned char *)b, n, p, end)) return 1; - wsi->u.http.tx_content_length = content_length; - wsi->u.http.tx_content_remain = content_length; + wsi->http.tx_content_length = content_length; + wsi->http.tx_content_remain = content_length; lwsl_info("%s: wsi %p: tx_content_length/remain %llu\n", __func__, wsi, (unsigned long long)content_length); @@ -183,8 +183,8 @@ lws_add_http_header_status(struct lws *wsi, unsigned int _code, if (code >= 300 && code < 400) description = "Redirect"; - if (wsi->u.http.request_version < ARRAY_SIZE(hver)) - p1 = hver[wsi->u.http.request_version]; + if (wsi->http.request_version < ARRAY_SIZE(hver)) + p1 = hver[wsi->http.request_version]; else p1 = hver[0]; @@ -282,15 +282,15 @@ lws_return_http_status(struct lws *wsi, unsigned int code, len = sprintf((char *)body, "

%u

%s", code, html_body); - wsi->u.http.tx_content_length = len; - wsi->u.http.tx_content_remain = len; + wsi->http.tx_content_length = len; + wsi->http.tx_content_remain = len; - wsi->u.h2.pending_status_body = lws_malloc(len + LWS_PRE + 1, + wsi->h2.pending_status_body = lws_malloc(len + LWS_PRE + 1, "pending status body"); - if (!wsi->u.h2.pending_status_body) + if (!wsi->h2.pending_status_body) return -1; - strcpy(wsi->u.h2.pending_status_body + LWS_PRE, + strcpy(wsi->h2.pending_status_body + LWS_PRE, (const char *)body); lws_callback_on_writable(wsi); diff --git a/lib/http2/hpack.c b/lib/http2/hpack.c index 6ed3ee46..430fbc4f 100644 --- a/lib/http2/hpack.c +++ b/lib/http2/hpack.c @@ -366,10 +366,10 @@ lws_token_from_index(struct lws *wsi, int index, const char **arg, int *len, /* dynamic table only belongs to network wsi */ wsi = lws_get_network_wsi(wsi); - if (!wsi->u.h2.h2n) + if (!wsi->h2.h2n) return -1; - dyn = &wsi->u.h2.h2n->hpack_dyn_table; + dyn = &wsi->h2.h2n->hpack_dyn_table; if (index < 0) return -1; @@ -427,9 +427,9 @@ lws_h2_dynamic_table_dump(struct lws *wsi) int n, m; const char *p; - if (!nwsi->u.h2.h2n) + if (!nwsi->h2.h2n) return 1; - dyn = &nwsi->u.h2.h2n->hpack_dyn_table; + dyn = &nwsi->h2.h2n->hpack_dyn_table; lwsl_header("Dump dyn table for nwsi %p (%d / %d members, pos = %d, " "start index %d, virt used %d / %d)\n", nwsi, @@ -492,9 +492,9 @@ lws_dynamic_token_insert(struct lws *wsi, int hdr_len, /* dynamic table only belongs to network wsi */ wsi = lws_get_network_wsi(wsi); - if (!wsi->u.h2.h2n) + if (!wsi->h2.h2n) return 1; - dyn = &wsi->u.h2.h2n->hpack_dyn_table; + dyn = &wsi->h2.h2n->hpack_dyn_table; if (!dyn->entries) { lwsl_err("%s: unsized dyn table\n", __func__); @@ -587,15 +587,15 @@ lws_hpack_dynamic_size(struct lws *wsi, int size) */ nwsi = lws_get_network_wsi(wsi); - if (!nwsi->u.h2.h2n) + if (!nwsi->h2.h2n) goto bail; - dyn = &nwsi->u.h2.h2n->hpack_dyn_table; + dyn = &nwsi->h2.h2n->hpack_dyn_table; lwsl_info("%s: from %d to %d, lim %d\n", __func__, (int)dyn->num_entries, size, - nwsi->u.h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]); + nwsi->h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]); - if (size > (int)nwsi->u.h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]) { + if (size > (int)nwsi->h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]) { lws_h2_goaway(nwsi, H2_ERR_COMPRESSION_ERROR, "Asked for header table bigger than we told"); goto bail; @@ -664,10 +664,10 @@ lws_hpack_destroy_dynamic_header(struct lws *wsi) struct hpack_dynamic_table *dyn; int n; - if (!wsi->u.h2.h2n) + if (!wsi->h2.h2n) return; - dyn = &wsi->u.h2.h2n->hpack_dyn_table; + dyn = &wsi->h2.h2n->hpack_dyn_table; if (!dyn->entries) return; @@ -767,7 +767,7 @@ lws_hpack_handle_pseudo_rules(struct lws *nwsi, struct lws *wsi, int m) int lws_hpack_interpret(struct lws *wsi, unsigned char c) { struct lws *nwsi = lws_get_network_wsi(wsi); - struct lws_h2_netconn *h2n = nwsi->u.h2.h2n; + struct lws_h2_netconn *h2n = nwsi->h2.h2n; struct allocated_headers *ah = wsi->ah; unsigned int prev; unsigned char c1; @@ -1373,7 +1373,7 @@ int lws_add_http2_header_status(struct lws *wsi, unsigned int code, unsigned char status[10]; int n; - wsi->u.h2.send_END_STREAM = 0; // !!(code >= 400); + wsi->h2.send_END_STREAM = 0; // !!(code >= 400); n = sprintf((char *)status, "%u", code); if (lws_add_http2_header_by_token(wsi, WSI_TOKEN_HTTP_COLON_STATUS, diff --git a/lib/http2/http2.c b/lib/http2/http2.c index 6956aa7c..c0fdfa83 100644 --- a/lib/http2/http2.c +++ b/lib/http2/http2.c @@ -118,7 +118,7 @@ lws_h2_dump_settings(struct http2_settings *set) void lws_h2_init(struct lws *wsi) { - wsi->u.h2.h2n->set = wsi->vhost->set; + wsi->h2.h2n->set = wsi->vhost->set; } static void @@ -127,11 +127,11 @@ lws_h2_state(struct lws *wsi, enum lws_h2_states s) if (!wsi) return; lwsl_info("%s: wsi %p: state %s -> %s\n", __func__, wsi, - h2_state_names[wsi->u.h2.h2_state], + h2_state_names[wsi->h2.h2_state], h2_state_names[s]); (void)h2_state_names; - wsi->u.h2.h2_state = (uint8_t)s; + wsi->h2.h2_state = (uint8_t)s; } struct lws * @@ -140,7 +140,7 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi, { struct lws *wsi; struct lws *nwsi = lws_get_network_wsi(parent_wsi); - struct lws_h2_netconn *h2n = nwsi->u.h2.h2n; + struct lws_h2_netconn *h2n = nwsi->h2.h2n; /* * The identifier of a newly established stream MUST be numerically @@ -156,8 +156,8 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi, } /* no more children allowed by parent */ - if (parent_wsi->u.h2.child_count + 1 > - parent_wsi->u.h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) { + if (parent_wsi->h2.child_count + 1 > + parent_wsi->h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) { lwsl_notice("reached concurrent stream limit\n"); return NULL; } @@ -168,20 +168,20 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi, } h2n->highest_sid_opened = sid; - wsi->u.h2.my_sid = sid; + wsi->h2.my_sid = sid; wsi->http2_substream = 1; wsi->seen_nonpseudoheader = 0; - wsi->u.h2.parent_wsi = parent_wsi; + wsi->h2.parent_wsi = parent_wsi; /* new guy's sibling is whoever was the first child before */ - wsi->u.h2.sibling_list = parent_wsi->u.h2.child_list; + wsi->h2.sibling_list = parent_wsi->h2.child_list; /* first child is now the new guy */ - parent_wsi->u.h2.child_list = wsi; - parent_wsi->u.h2.child_count++; + parent_wsi->h2.child_list = wsi; + parent_wsi->h2.child_count++; - wsi->u.h2.my_priority = 16; - wsi->u.h2.tx_cr = nwsi->u.h2.h2n->set.s[H2SET_INITIAL_WINDOW_SIZE]; - wsi->u.h2.peer_tx_cr_est = nwsi->vhost->set.s[H2SET_INITIAL_WINDOW_SIZE]; + wsi->h2.my_priority = 16; + wsi->h2.tx_cr = nwsi->h2.h2n->set.s[H2SET_INITIAL_WINDOW_SIZE]; + wsi->h2.peer_tx_cr_est = nwsi->vhost->set.s[H2SET_INITIAL_WINDOW_SIZE]; wsi->state = LWSS_HTTP2_ESTABLISHED; wsi->mode = parent_wsi->mode; @@ -195,14 +195,14 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi, lwsl_info("%s: %p new ch %p, sid %d, usersp=%p, tx cr %d, " "peer_credit %d (nwsi tx_cr %d)\n", __func__, parent_wsi, wsi, sid, wsi->user_space, - wsi->u.h2.tx_cr, wsi->u.h2.peer_tx_cr_est, nwsi->u.h2.tx_cr); + wsi->h2.tx_cr, wsi->h2.peer_tx_cr_est, nwsi->h2.tx_cr); return wsi; bail1: /* undo the insert */ - parent_wsi->u.h2.child_list = wsi->u.h2.sibling_list; - parent_wsi->u.h2.child_count--; + parent_wsi->h2.child_list = wsi->h2.sibling_list; + parent_wsi->h2.child_count--; if (wsi->user_space) lws_free_set_NULL(wsi->user_space); @@ -215,23 +215,23 @@ bail1: struct lws * lws_h2_wsi_from_id(struct lws *parent_wsi, unsigned int sid) { - lws_start_foreach_ll(struct lws *, wsi, parent_wsi->u.h2.child_list) { - if (wsi->u.h2.my_sid == sid) + lws_start_foreach_ll(struct lws *, wsi, parent_wsi->h2.child_list) { + if (wsi->h2.my_sid == sid) return wsi; - } lws_end_foreach_ll(wsi, u.h2.sibling_list); + } lws_end_foreach_ll(wsi, h2.sibling_list); return NULL; } int lws_remove_server_child_wsi(struct lws_context *context, struct lws *wsi) { - lws_start_foreach_llp(struct lws **, w, wsi->u.h2.child_list) { + lws_start_foreach_llp(struct lws **, w, wsi->h2.child_list) { if (*w == wsi) { - *w = wsi->u.h2.sibling_list; - (wsi->u.h2.parent_wsi)->u.h2.child_count--; + *w = wsi->h2.sibling_list; + (wsi->h2.parent_wsi)->h2.child_count--; return 0; } - } lws_end_foreach_llp(w, u.h2.sibling_list); + } lws_end_foreach_llp(w, h2.sibling_list); lwsl_err("%s: can't find %p\n", __func__, wsi); @@ -242,7 +242,7 @@ void lws_pps_schedule(struct lws *wsi, struct lws_h2_protocol_send *pps) { struct lws *nwsi = lws_get_network_wsi(wsi); - struct lws_h2_netconn *h2n = nwsi->u.h2.h2n; + struct lws_h2_netconn *h2n = nwsi->h2.h2n; pps->next = h2n->pps; h2n->pps = pps; @@ -265,7 +265,7 @@ lws_h2_new_pps(enum lws_h2_protocol_send_type type) int lws_h2_goaway(struct lws *wsi, uint32_t err, const char *reason) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; struct lws_h2_protocol_send *pps; if (h2n->type == LWS_H2_FRAME_TYPE_COUNT) @@ -292,7 +292,7 @@ int lws_h2_rst_stream(struct lws *wsi, uint32_t err, const char *reason) { struct lws *nwsi = lws_get_network_wsi(wsi); - struct lws_h2_netconn *h2n = nwsi->u.h2.h2n; + struct lws_h2_netconn *h2n = nwsi->h2.h2n; struct lws_h2_protocol_send *pps; if (h2n->type == LWS_H2_FRAME_TYPE_COUNT) @@ -365,16 +365,16 @@ lws_h2_settings(struct lws *wsi, struct http2_settings *settings, */ lws_start_foreach_ll(struct lws *, w, - nwsi->u.h2.child_list) { + nwsi->h2.child_list) { lwsl_info("%s: adi child tc cr %d +%d -> %d", __func__, - w->u.h2.tx_cr, b - settings->s[a], - w->u.h2.tx_cr + b - settings->s[a]); - w->u.h2.tx_cr += b - settings->s[a]; - if (w->u.h2.tx_cr > 0 && - w->u.h2.tx_cr <= (int32_t)(b - settings->s[a])) + w->h2.tx_cr, b - settings->s[a], + w->h2.tx_cr + b - settings->s[a]); + w->h2.tx_cr += b - settings->s[a]; + if (w->h2.tx_cr > 0 && + w->h2.tx_cr <= (int32_t)(b - settings->s[a])) lws_callback_on_writable(w); - } lws_end_foreach_ll(w, u.h2.sibling_list); + } lws_end_foreach_ll(w, h2.sibling_list); break; case H2SET_MAX_FRAME_SIZE: @@ -428,7 +428,7 @@ skip: int lws_h2_tx_cr_get(struct lws *wsi) { - int c = wsi->u.h2.tx_cr; + int c = wsi->h2.tx_cr; struct lws *nwsi; if (!wsi->http2_substream && !wsi->upgraded_to_http2) @@ -437,10 +437,10 @@ lws_h2_tx_cr_get(struct lws *wsi) nwsi = lws_get_network_wsi(wsi); lwsl_info ("%s: %p: own tx credit %d: nwsi credit %d\n", - __func__, wsi, c, nwsi->u.h2.tx_cr); + __func__, wsi, c, nwsi->h2.tx_cr); - if (nwsi->u.h2.tx_cr < c) - c = nwsi->u.h2.tx_cr; + if (nwsi->h2.tx_cr < c) + c = nwsi->h2.tx_cr; if (c < 0) return 0; @@ -453,10 +453,10 @@ lws_h2_tx_cr_consume(struct lws *wsi, int consumed) { struct lws *nwsi = lws_get_network_wsi(wsi); - wsi->u.h2.tx_cr -= consumed; + wsi->h2.tx_cr -= consumed; if (nwsi != wsi) - nwsi->u.h2.tx_cr -= consumed; + nwsi->h2.tx_cr -= consumed; } int lws_h2_frame_write(struct lws *wsi, int type, int flags, @@ -478,13 +478,13 @@ int lws_h2_frame_write(struct lws *wsi, int type, int flags, lwsl_debug("%s: %p (eff %p). typ %d, fl 0x%x, sid=%d, len=%d, " "txcr=%d, nwsi->txcr=%d\n", __func__, wsi, nwsi, type, flags, - sid, len, wsi->u.h2.tx_cr, nwsi->u.h2.tx_cr); + sid, len, wsi->h2.tx_cr, nwsi->h2.tx_cr); if (type == LWS_H2_FRAME_TYPE_DATA) { - if (wsi->u.h2.tx_cr < (int)len) + if (wsi->h2.tx_cr < (int)len) lwsl_err("%s: %p: sending payload len %d" " but tx_cr only %d!\n", __func__, wsi, - len, wsi->u.h2.tx_cr); + len, wsi->h2.tx_cr); lws_h2_tx_cr_consume(wsi, len); } @@ -503,15 +503,15 @@ static void lws_h2_set_bin(struct lws *wsi, int n, unsigned char *buf) { *buf++ = n >> 8; *buf++ = n; - *buf++ = wsi->u.h2.h2n->set.s[n] >> 24; - *buf++ = wsi->u.h2.h2n->set.s[n] >> 16; - *buf++ = wsi->u.h2.h2n->set.s[n] >> 8; - *buf = wsi->u.h2.h2n->set.s[n]; + *buf++ = wsi->h2.h2n->set.s[n] >> 24; + *buf++ = wsi->h2.h2n->set.s[n] >> 16; + *buf++ = wsi->h2.h2n->set.s[n] >> 8; + *buf = wsi->h2.h2n->set.s[n]; } int lws_h2_do_pps_send(struct lws *wsi) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; struct lws_h2_protocol_send *pps = NULL; struct lws *cwsi; uint8_t set[LWS_PRE + 64], *p = &set[LWS_PRE], *q; @@ -545,7 +545,7 @@ int lws_h2_do_pps_send(struct lws *wsi) for (n = 1; n < H2SET_COUNT; n++) if (h2n->set.s[n] != lws_h2_defaults.s[n]) { lwsl_debug("sending SETTING %d 0x%x\n", n, - wsi->u.h2.h2n->set.s[n]); + wsi->h2.h2n->set.s[n]); lws_h2_set_bin(wsi, n, &set[LWS_PRE + m]); m += sizeof(h2n->one_setting); } @@ -569,7 +569,7 @@ int lws_h2_do_pps_send(struct lws *wsi) /* this is the end of the preface dance then? */ if (wsi->state == LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS) { wsi->state = LWSS_HTTP2_ESTABLISHED; - wsi->u.http.fop_fd = NULL; + wsi->http.fop_fd = NULL; if (lws_is_ssl(lws_get_network_wsi(wsi))) break; /* @@ -586,13 +586,13 @@ int lws_h2_do_pps_send(struct lws *wsi) lwsl_info("%s: inherited headers %p\n", __func__, h2n->swsi->ah); - h2n->swsi->u.h2.tx_cr = + h2n->swsi->h2.tx_cr = h2n->set.s[H2SET_INITIAL_WINDOW_SIZE]; lwsl_info("initial tx credit on conn %p: %d\n", - h2n->swsi, h2n->swsi->u.h2.tx_cr); - h2n->swsi->u.h2.initialized = 1; + h2n->swsi, h2n->swsi->h2.tx_cr); + h2n->swsi->h2.initialized = 1; /* demanded by HTTP2 */ - h2n->swsi->u.h2.END_STREAM = 1; + h2n->swsi->h2.END_STREAM = 1; lwsl_info("servicing initial http request\n"); wsi->vhost->conn_stats.h2_trans++; @@ -696,7 +696,7 @@ bail: static int lws_h2_parse_frame_header(struct lws *wsi) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; struct lws_h2_protocol_send *pps; int n; @@ -746,7 +746,7 @@ lws_h2_parse_frame_header(struct lws *wsi) if (h2n->swsi) lwsl_info("%s: wsi %p, State: %s, received cmd %d\n", __func__, h2n->swsi, - h2_state_names[h2n->swsi->u.h2.h2_state], h2n->type); + h2_state_names[h2n->swsi->h2.h2_state], h2n->type); else { /* if it's data, either way no swsi means CLOSED state */ if (h2n->type == LWS_H2_FRAME_TYPE_DATA) { @@ -768,14 +768,14 @@ lws_h2_parse_frame_header(struct lws *wsi) } if (h2n->swsi && h2n->sid && - !(http2_rx_validity[h2n->swsi->u.h2.h2_state] & (1 << h2n->type))) { + !(http2_rx_validity[h2n->swsi->h2.h2_state] & (1 << h2n->type))) { lwsl_info("%s: wsi %p, State: %s, ILLEGAL cmdrx %d (OK 0x%x)\n", __func__, h2n->swsi, - h2_state_names[h2n->swsi->u.h2.h2_state], h2n->type, - http2_rx_validity[h2n->swsi->u.h2.h2_state]); + h2_state_names[h2n->swsi->h2.h2_state], h2n->type, + http2_rx_validity[h2n->swsi->h2.h2_state]); - if (h2n->swsi->u.h2.h2_state == LWS_H2_STATE_CLOSED || - h2n->swsi->u.h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE) + if (h2n->swsi->h2.h2_state == LWS_H2_STATE_CLOSED || + h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE) n = H2_ERR_STREAM_CLOSED; else n = H2_ERR_PROTOCOL_ERROR; @@ -810,11 +810,11 @@ lws_h2_parse_frame_header(struct lws *wsi) if (!h2n->swsi) break; - h2n->swsi->u.h2.peer_tx_cr_est -= h2n->length; + h2n->swsi->h2.peer_tx_cr_est -= h2n->length; lwsl_debug(" peer_tx_cr_est %d\n", - h2n->swsi->u.h2.peer_tx_cr_est); - if (h2n->swsi->u.h2.peer_tx_cr_est < 32768) { - h2n->swsi->u.h2.peer_tx_cr_est += 65536; + h2n->swsi->h2.peer_tx_cr_est); + if (h2n->swsi->h2.peer_tx_cr_est < 32768) { + h2n->swsi->h2.peer_tx_cr_est += 65536; pps = lws_h2_new_pps(LWS_H2_PPS_UPDATE_WINDOW); if (!pps) return 1; @@ -830,8 +830,8 @@ lws_h2_parse_frame_header(struct lws *wsi) } if ( - h2n->swsi->u.h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE || - h2n->swsi->u.h2.h2_state == LWS_H2_STATE_CLOSED) { + h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE || + h2n->swsi->h2.h2_state == LWS_H2_STATE_CLOSED) { lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED, "conn closed"); break; } @@ -935,7 +935,7 @@ lws_h2_parse_frame_header(struct lws *wsi) "unexpected CONTINUATION"); break; } - if (h2n->swsi->u.h2.END_HEADERS) { + if (h2n->swsi->h2.END_HEADERS) { lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "END_HEADERS already seen"); break; @@ -952,8 +952,8 @@ lws_h2_parse_frame_header(struct lws *wsi) if (!h2n->swsi) { /* no more children allowed by parent */ - if (wsi->u.h2.child_count + 1 > - wsi->u.h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) { + if (wsi->h2.child_count + 1 > + wsi->h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) { lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "Another stream not allowed"); @@ -989,18 +989,18 @@ lws_h2_parse_frame_header(struct lws *wsi) * transitions to the "closed" state when the first frame for * stream 7 is sent or received. */ - lws_start_foreach_ll(struct lws *, w, wsi->u.h2.child_list) { - if (w->u.h2.my_sid < h2n->sid && - w->u.h2.h2_state == LWS_H2_STATE_IDLE) + lws_start_foreach_ll(struct lws *, w, wsi->h2.child_list) { + if (w->h2.my_sid < h2n->sid && + w->h2.h2_state == LWS_H2_STATE_IDLE) lws_close_free_wsi(w, 0); - } lws_end_foreach_ll(w, u.h2.sibling_list); + } lws_end_foreach_ll(w, h2.sibling_list); /* END_STREAM means after servicing this, close the stream */ - h2n->swsi->u.h2.END_STREAM = + h2n->swsi->h2.END_STREAM = !!(h2n->flags & LWS_H2_FLAG_END_STREAM); lwsl_info("%s: hdr END_STREAM = %d\n",__func__, - h2n->swsi->u.h2.END_STREAM); + h2n->swsi->h2.END_STREAM); h2n->cont_exp = !(h2n->flags & LWS_H2_FLAG_END_HEADERS); h2n->cont_exp_sid = h2n->sid; @@ -1009,11 +1009,11 @@ lws_h2_parse_frame_header(struct lws *wsi) update_end_headers: /* no END_HEADERS means CONTINUATION must come */ - h2n->swsi->u.h2.END_HEADERS = + h2n->swsi->h2.END_HEADERS = !!(h2n->flags & LWS_H2_FLAG_END_HEADERS); - if (h2n->swsi->u.h2.END_HEADERS) + if (h2n->swsi->h2.END_HEADERS) h2n->cont_exp = 0; - lwsl_debug("END_HEADERS %d\n", h2n->swsi->u.h2.END_HEADERS); + lwsl_debug("END_HEADERS %d\n", h2n->swsi->h2.END_HEADERS); break; case LWS_H2_FRAME_TYPE_WINDOW_UPDATE: @@ -1042,7 +1042,7 @@ update_end_headers: static int lws_h2_parse_end_of_frame(struct lws *wsi) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; struct lws_h2_protocol_send *pps; struct lws *eff_wsi = wsi; const char *p; @@ -1058,11 +1058,11 @@ lws_h2_parse_end_of_frame(struct lws *wsi) h2n->highest_sid = h2n->sid; /* set our initial window size */ - if (!wsi->u.h2.initialized) { - wsi->u.h2.tx_cr = h2n->set.s[H2SET_INITIAL_WINDOW_SIZE]; + if (!wsi->h2.initialized) { + wsi->h2.tx_cr = h2n->set.s[H2SET_INITIAL_WINDOW_SIZE]; lwsl_info("initial tx credit on master %p: %d\n", wsi, - wsi->u.h2.tx_cr); - wsi->u.h2.initialized = 1; + wsi->h2.tx_cr); + wsi->h2.initialized = 1; } if (h2n->collected_priority && (h2n->dep & ~(1 << 31)) == h2n->sid) { @@ -1082,7 +1082,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi) break; } - if (!h2n->swsi->u.h2.END_HEADERS) { + if (!h2n->swsi->h2.END_HEADERS) { /* we are not finished yet */ lwsl_info("witholding http action for continuation\n"); break; @@ -1100,7 +1100,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi) } /* this is the last part of HEADERS */ - switch (h2n->swsi->u.h2.h2_state) { + switch (h2n->swsi->h2.h2_state) { case LWS_H2_STATE_IDLE: lws_h2_state(h2n->swsi, LWS_H2_STATE_OPEN); break; @@ -1113,13 +1113,13 @@ lws_h2_parse_end_of_frame(struct lws *wsi) h2n->swsi->hdr_parsing_completed = 1; if (lws_hdr_extant(h2n->swsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { - h2n->swsi->u.http.rx_content_length = atoll( + h2n->swsi->http.rx_content_length = atoll( lws_hdr_simple_ptr(h2n->swsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)); - h2n->swsi->u.http.rx_content_remain = - h2n->swsi->u.http.rx_content_length; + h2n->swsi->http.rx_content_remain = + h2n->swsi->http.rx_content_length; lwsl_info("setting rx_content_length %lld\n", - (long long)h2n->swsi->u.http.rx_content_length); + (long long)h2n->swsi->http.rx_content_length); } { @@ -1148,21 +1148,21 @@ lws_h2_parse_end_of_frame(struct lws *wsi) } while (c); } - if (h2n->swsi->u.h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE || - h2n->swsi->u.h2.h2_state == LWS_H2_STATE_CLOSED) { + if (h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_REMOTE || + h2n->swsi->h2.h2_state == LWS_H2_STATE_CLOSED) { lws_h2_goaway(wsi, H2_ERR_STREAM_CLOSED, "Banning service on CLOSED_REMOTE"); break; } - switch (h2n->swsi->u.h2.h2_state) { + switch (h2n->swsi->h2.h2_state) { case LWS_H2_STATE_OPEN: - if (h2n->swsi->u.h2.END_STREAM) + if (h2n->swsi->h2.END_STREAM) lws_h2_state(h2n->swsi, LWS_H2_STATE_HALF_CLOSED_REMOTE); break; case LWS_H2_STATE_HALF_CLOSED_LOCAL: - if (h2n->swsi->u.h2.END_STREAM) + if (h2n->swsi->h2.END_STREAM) lws_h2_state(h2n->swsi, LWS_H2_STATE_CLOSED); break; } @@ -1199,15 +1199,15 @@ lws_h2_parse_end_of_frame(struct lws *wsi) lwsl_info(" action start...\n"); n = lws_http_action(h2n->swsi); lwsl_info(" action result %d " - "(wsi->u.http.rx_content_remain %lld)\n", - n, h2n->swsi->u.http.rx_content_remain); + "(wsi->http.rx_content_remain %lld)\n", + n, h2n->swsi->http.rx_content_remain); /* * Commonly we only managed to start a larger transfer that will * complete asynchronously. In those cases we will hear about * END_STREAM going out in the POLLOUT handler. */ - if (n || h2n->swsi->u.h2.send_END_STREAM) { + if (n || h2n->swsi->h2.send_END_STREAM) { lws_close_free_wsi(h2n->swsi, 0); h2n->swsi = NULL; break; @@ -1219,20 +1219,20 @@ lws_h2_parse_end_of_frame(struct lws *wsi) break; if (lws_hdr_total_length(h2n->swsi, WSI_TOKEN_HTTP_CONTENT_LENGTH) && - h2n->swsi->u.h2.END_STREAM && - h2n->swsi->u.http.rx_content_length && - h2n->swsi->u.http.rx_content_remain) { + h2n->swsi->h2.END_STREAM && + h2n->swsi->http.rx_content_length && + h2n->swsi->http.rx_content_remain) { lws_h2_rst_stream(h2n->swsi, H2_ERR_PROTOCOL_ERROR, "Not enough rx content"); break; } - if (h2n->swsi->u.h2.END_STREAM && - h2n->swsi->u.h2.h2_state == LWS_H2_STATE_OPEN) + if (h2n->swsi->h2.END_STREAM && + h2n->swsi->h2.h2_state == LWS_H2_STATE_OPEN) lws_h2_state(h2n->swsi, LWS_H2_STATE_HALF_CLOSED_REMOTE); - if (h2n->swsi->u.h2.END_STREAM && - h2n->swsi->u.h2.h2_state == LWS_H2_STATE_HALF_CLOSED_LOCAL) + if (h2n->swsi->h2.END_STREAM && + h2n->swsi->h2.h2_state == LWS_H2_STATE_HALF_CLOSED_LOCAL) lws_h2_state(h2n->swsi, LWS_H2_STATE_CLOSED); break; @@ -1264,7 +1264,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi) break; /* ignore */ } - if ((uint64_t)eff_wsi->u.h2.tx_cr + (uint64_t)h2n->hpack_e_dep > + if ((uint64_t)eff_wsi->h2.tx_cr + (uint64_t)h2n->hpack_e_dep > (uint64_t)0x7fffffff) { if (h2n->sid) lws_h2_rst_stream(h2n->swsi, @@ -1281,10 +1281,10 @@ lws_h2_parse_end_of_frame(struct lws *wsi) "Zero length window update"); break; } - n = eff_wsi->u.h2.tx_cr; - eff_wsi->u.h2.tx_cr += h2n->hpack_e_dep; + n = eff_wsi->h2.tx_cr; + eff_wsi->h2.tx_cr += h2n->hpack_e_dep; - if (n <= 0 && eff_wsi->u.h2.tx_cr <= 0) + if (n <= 0 && eff_wsi->h2.tx_cr <= 0) /* it helps, but won't change sendability for anyone */ break; @@ -1292,13 +1292,13 @@ lws_h2_parse_end_of_frame(struct lws *wsi) * It did change sendability... for us and any children waiting * on us... reassess blockage for all children first */ - lws_start_foreach_ll(struct lws *, w, wsi->u.h2.child_list) { + lws_start_foreach_ll(struct lws *, w, wsi->h2.child_list) { lws_callback_on_writable(w); - } lws_end_foreach_ll(w, u.h2.sibling_list); + } lws_end_foreach_ll(w, h2.sibling_list); - if (eff_wsi->u.h2.skint && lws_h2_tx_cr_get(eff_wsi)) { + if (eff_wsi->h2.skint && lws_h2_tx_cr_get(eff_wsi)) { lwsl_info("%s: %p: skint\n", __func__, wsi); - eff_wsi->u.h2.skint = 0; + eff_wsi->h2.skint = 0; lws_callback_on_writable(eff_wsi); } break; @@ -1307,7 +1307,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi) lwsl_info("GOAWAY: last sid %d, error 0x%08X, string '%s'\n", h2n->goaway_last_sid, h2n->goaway_err, h2n->goaway_str); - wsi->u.h2.GOING_AWAY = 1; + wsi->h2.GOING_AWAY = 1; return 1; @@ -1321,7 +1321,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi) int lws_h2_parser(struct lws *wsi, unsigned char c) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; struct lws_h2_protocol_send *pps; int n; @@ -1339,7 +1339,7 @@ lws_h2_parser(struct lws *wsi, unsigned char c) lwsl_info("http2: %p: established\n", wsi); wsi->state = LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS; h2n->count = 0; - wsi->u.h2.tx_cr = 65535; + wsi->h2.tx_cr = 65535; /* * we must send a settings frame -- empty one is OK... @@ -1402,7 +1402,7 @@ lws_h2_parser(struct lws *wsi, unsigned char c) goto frame_end; } - /* applies to wsi->u.h2.swsi which may be wsi */ + /* applies to wsi->h2.swsi which may be wsi */ switch(h2n->type) { case LWS_H2_FRAME_TYPE_SETTINGS: @@ -1464,8 +1464,8 @@ lws_h2_parser(struct lws *wsi, unsigned char c) h2n->inside++; if (lws_hdr_total_length(h2n->swsi, WSI_TOKEN_HTTP_CONTENT_LENGTH) && - h2n->swsi->u.http.rx_content_length && - h2n->swsi->u.http.rx_content_remain == 1 && /* last */ + h2n->swsi->http.rx_content_length && + h2n->swsi->http.rx_content_remain == 1 && /* last */ h2n->inside < h2n->length) { /* unread data in frame */ lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "More rx than content_length told"); diff --git a/lib/http2/ssl-http2.c b/lib/http2/ssl-http2.c index 37e47862..05d69536 100644 --- a/lib/http2/ssl-http2.c +++ b/lib/http2/ssl-http2.c @@ -135,8 +135,8 @@ int lws_h2_configure_if_upgraded(struct lws *wsi) /* http2 union member has http union struct at start */ wsi->ah = ah; - wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n), "h2n"); - if (!wsi->u.h2.h2n) + wsi->h2.h2n = lws_zalloc(sizeof(*wsi->h2.h2n), "h2n"); + if (!wsi->h2.h2n) return 1; lws_h2_init(wsi); @@ -144,8 +144,8 @@ int lws_h2_configure_if_upgraded(struct lws *wsi) /* HTTP2 union */ lws_hpack_dynamic_size(wsi, - wsi->u.h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]); - wsi->u.h2.tx_cr = 65535; + wsi->h2.h2n->set.s[H2SET_HEADER_TABLE_SIZE]); + wsi->h2.tx_cr = 65535; lwsl_info("%s: wsi %p: configured for h2\n", __func__, wsi); #endif diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index a5e7b857..a9e1f71a 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -79,6 +79,7 @@ lws_free_wsi(struct lws *wsi) lws_free_set_NULL(wsi->rxflow_buffer); lws_free_set_NULL(wsi->trunc_alloc); + lws_free_set_NULL(wsi->ws); /* we may not have an ah, but may be on the waiting list... */ lwsl_info("ah det due to close\n"); @@ -111,8 +112,8 @@ lws_free_wsi(struct lws *wsi) if (wsi->upgraded_to_http2 || wsi->http2_substream) { lws_hpack_destroy_dynamic_header(wsi); - if (wsi->u.h2.h2n) - lws_free_set_NULL(wsi->u.h2.h2n); + if (wsi->h2.h2n) + lws_free_set_NULL(wsi->h2.h2n); } #endif @@ -323,73 +324,73 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason) #if defined(LWS_WITH_HTTP2) - if (wsi->u.h2.parent_wsi) { + if (wsi->h2.parent_wsi) { lwsl_info(" wsi: %p, his parent %p: siblings:\n", wsi, - wsi->u.h2.parent_wsi); + wsi->h2.parent_wsi); lws_start_foreach_llp(struct lws **, w, - wsi->u.h2.parent_wsi->u.h2.child_list) { + wsi->h2.parent_wsi->h2.child_list) { lwsl_info(" \\---- child %p\n", *w); - } lws_end_foreach_llp(w, u.h2.sibling_list); + } lws_end_foreach_llp(w, h2.sibling_list); } if (wsi->upgraded_to_http2 || wsi->http2_substream) { - lwsl_info("closing %p: parent %p\n", wsi, wsi->u.h2.parent_wsi); + lwsl_info("closing %p: parent %p\n", wsi, wsi->h2.parent_wsi); - if (wsi->u.h2.child_list) { + if (wsi->h2.child_list) { lwsl_info(" parent %p: closing children: list:\n", wsi); lws_start_foreach_llp(struct lws **, w, - wsi->u.h2.child_list) { + wsi->h2.child_list) { lwsl_info(" \\---- child %p\n", *w); - } lws_end_foreach_llp(w, u.h2.sibling_list); + } lws_end_foreach_llp(w, h2.sibling_list); /* trigger closing of all of our http2 children first */ lws_start_foreach_llp(struct lws **, w, - wsi->u.h2.child_list) { + wsi->h2.child_list) { lwsl_info(" closing child %p\n", *w); /* disconnect from siblings */ - wsi2 = (*w)->u.h2.sibling_list; - (*w)->u.h2.sibling_list = NULL; + wsi2 = (*w)->h2.sibling_list; + (*w)->h2.sibling_list = NULL; (*w)->socket_is_permanently_unusable = 1; lws_close_free_wsi(*w, reason); *w = wsi2; continue; - } lws_end_foreach_llp(w, u.h2.sibling_list); + } lws_end_foreach_llp(w, h2.sibling_list); } } if (wsi->upgraded_to_http2) { /* remove pps */ - struct lws_h2_protocol_send *w = wsi->u.h2.h2n->pps, *w1; + struct lws_h2_protocol_send *w = wsi->h2.h2n->pps, *w1; while (w) { - w1 = wsi->u.h2.h2n->pps->next; + w1 = w->next; free(w); w = w1; } - wsi->u.h2.h2n->pps = NULL; + wsi->h2.h2n->pps = NULL; } - if (wsi->http2_substream && wsi->u.h2.parent_wsi) { + if (wsi->http2_substream && wsi->h2.parent_wsi) { lwsl_info(" %p: disentangling from siblings\n", wsi); lws_start_foreach_llp(struct lws **, w, - wsi->u.h2.parent_wsi->u.h2.child_list) { + wsi->h2.parent_wsi->h2.child_list) { /* disconnect from siblings */ if (*w == wsi) { - wsi2 = (*w)->u.h2.sibling_list; - (*w)->u.h2.sibling_list = NULL; + wsi2 = (*w)->h2.sibling_list; + (*w)->h2.sibling_list = NULL; *w = wsi2; lwsl_info(" %p disentangled from sibling %p\n", wsi, wsi2); break; } - } lws_end_foreach_llp(w, u.h2.sibling_list); - wsi->u.h2.parent_wsi->u.h2.child_count--; - wsi->u.h2.parent_wsi = NULL; - if (wsi->u.h2.pending_status_body) - lws_free_set_NULL(wsi->u.h2.pending_status_body); + } lws_end_foreach_llp(w, h2.sibling_list); + wsi->h2.parent_wsi->h2.child_count--; + wsi->h2.parent_wsi = NULL; + if (wsi->h2.pending_status_body) + lws_free_set_NULL(wsi->h2.pending_status_body); } - if (wsi->upgraded_to_http2 && wsi->u.h2.h2n && - wsi->u.h2.h2n->rx_scratch) - lws_free_set_NULL(wsi->u.h2.h2n->rx_scratch); + if (wsi->upgraded_to_http2 && wsi->h2.h2n && + wsi->h2.h2n->rx_scratch) + lws_free_set_NULL(wsi->h2.h2n->rx_scratch); #endif if (wsi->mode == LWSCM_RAW_FILEDESC) { @@ -446,8 +447,8 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason) if ((wsi->mode == LWSCM_HTTP_SERVING_ACCEPTED || wsi->mode == LWSCM_HTTP2_SERVING) && - wsi->u.http.fop_fd != NULL) { - lws_vfs_file_close(&wsi->u.http.fop_fd); + wsi->http.fop_fd != NULL) { + lws_vfs_file_close(&wsi->http.fop_fd); wsi->vhost->protocols->callback(wsi, LWS_CALLBACK_CLOSED_HTTP, wsi->user_space, NULL, 0); wsi->told_user_closed = 1; @@ -560,17 +561,17 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason) */ if (wsi->state_pre_close == LWSS_ESTABLISHED && - (wsi->u.ws.close_in_ping_buffer_len || /* already a reason */ + (wsi->ws->close_in_ping_buffer_len || /* already a reason */ (reason != LWS_CLOSE_STATUS_NOSTATUS && (reason != LWS_CLOSE_STATUS_NOSTATUS_CONTEXT_DESTROY)))) { lwsl_debug("sending close indication...\n"); /* if no prepared close reason, use 1000 and no aux data */ - if (!wsi->u.ws.close_in_ping_buffer_len) { - wsi->u.ws.close_in_ping_buffer_len = 2; - wsi->u.ws.ping_payload_buf[LWS_PRE] = + if (!wsi->ws->close_in_ping_buffer_len) { + wsi->ws->close_in_ping_buffer_len = 2; + wsi->ws->ping_payload_buf[LWS_PRE] = (reason >> 8) & 0xff; - wsi->u.ws.ping_payload_buf[LWS_PRE + 1] = + wsi->ws->ping_payload_buf[LWS_PRE + 1] = reason & 0xff; } @@ -709,43 +710,43 @@ just_kill_connection: wsi->mode == LWSCM_WS_SERVING || wsi->mode == LWSCM_WS_CLIENT) { - if (wsi->u.ws.rx_draining_ext) { + if (wsi->ws->rx_draining_ext) { struct lws **w = &pt->rx_draining_ext_list; - wsi->u.ws.rx_draining_ext = 0; + wsi->ws->rx_draining_ext = 0; /* remove us from context draining ext list */ while (*w) { if (*w == wsi) { - *w = wsi->u.ws.rx_draining_ext_list; + *w = wsi->ws->rx_draining_ext_list; break; } - w = &((*w)->u.ws.rx_draining_ext_list); + w = &((*w)->ws->rx_draining_ext_list); } - wsi->u.ws.rx_draining_ext_list = NULL; + wsi->ws->rx_draining_ext_list = NULL; } - if (wsi->u.ws.tx_draining_ext) { + if (wsi->ws->tx_draining_ext) { struct lws **w = &pt->tx_draining_ext_list; - wsi->u.ws.tx_draining_ext = 0; + wsi->ws->tx_draining_ext = 0; /* remove us from context draining ext list */ while (*w) { if (*w == wsi) { - *w = wsi->u.ws.tx_draining_ext_list; + *w = wsi->ws->tx_draining_ext_list; break; } - w = &((*w)->u.ws.tx_draining_ext_list); + w = &((*w)->ws->tx_draining_ext_list); } - wsi->u.ws.tx_draining_ext_list = NULL; + wsi->ws->tx_draining_ext_list = NULL; } - lws_free_set_NULL(wsi->u.ws.rx_ubuf); + lws_free_set_NULL(wsi->ws->rx_ubuf); if (wsi->trunc_alloc) /* not going to be completed... nuke it */ lws_free_set_NULL(wsi->trunc_alloc); - wsi->u.ws.ping_payload_len = 0; - wsi->u.ws.ping_pending_flag = 0; + wsi->ws->ping_payload_len = 0; + wsi->ws->ping_pending_flag = 0; } /* tell the user it's all over for this guy */ @@ -987,7 +988,7 @@ lws_get_peer_simple(struct lws *wsi, char *name, int namelen) #if defined(LWS_WITH_HTTP2) if (wsi->http2_substream) - wsi = wsi->u.h2.parent_wsi; + wsi = wsi->h2.parent_wsi; #endif if (wsi->parent_carries_io) @@ -1115,8 +1116,8 @@ lws_get_network_wsi(struct lws *wsi) if (!wsi->http2_substream) return wsi; - while (wsi->u.h2.parent_wsi) - wsi = wsi->u.h2.parent_wsi; + while (wsi->h2.parent_wsi) + wsi = wsi->h2.parent_wsi; #endif return wsi; @@ -1656,22 +1657,22 @@ LWS_VISIBLE int lws_is_final_fragment(struct lws *wsi) { lwsl_info("%s: final %d, rx pk length %ld, draining %ld\n", __func__, - wsi->u.ws.final, (long)wsi->u.ws.rx_packet_length, - (long)wsi->u.ws.rx_draining_ext); - return wsi->u.ws.final && !wsi->u.ws.rx_packet_length && - !wsi->u.ws.rx_draining_ext; + wsi->ws->final, (long)wsi->ws->rx_packet_length, + (long)wsi->ws->rx_draining_ext); + return wsi->ws->final && !wsi->ws->rx_packet_length && + !wsi->ws->rx_draining_ext; } LWS_VISIBLE int lws_is_first_fragment(struct lws *wsi) { - return wsi->u.ws.first_fragment; + return wsi->ws->first_fragment; } LWS_VISIBLE unsigned char lws_get_reserved_bits(struct lws *wsi) { - return wsi->u.ws.rsv; + return wsi->ws->rsv; } int @@ -1938,7 +1939,6 @@ LWS_VISIBLE void lws_union_transition(struct lws *wsi, enum connection_mode mode) { lwsl_debug("%s: %p: mode %d\n", __func__, wsi, mode); - memset(&wsi->u, 0, sizeof(wsi->u)); wsi->mode = mode; } @@ -2021,13 +2021,13 @@ lws_clear_child_pending_on_writable(struct lws *wsi) LWS_VISIBLE LWS_EXTERN int lws_get_close_length(struct lws *wsi) { - return wsi->u.ws.close_in_ping_buffer_len; + return wsi->ws->close_in_ping_buffer_len; } LWS_VISIBLE LWS_EXTERN unsigned char * lws_get_close_payload(struct lws *wsi) { - return &wsi->u.ws.ping_payload_buf[LWS_PRE]; + return &wsi->ws->ping_payload_buf[LWS_PRE]; } LWS_VISIBLE LWS_EXTERN void @@ -2035,11 +2035,11 @@ lws_close_reason(struct lws *wsi, enum lws_close_status status, unsigned char *buf, size_t len) { unsigned char *p, *start; - int budget = sizeof(wsi->u.ws.ping_payload_buf) - LWS_PRE; + int budget = sizeof(wsi->ws->ping_payload_buf) - LWS_PRE; assert(wsi->mode == LWSCM_WS_SERVING || wsi->mode == LWSCM_WS_CLIENT); - start = p = &wsi->u.ws.ping_payload_buf[LWS_PRE]; + start = p = &wsi->ws->ping_payload_buf[LWS_PRE]; *p++ = (((int)status) >> 8) & 0xff; *p++ = ((int)status) & 0xff; @@ -2048,7 +2048,7 @@ lws_close_reason(struct lws *wsi, enum lws_close_status status, while (len-- && p < start + budget) *p++ = *buf++; - wsi->u.ws.close_in_ping_buffer_len = lws_ptr_diff(p, start); + wsi->ws->close_in_ping_buffer_len = lws_ptr_diff(p, start); } LWS_EXTERN int @@ -2449,7 +2449,7 @@ lws_restart_ws_ping_pong_timer(struct lws *wsi) if (wsi->state != LWSS_ESTABLISHED) return; - wsi->u.ws.time_next_ping_check = (time_t)lws_now_secs() + + wsi->ws->time_next_ping_check = (time_t)lws_now_secs() + wsi->context->ws_ping_pong_interval; } diff --git a/lib/output.c b/lib/output.c index 4e2edabe..0a9638bd 100644 --- a/lib/output.c +++ b/lib/output.c @@ -27,7 +27,7 @@ lws_0405_frame_mask_generate(struct lws *wsi) int n; /* fetch the per-frame nonce */ - n = lws_get_random(lws_get_context(wsi), wsi->u.ws.mask, 4); + n = lws_get_random(lws_get_context(wsi), wsi->ws->mask, 4); if (n != 4) { lwsl_parser("Unable to read from random device %s %d\n", SYSTEM_RANDOM_FILEPATH, n); @@ -35,7 +35,7 @@ lws_0405_frame_mask_generate(struct lws *wsi) } /* start masking from first byte of masking key buffer */ - wsi->u.ws.mask_idx = 0; + wsi->ws->mask_idx = 0; return 0; } @@ -233,21 +233,21 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, if (wsi->vhost) wsi->vhost->conn_stats.tx += len; - if (wsi->state == LWSS_ESTABLISHED && wsi->u.ws.tx_draining_ext) { + if (wsi->state == LWSS_ESTABLISHED && wsi->ws->tx_draining_ext) { /* remove us from the list */ struct lws **w = &pt->tx_draining_ext_list; - wsi->u.ws.tx_draining_ext = 0; + wsi->ws->tx_draining_ext = 0; /* remove us from context draining ext list */ while (*w) { if (*w == wsi) { - *w = wsi->u.ws.tx_draining_ext_list; + *w = wsi->ws->tx_draining_ext_list; break; } - w = &((*w)->u.ws.tx_draining_ext_list); + w = &((*w)->ws->tx_draining_ext_list); } - wsi->u.ws.tx_draining_ext_list = NULL; - wp = (wsi->u.ws.tx_draining_stashed_wp & 0xc0) | + wsi->ws->tx_draining_ext_list = NULL; + wp = (wsi->ws->tx_draining_stashed_wp & 0xc0) | LWS_WRITE_CONTINUATION; lwsl_ext("FORCED draining wp to 0x%02X\n", wp); @@ -271,12 +271,12 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, /* if we are continuing a frame that already had its header done */ - if (wsi->u.ws.inside_frame) { + if (wsi->ws->inside_frame) { lwsl_debug("INSIDE FRAME\n"); goto do_more_inside_frame; } - wsi->u.ws.clean_buffer = 1; + wsi->ws->clean_buffer = 1; /* * give a chance to the extensions to modify payload @@ -308,8 +308,8 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, if (n && eff_buf.token_len) { lwsl_debug("drain len %d\n", (int)eff_buf.token_len); /* extension requires further draining */ - wsi->u.ws.tx_draining_ext = 1; - wsi->u.ws.tx_draining_ext_list = + wsi->ws->tx_draining_ext = 1; + wsi->ws->tx_draining_ext_list = pt->tx_draining_ext_list; pt->tx_draining_ext_list = wsi; /* we must come back to do more */ @@ -319,7 +319,7 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, * action that has provoked generation of these * fragments, so the last guy can use its FIN state. */ - wsi->u.ws.tx_draining_stashed_wp = wp; + wsi->ws->tx_draining_stashed_wp = wp; /* this is definitely not actually the last fragment * because the extension asserted he has more coming * So make sure this intermediate one doesn't go out @@ -328,9 +328,9 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, wp |= LWS_WRITE_NO_FIN; } - if (eff_buf.token_len && wsi->u.ws.stashed_write_pending) { - wsi->u.ws.stashed_write_pending = 0; - wp = (wp &0xc0) | (int)wsi->u.ws.stashed_write_type; + if (eff_buf.token_len && wsi->ws->stashed_write_pending) { + wsi->ws->stashed_write_pending = 0; + wp = (wp &0xc0) | (int)wsi->ws->stashed_write_type; } } @@ -346,16 +346,16 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, * replace the write type that was lost here the first time. */ if (len && !eff_buf.token_len) { - if (!wsi->u.ws.stashed_write_pending) - wsi->u.ws.stashed_write_type = (char)wp & 0x3f; - wsi->u.ws.stashed_write_pending = 1; + if (!wsi->ws->stashed_write_pending) + wsi->ws->stashed_write_type = (char)wp & 0x3f; + wsi->ws->stashed_write_pending = 1; return (int)len; } /* * extension recreated it: * need to buffer this if not all sent */ - wsi->u.ws.clean_buffer = 0; + wsi->ws->clean_buffer = 0; } buf = (unsigned char *)eff_buf.token; @@ -366,7 +366,7 @@ LWS_VISIBLE int lws_write(struct lws *wsi, unsigned char *buf, size_t len, return -1; } - switch (wsi->ietf_spec_revision) { + switch (wsi->ws->ietf_spec_revision) { case 13: if (masked7) { pre += 4; @@ -445,7 +445,7 @@ do_more_inside_frame: */ if (masked7) { - if (!wsi->u.ws.inside_frame) + if (!wsi->ws->inside_frame) if (lws_0405_frame_mask_generate(wsi)) { lwsl_err("frame mask generation failed\n"); return -1; @@ -456,11 +456,11 @@ do_more_inside_frame: */ if (dropmask) { /* never set if already inside frame */ for (n = 4; n < (int)len + 4; n++) - dropmask[n] = dropmask[n] ^ wsi->u.ws.mask[ - (wsi->u.ws.mask_idx++) & 3]; + dropmask[n] = dropmask[n] ^ wsi->ws->mask[ + (wsi->ws->mask_idx++) & 3]; /* copy the frame nonce into place */ - memcpy(dropmask, wsi->u.ws.mask, 4); + memcpy(dropmask, wsi->ws->mask, 4); } } @@ -483,10 +483,10 @@ send_raw: n = LWS_H2_FRAME_TYPE_HEADERS; if (!(wp & LWS_WRITE_NO_FIN)) flags = LWS_H2_FLAG_END_HEADERS; - if (wsi->u.h2.send_END_STREAM || + if (wsi->h2.send_END_STREAM || (wp & LWS_WRITE_H2_STREAM_END)) { flags |= LWS_H2_FLAG_END_STREAM; - wsi->u.h2.send_END_STREAM = 1; + wsi->h2.send_END_STREAM = 1; } } @@ -494,20 +494,20 @@ send_raw: n = LWS_H2_FRAME_TYPE_CONTINUATION; if (!(wp & LWS_WRITE_NO_FIN)) flags = LWS_H2_FLAG_END_HEADERS; - if (wsi->u.h2.send_END_STREAM || + if (wsi->h2.send_END_STREAM || (wp & LWS_WRITE_H2_STREAM_END)) { flags |= LWS_H2_FLAG_END_STREAM; - wsi->u.h2.send_END_STREAM = 1; + wsi->h2.send_END_STREAM = 1; } } if (((wp & 0x1f) == LWS_WRITE_HTTP || (wp & 0x1f) == LWS_WRITE_HTTP_FINAL) && - wsi->u.http.tx_content_length) { - wsi->u.http.tx_content_remain -= len; + wsi->http.tx_content_length) { + wsi->http.tx_content_remain -= len; lwsl_info("%s: wsi %p: tx_content_remain = %llu\n", __func__, wsi, - (unsigned long long)wsi->u.http.tx_content_remain); - if (!wsi->u.http.tx_content_remain) { + (unsigned long long)wsi->http.tx_content_remain); + if (!wsi->http.tx_content_remain) { lwsl_info("%s: selecting final write mode\n", __func__); wp = LWS_WRITE_HTTP_FINAL; @@ -516,14 +516,14 @@ send_raw: if ((wp & 0x1f) == LWS_WRITE_HTTP_FINAL || (wp & LWS_WRITE_H2_STREAM_END)) { - //lws_get_network_wsi(wsi)->u.h2.END_STREAM) { + //lws_get_network_wsi(wsi)->h2.END_STREAM) { lwsl_info("%s: setting END_STREAM\n", __func__); flags |= LWS_H2_FLAG_END_STREAM; - wsi->u.h2.send_END_STREAM = 1; + wsi->h2.send_END_STREAM = 1; } return lws_h2_frame_write(wsi, n, flags, - wsi->u.h2.my_sid, (int)len, buf); + wsi->h2.my_sid, (int)len, buf); } #endif return lws_issue_raw(wsi, (unsigned char *)buf - pre, len + pre); @@ -545,19 +545,19 @@ send_raw: * callback returns 1 in case it wants to spill more buffers * * This takes care of holding the buffer if send is incomplete, ie, - * if wsi->u.ws.clean_buffer is 0 (meaning an extension meddled with - * the buffer). If wsi->u.ws.clean_buffer is 1, it will instead + * if wsi->ws->clean_buffer is 0 (meaning an extension meddled with + * the buffer). If wsi->ws->clean_buffer is 1, it will instead * return to the user code how much OF THE USER BUFFER was consumed. */ n = lws_issue_raw_ext_access(wsi, buf - pre, len + pre); - wsi->u.ws.inside_frame = 1; + wsi->ws->inside_frame = 1; if (n <= 0) return n; if (n == (int)len + pre) { /* everything in the buffer was handled (or rebuffered...) */ - wsi->u.ws.inside_frame = 0; + wsi->ws->inside_frame = 0; return (int)orig_len; } @@ -597,7 +597,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) continue; } - if (wsi->u.http.filepos == wsi->u.http.filelen) + if (wsi->http.filepos == wsi->http.filelen) goto all_sent; n = 0; @@ -607,19 +607,19 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) p = pstart; #if defined(LWS_WITH_RANGES) - if (wsi->u.http.range.count_ranges && !wsi->u.http.range.inside) { + if (wsi->http.range.count_ranges && !wsi->http.range.inside) { lwsl_notice("%s: doing range start %llu\n", __func__, - wsi->u.http.range.start); + wsi->http.range.start); - if ((long long)lws_vfs_file_seek_cur(wsi->u.http.fop_fd, - wsi->u.http.range.start - - wsi->u.http.filepos) < 0) + if ((long long)lws_vfs_file_seek_cur(wsi->http.fop_fd, + wsi->http.range.start - + wsi->http.filepos) < 0) goto file_had_it; - wsi->u.http.filepos = wsi->u.http.range.start; + wsi->http.filepos = wsi->http.range.start; - if (wsi->u.http.range.count_ranges > 1) { + if (wsi->http.range.count_ranges > 1) { n = lws_snprintf((char *)p, context->pt_serv_buf_size - LWS_H2_FRAME_HEADER_LENGTH, @@ -627,23 +627,23 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) "Content-Type: %s\x0d\x0a" "Content-Range: bytes %llu-%llu/%llu\x0d\x0a" "\x0d\x0a", - wsi->u.http.multipart_content_type, - wsi->u.http.range.start, - wsi->u.http.range.end, - wsi->u.http.range.extent); + wsi->http.multipart_content_type, + wsi->http.range.start, + wsi->http.range.end, + wsi->http.range.extent); p += n; } - wsi->u.http.range.budget = wsi->u.http.range.end - - wsi->u.http.range.start + 1; - wsi->u.http.range.inside = 1; + wsi->http.range.budget = wsi->http.range.end - + wsi->http.range.start + 1; + wsi->http.range.inside = 1; } #endif poss = context->pt_serv_buf_size - n - LWS_H2_FRAME_HEADER_LENGTH; - if (poss > wsi->u.http.tx_content_remain) - poss = wsi->u.http.tx_content_remain; + if (poss > wsi->http.tx_content_remain) + poss = wsi->http.tx_content_remain; /* * if there is a hint about how much we will do well to send at one time, @@ -668,11 +668,11 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) #endif #if defined(LWS_WITH_RANGES) - if (wsi->u.http.range.count_ranges) { - if (wsi->u.http.range.count_ranges > 1) + if (wsi->http.range.count_ranges) { + if (wsi->http.range.count_ranges > 1) poss -= 7; /* allow for final boundary */ - if (poss > wsi->u.http.range.budget) - poss = wsi->u.http.range.budget; + if (poss > wsi->http.range.budget) + poss = wsi->http.range.budget; } #endif if (wsi->sending_chunked) { @@ -682,7 +682,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) poss -= 10 + 128; } - if (lws_vfs_file_read(wsi->u.http.fop_fd, &amount, p, poss) < 0) + if (lws_vfs_file_read(wsi->http.fop_fd, &amount, p, poss) < 0) goto file_had_it; /* caller will close */ if (wsi->sending_chunked) @@ -700,8 +700,8 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) args.p = (char *)p; args.len = n; args.max_len = (unsigned int)poss + 128; - args.final = wsi->u.http.filepos + n == - wsi->u.http.filelen; + args.final = wsi->http.filepos + n == + wsi->http.filelen; if (user_callback_handle_rxflow( wsi->vhost->protocols[ (int)wsi->protocol_interpret_idx].callback, @@ -714,34 +714,34 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) p = pstart; #if defined(LWS_WITH_RANGES) - if (wsi->u.http.range.send_ctr + 1 == - wsi->u.http.range.count_ranges && // last range - wsi->u.http.range.count_ranges > 1 && // was 2+ ranges (ie, multipart) - wsi->u.http.range.budget - amount == 0) {// final part + if (wsi->http.range.send_ctr + 1 == + wsi->http.range.count_ranges && // last range + wsi->http.range.count_ranges > 1 && // was 2+ ranges (ie, multipart) + wsi->http.range.budget - amount == 0) {// final part n += lws_snprintf((char *)pstart + n, 6, "_lws\x0d\x0a"); // append trailing boundary lwsl_debug("added trailing boundary\n"); } #endif m = lws_write(wsi, p, n, - wsi->u.http.filepos == wsi->u.http.filelen ? + wsi->http.filepos == wsi->http.filelen ? LWS_WRITE_HTTP_FINAL : LWS_WRITE_HTTP ); if (m < 0) goto file_had_it; - wsi->u.http.filepos += amount; + wsi->http.filepos += amount; #if defined(LWS_WITH_RANGES) - if (wsi->u.http.range.count_ranges >= 1) { - wsi->u.http.range.budget -= amount; - if (wsi->u.http.range.budget == 0) { + if (wsi->http.range.count_ranges >= 1) { + wsi->http.range.budget -= amount; + if (wsi->http.range.budget == 0) { lwsl_notice("range budget exhausted\n"); - wsi->u.http.range.inside = 0; - wsi->u.http.range.send_ctr++; + wsi->http.range.inside = 0; + wsi->http.range.send_ctr++; - if (lws_ranges_next(&wsi->u.http.range) < 1) { + if (lws_ranges_next(&wsi->http.range) < 1) { finished = 1; goto all_sent; } @@ -751,7 +751,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) if (m != n) { /* adjust for what was not sent */ - if (lws_vfs_file_seek_cur(wsi->u.http.fop_fd, + if (lws_vfs_file_seek_cur(wsi->http.fop_fd, m - n) == (lws_fileofs_t)-1) goto file_had_it; @@ -759,7 +759,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi) } all_sent: - if ((!wsi->trunc_len && wsi->u.http.filepos >= wsi->u.http.filelen) + if ((!wsi->trunc_len && wsi->http.filepos >= wsi->http.filelen) #if defined(LWS_WITH_RANGES) || finished) #else @@ -768,7 +768,7 @@ all_sent: { wsi->state = LWSS_HTTP; /* we might be in keepalive, so close it off here */ - lws_vfs_file_close(&wsi->u.http.fop_fd); + lws_vfs_file_close(&wsi->http.fop_fd); lwsl_debug("file completed\n"); @@ -806,7 +806,7 @@ all_sent: return 0; /* indicates further processing must be done */ file_had_it: - lws_vfs_file_close(&wsi->u.http.fop_fd); + lws_vfs_file_close(&wsi->http.fop_fd); return -1; } diff --git a/lib/pollfd.c b/lib/pollfd.c index 4c20a55c..8723054c 100644 --- a/lib/pollfd.c +++ b/lib/pollfd.c @@ -464,13 +464,13 @@ lws_callback_on_writable(struct lws *wsi) if (wsi->mode != LWSCM_HTTP2_SERVING) goto network_sock; - if (wsi->u.h2.requested_POLLOUT) { + if (wsi->h2.requested_POLLOUT) { lwsl_info("already pending writable\n"); return 1; } /* is this for DATA or for control messages? */ - if (wsi->upgraded_to_http2 && !wsi->u.h2.h2n->pps && + if (wsi->upgraded_to_http2 && !wsi->h2.h2n->pps && !lws_h2_tx_cr_get(wsi)) { /* * other side is not able to cope with us sending DATA @@ -481,22 +481,22 @@ lws_callback_on_writable(struct lws *wsi) * space for more using tx window command in http2 layer */ lwsl_notice("%s: %p: skint (%d)\n", __func__, wsi, - wsi->u.h2.tx_cr); - wsi->u.h2.skint = 1; + wsi->h2.tx_cr); + wsi->h2.skint = 1; return 0; } - wsi->u.h2.skint = 0; + wsi->h2.skint = 0; network_wsi = lws_get_network_wsi(wsi); - already = network_wsi->u.h2.requested_POLLOUT; + already = network_wsi->h2.requested_POLLOUT; /* mark everybody above him as requesting pollout */ wsi2 = wsi; while (wsi2) { - wsi2->u.h2.requested_POLLOUT = 1; + wsi2->h2.requested_POLLOUT = 1; lwsl_info("mark %p pending writable\n", wsi2); - wsi2 = wsi2->u.h2.parent_wsi; + wsi2 = wsi2->h2.parent_wsi; } /* for network action, act only on the network wsi */ diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index 35dbc762..528b2e29 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1724,12 +1724,6 @@ struct lws_h2_netconn { }; struct _lws_h2_related { - /* - * having this first lets us also re-use all HTTP union code - * and in turn, http_mode_related has allocated headers in right - * place so we can use the header apis on the wsi directly still - */ - struct _lws_http_mode_related http; /* MUST BE FIRST IN STRUCT */ struct lws_h2_netconn *h2n; /* malloc'd for root net conn */ struct lws *parent_wsi; @@ -1754,38 +1748,40 @@ struct _lws_h2_related { uint16_t round_robin_POLLOUT; uint16_t count_POLLOUT_children; + uint8_t h2_state; /* the RFC7540 state of the connection */ uint8_t weight; - uint8_t initialized; }; -#define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->u.h2.parent_wsi) +#define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->h2.parent_wsi) #endif struct _lws_websocket_related { char *rx_ubuf; - unsigned int rx_ubuf_alloc; struct lws *rx_draining_ext_list; struct lws *tx_draining_ext_list; + /* Also used for close content... control opcode == < 128 */ + uint8_t ping_payload_buf[128 - 3 + LWS_PRE]; + uint8_t mask[4]; + time_t time_next_ping_check; size_t rx_packet_length; - unsigned int rx_ubuf_head; - unsigned char mask[4]; - /* Also used for close content... control opcode == < 128 */ - unsigned char ping_payload_buf[128 - 3 + LWS_PRE]; + uint32_t rx_ubuf_head; + uint32_t rx_ubuf_alloc; - unsigned char ping_payload_len; - unsigned char mask_idx; - unsigned char opcode; - unsigned char rsv; - unsigned char rsv_first_msg; + uint8_t ping_payload_len; + uint8_t mask_idx; + uint8_t opcode; + uint8_t rsv; + uint8_t rsv_first_msg; /* zero if no info, or length including 2-byte close code */ - unsigned char close_in_ping_buffer_len; - unsigned char utf8; - unsigned char stashed_write_type; - unsigned char tx_draining_stashed_wp; + uint8_t close_in_ping_buffer_len; + uint8_t utf8; + uint8_t stashed_write_type; + uint8_t tx_draining_stashed_wp; + uint8_t ietf_spec_revision; unsigned int final:1; unsigned int frame_is_binary:1; @@ -1831,17 +1827,19 @@ struct lws_cgi { unsigned char *headers_pos; unsigned char *headers_dumped; unsigned char *headers_end; + lws_filepos_t content_length; lws_filepos_t content_length_seen; + int pipe_fds[3][2]; int match[SIGNIFICANT_HDR_COUNT]; + char l[12]; int pid; int response_code; int lp; - char l[12]; - unsigned int being_closed:1; - unsigned int explicitly_chunked:1; + unsigned char being_closed:1; + unsigned char explicitly_chunked:1; unsigned char chunked_grace; }; @@ -1881,15 +1879,10 @@ struct lws_access_log { struct lws { /* structs */ - /* members with mutually exclusive lifetimes are unionized */ - - union u { - struct _lws_http_mode_related http; + struct _lws_http_mode_related http; #ifdef LWS_WITH_HTTP2 - struct _lws_h2_related h2; + struct _lws_h2_related h2; #endif - struct _lws_websocket_related ws; - } u; /* lifetime members */ @@ -1902,7 +1895,6 @@ struct lws { #ifdef LWS_WITH_ACCESS_LOG struct lws_access_log access_log; #endif - time_t pending_timeout_limit; /* pointers */ @@ -1911,6 +1903,7 @@ struct lws { struct lws *parent; /* points to parent, if any */ struct lws *child_list; /* points to first child */ struct lws *sibling_list; /* subsequent children at same level */ + struct _lws_websocket_related *ws; /* allocated if we upgrade to ws */ #ifdef LWS_WITH_CGI struct lws_cgi *cgi; /* wsi being cgi master have one of these */ #endif @@ -1947,10 +1940,6 @@ struct lws { lws_tls_conn *ssl; lws_tls_bio *client_bio; struct lws *pending_read_list_prev, *pending_read_list_next; -#if defined(LWS_WITH_STATS) - uint64_t accept_start_us; - char seen_rx; -#endif #endif #ifdef LWS_WITH_HTTP_PROXY struct lws_rewrite *rw; @@ -1962,7 +1951,12 @@ struct lws { lws_sock_file_fd_type desc; /* .filefd / .sockfd */ #if defined(LWS_WITH_STATS) uint64_t active_writable_req_us; +#if defined(LWS_OPENSSL_SUPPORT) + uint64_t accept_start_us; #endif +#endif + time_t pending_timeout_limit; + /* ints */ int position_in_fds_table; uint32_t rxflow_len; @@ -2037,9 +2031,8 @@ struct lws { /* chars */ #ifndef LWS_NO_EXTENSIONS - unsigned char count_act_ext; + uint8_t count_act_ext; #endif - uint8_t ietf_spec_revision; char mode; /* enum connection_mode */ char state; /* enum lws_connection_states */ char state_pre_close; @@ -2059,6 +2052,9 @@ struct lws { #endif #if defined(LWS_WITH_CGI) || !defined(LWS_NO_CLIENT) char reason_bf; /* internal writeable callback reason bitfield */ +#endif +#if defined(LWS_WITH_STATS) && defined(LWS_OPENSSL_SUPPORT) + char seen_rx; #endif /* volatile to make sure code is aware other thread can change */ volatile char handling_pollout; diff --git a/lib/server/access-log.c b/lib/server/access-log.c index 3cc15e45..15009da7 100644 --- a/lib/server/access-log.c +++ b/lib/server/access-log.c @@ -77,7 +77,7 @@ lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int meth) lws_snprintf(wsi->access_log.header_log, l, "%s - - [%s] \"%s %s %s\"", pa, da, me, uri_ptr, - hver[wsi->u.http.request_version]); + hver[wsi->http.request_version]); l = lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_USER_AGENT); if (l) { diff --git a/lib/server/cgi.c b/lib/server/cgi.c index 6b089e7b..59f3147d 100644 --- a/lib/server/cgi.c +++ b/lib/server/cgi.c @@ -101,7 +101,6 @@ lws_create_basic_wsi(struct lws_context *context, int tsi) */ new_wsi->protocol = context->vhost_list->protocols; new_wsi->user_space = NULL; - new_wsi->ietf_spec_revision = 0; new_wsi->desc.sockfd = LWS_SOCK_INVALID; context->count_wsi_allocated++; diff --git a/lib/server/parsers.c b/lib/server/parsers.c index 859af77d..d3873039 100644 --- a/lib/server/parsers.c +++ b/lib/server/parsers.c @@ -848,7 +848,7 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c) } if (c == '?' && !enc && - !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI arguments */ + !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI args */ if (ah->ues != URIES_IDLE) goto forbid; @@ -1065,9 +1065,9 @@ swallow: ah->ups = URIPS_IDLE; if (context->token_limits) - ah->current_token_limit = - context->token_limits->token_limit[ - ah->parser_state]; + ah->current_token_limit = context-> + token_limits->token_limit[ + ah->parser_state]; else ah->current_token_limit = wsi->context->max_http_header_data; @@ -1139,10 +1139,10 @@ set_parsing_complete: goto forbid; if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) { if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION)) - wsi->ietf_spec_revision = + wsi->rx_frame_type = /* temp for ws version index */ atoi(lws_hdr_simple_ptr(wsi, WSI_TOKEN_VERSION)); - lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision); + lwsl_parser("v%02d hdrs done\n", wsi->rx_frame_type); } ah->parser_state = WSI_PARSING_COMPLETE; wsi->hdr_parsing_completed = 1; @@ -1158,7 +1158,7 @@ forbid: LWS_VISIBLE int lws_frame_is_binary(struct lws *wsi) { - return wsi->u.ws.frame_is_binary; + return wsi->ws->frame_is_binary; } void @@ -1166,13 +1166,13 @@ lws_add_wsi_to_draining_ext_list(struct lws *wsi) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - if (wsi->u.ws.rx_draining_ext) + if (wsi->ws->rx_draining_ext) return; lwsl_ext("%s: RX EXT DRAINING: Adding to list\n", __func__); - wsi->u.ws.rx_draining_ext = 1; - wsi->u.ws.rx_draining_ext_list = pt->rx_draining_ext_list; + wsi->ws->rx_draining_ext = 1; + wsi->ws->rx_draining_ext_list = pt->rx_draining_ext_list; pt->rx_draining_ext_list = wsi; } @@ -1182,23 +1182,23 @@ lws_remove_wsi_from_draining_ext_list(struct lws *wsi) struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; struct lws **w = &pt->rx_draining_ext_list; - if (!wsi->u.ws.rx_draining_ext) + if (!wsi->ws->rx_draining_ext) return; lwsl_ext("%s: RX EXT DRAINING: Removing from list\n", __func__); - wsi->u.ws.rx_draining_ext = 0; + wsi->ws->rx_draining_ext = 0; /* remove us from context draining ext list */ while (*w) { if (*w == wsi) { /* if us, point it instead to who we were pointing to */ - *w = wsi->u.ws.rx_draining_ext_list; + *w = wsi->ws->rx_draining_ext_list; break; } - w = &((*w)->u.ws.rx_draining_ext_list); + w = &((*w)->ws->rx_draining_ext_list); } - wsi->u.ws.rx_draining_ext_list = NULL; + wsi->ws->rx_draining_ext_list = NULL; } /* @@ -1220,7 +1220,7 @@ lws_rx_sm(struct lws *wsi, unsigned char c) switch (wsi->lws_rx_parse_state) { case LWS_RXPS_NEW: - if (wsi->u.ws.rx_draining_ext) { + if (wsi->ws->rx_draining_ext) { eff_buf.token = NULL; eff_buf.token_len = 0; lws_remove_wsi_from_draining_ext_list(wsi); @@ -1229,43 +1229,43 @@ lws_rx_sm(struct lws *wsi, unsigned char c) goto drain_extension; } - switch (wsi->ietf_spec_revision) { + switch (wsi->ws->ietf_spec_revision) { case 13: /* * no prepended frame key any more */ - wsi->u.ws.all_zero_nonce = 1; + wsi->ws->all_zero_nonce = 1; goto handle_first; default: lwsl_warn("lws_rx_sm: unknown spec version %d\n", - wsi->ietf_spec_revision); + wsi->ws->ietf_spec_revision); break; } break; case LWS_RXPS_04_mask_1: - wsi->u.ws.mask[1] = c; + wsi->ws->mask[1] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_04_mask_2; break; case LWS_RXPS_04_mask_2: - wsi->u.ws.mask[2] = c; + wsi->ws->mask[2] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_04_mask_3; break; case LWS_RXPS_04_mask_3: - wsi->u.ws.mask[3] = c; + wsi->ws->mask[3] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; /* * start from the zero'th byte in the XOR key buffer since * this is the start of a frame with a new key */ - wsi->u.ws.mask_idx = 0; + wsi->ws->mask_idx = 0; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_1; break; @@ -1303,17 +1303,17 @@ lws_rx_sm(struct lws *wsi, unsigned char c) case LWS_RXPS_04_FRAME_HDR_1: handle_first: - wsi->u.ws.opcode = c & 0xf; - wsi->u.ws.rsv = c & 0x70; - wsi->u.ws.final = !!((c >> 7) & 1); + wsi->ws->opcode = c & 0xf; + wsi->ws->rsv = c & 0x70; + wsi->ws->final = !!((c >> 7) & 1); - switch (wsi->u.ws.opcode) { + switch (wsi->ws->opcode) { case LWSWSOPC_TEXT_FRAME: case LWSWSOPC_BINARY_FRAME: - wsi->u.ws.rsv_first_msg = (c & 0x70); - wsi->u.ws.frame_is_binary = - wsi->u.ws.opcode == LWSWSOPC_BINARY_FRAME; - wsi->u.ws.first_fragment = 1; + wsi->ws->rsv_first_msg = (c & 0x70); + wsi->ws->frame_is_binary = + wsi->ws->opcode == LWSWSOPC_BINARY_FRAME; + wsi->ws->first_fragment = 1; break; case 3: case 4: @@ -1333,30 +1333,30 @@ handle_first: case LWS_RXPS_04_FRAME_HDR_LEN: - wsi->u.ws.this_frame_masked = !!(c & 0x80); + wsi->ws->this_frame_masked = !!(c & 0x80); switch (c & 0x7f) { case 126: /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) + if (wsi->ws->opcode & 8) goto illegal_ctl_length; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_2; break; case 127: /* control frames are not allowed to have big lengths */ - if (wsi->u.ws.opcode & 8) + if (wsi->ws->opcode & 8) goto illegal_ctl_length; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_8; break; default: - wsi->u.ws.rx_packet_length = c & 0x7f; - if (wsi->u.ws.this_frame_masked) + wsi->ws->rx_packet_length = c & 0x7f; + if (wsi->ws->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; else - if (wsi->u.ws.rx_packet_length) + if (wsi->ws->rx_packet_length) wsi->lws_rx_parse_state = LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; else { @@ -1368,13 +1368,13 @@ handle_first: break; case LWS_RXPS_04_FRAME_HDR_LEN16_2: - wsi->u.ws.rx_packet_length = c << 8; + wsi->ws->rx_packet_length = c << 8; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN16_1; break; case LWS_RXPS_04_FRAME_HDR_LEN16_1: - wsi->u.ws.rx_packet_length |= c; - if (wsi->u.ws.this_frame_masked) + wsi->ws->rx_packet_length |= c; + if (wsi->ws->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; else @@ -1389,52 +1389,52 @@ handle_first: return -1; } #if defined __LP64__ - wsi->u.ws.rx_packet_length = ((size_t)c) << 56; + wsi->ws->rx_packet_length = ((size_t)c) << 56; #else - wsi->u.ws.rx_packet_length = 0; + wsi->ws->rx_packet_length = 0; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_7; break; case LWS_RXPS_04_FRAME_HDR_LEN64_7: #if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 48; + wsi->ws->rx_packet_length |= ((size_t)c) << 48; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_6; break; case LWS_RXPS_04_FRAME_HDR_LEN64_6: #if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 40; + wsi->ws->rx_packet_length |= ((size_t)c) << 40; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_5; break; case LWS_RXPS_04_FRAME_HDR_LEN64_5: #if defined __LP64__ - wsi->u.ws.rx_packet_length |= ((size_t)c) << 32; + wsi->ws->rx_packet_length |= ((size_t)c) << 32; #endif wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_4; break; case LWS_RXPS_04_FRAME_HDR_LEN64_4: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 24; + wsi->ws->rx_packet_length |= ((size_t)c) << 24; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_3; break; case LWS_RXPS_04_FRAME_HDR_LEN64_3: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 16; + wsi->ws->rx_packet_length |= ((size_t)c) << 16; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_2; break; case LWS_RXPS_04_FRAME_HDR_LEN64_2: - wsi->u.ws.rx_packet_length |= ((size_t)c) << 8; + wsi->ws->rx_packet_length |= ((size_t)c) << 8; wsi->lws_rx_parse_state = LWS_RXPS_04_FRAME_HDR_LEN64_1; break; case LWS_RXPS_04_FRAME_HDR_LEN64_1: - wsi->u.ws.rx_packet_length |= ((size_t)c); - if (wsi->u.ws.this_frame_masked) + wsi->ws->rx_packet_length |= ((size_t)c); + if (wsi->ws->this_frame_masked) wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_1; else @@ -1443,34 +1443,34 @@ handle_first: break; case LWS_RXPS_07_COLLECT_FRAME_KEY_1: - wsi->u.ws.mask[0] = c; + wsi->ws->mask[0] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_2; break; case LWS_RXPS_07_COLLECT_FRAME_KEY_2: - wsi->u.ws.mask[1] = c; + wsi->ws->mask[1] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_3; break; case LWS_RXPS_07_COLLECT_FRAME_KEY_3: - wsi->u.ws.mask[2] = c; + wsi->ws->mask[2] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_07_COLLECT_FRAME_KEY_4; break; case LWS_RXPS_07_COLLECT_FRAME_KEY_4: - wsi->u.ws.mask[3] = c; + wsi->ws->mask[3] = c; if (c) - wsi->u.ws.all_zero_nonce = 0; + wsi->ws->all_zero_nonce = 0; wsi->lws_rx_parse_state = LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED; - wsi->u.ws.mask_idx = 0; - if (wsi->u.ws.rx_packet_length == 0) { + wsi->ws->mask_idx = 0; + if (wsi->ws->rx_packet_length == 0) { wsi->lws_rx_parse_state = LWS_RXPS_NEW; goto spill; } @@ -1478,26 +1478,26 @@ handle_first: case LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED: - assert(wsi->u.ws.rx_ubuf); + assert(wsi->ws->rx_ubuf); - if (wsi->u.ws.rx_draining_ext) + if (wsi->ws->rx_draining_ext) goto drain_extension; - if (wsi->u.ws.rx_ubuf_head + LWS_PRE >= - wsi->u.ws.rx_ubuf_alloc) { + if (wsi->ws->rx_ubuf_head + LWS_PRE >= + wsi->ws->rx_ubuf_alloc) { lwsl_err("Attempted overflow \n"); return -1; } - if (wsi->u.ws.all_zero_nonce) - wsi->u.ws.rx_ubuf[LWS_PRE + - (wsi->u.ws.rx_ubuf_head++)] = c; + if (wsi->ws->all_zero_nonce) + wsi->ws->rx_ubuf[LWS_PRE + + (wsi->ws->rx_ubuf_head++)] = c; else - wsi->u.ws.rx_ubuf[LWS_PRE + - (wsi->u.ws.rx_ubuf_head++)] = - c ^ wsi->u.ws.mask[ - (wsi->u.ws.mask_idx++) & 3]; + wsi->ws->rx_ubuf[LWS_PRE + + (wsi->ws->rx_ubuf_head++)] = + c ^ wsi->ws->mask[ + (wsi->ws->mask_idx++) & 3]; - if (--wsi->u.ws.rx_packet_length == 0) { + if (--wsi->ws->rx_packet_length == 0) { /* spill because we have the whole frame */ wsi->lws_rx_parse_state = LWS_RXPS_NEW; goto spill; @@ -1508,11 +1508,11 @@ handle_first: * supposed to default to context->pt_serv_buf_size */ if (!wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_ubuf_head != wsi->context->pt_serv_buf_size) + wsi->ws->rx_ubuf_head != wsi->context->pt_serv_buf_size) break; if (wsi->protocol->rx_buffer_size && - wsi->u.ws.rx_ubuf_head != wsi->protocol->rx_buffer_size) + wsi->ws->rx_ubuf_head != wsi->protocol->rx_buffer_size) break; /* spill because we filled our rx buffer */ @@ -1524,7 +1524,7 @@ spill: lwsl_parser("spill on %s\n", wsi->protocol->name); - switch (wsi->u.ws.opcode) { + switch (wsi->ws->opcode) { case LWSWSOPC_CLOSE: /* is this an acknowledgement of our close? */ @@ -1555,21 +1555,21 @@ spill: wsi->protocol->callback, wsi, LWS_CALLBACK_WS_PEER_INITIATED_CLOSE, wsi->user_space, - &wsi->u.ws.rx_ubuf[LWS_PRE], - wsi->u.ws.rx_ubuf_head)) + &wsi->ws->rx_ubuf[LWS_PRE], + wsi->ws->rx_ubuf_head)) return -1; lwsl_parser("server sees client close packet\n"); wsi->state = LWSS_RETURNED_CLOSE_ALREADY; /* deal with the close packet contents as a PONG */ - wsi->u.ws.payload_is_close = 1; + wsi->ws->payload_is_close = 1; goto process_as_ping; case LWSWSOPC_PING: lwsl_info("received %d byte ping, sending pong\n", - wsi->u.ws.rx_ubuf_head); + wsi->ws->rx_ubuf_head); - if (wsi->u.ws.ping_pending_flag) { + if (wsi->ws->ping_pending_flag) { /* * there is already a pending ping payload * we should just log and drop @@ -1579,32 +1579,34 @@ spill: } process_as_ping: /* control packets can only be < 128 bytes long */ - if (wsi->u.ws.rx_ubuf_head > 128 - 3) { + if (wsi->ws->rx_ubuf_head > 128 - 3) { lwsl_parser("DROP PING payload too large\n"); goto ping_drop; } /* stash the pong payload */ - memcpy(wsi->u.ws.ping_payload_buf + LWS_PRE, - &wsi->u.ws.rx_ubuf[LWS_PRE], - wsi->u.ws.rx_ubuf_head); + memcpy(wsi->ws->ping_payload_buf + LWS_PRE, + &wsi->ws->rx_ubuf[LWS_PRE], + wsi->ws->rx_ubuf_head); - wsi->u.ws.ping_payload_len = wsi->u.ws.rx_ubuf_head; - wsi->u.ws.ping_pending_flag = 1; + wsi->ws->ping_payload_len = wsi->ws->rx_ubuf_head; + wsi->ws->ping_pending_flag = 1; /* get it sent as soon as possible */ lws_callback_on_writable(wsi); ping_drop: - wsi->u.ws.rx_ubuf_head = 0; + wsi->ws->rx_ubuf_head = 0; return 0; case LWSWSOPC_PONG: lwsl_info("received pong\n"); - lwsl_hexdump(&wsi->u.ws.rx_ubuf[LWS_PRE], - wsi->u.ws.rx_ubuf_head); + lwsl_hexdump(&wsi->ws->rx_ubuf[LWS_PRE], + wsi->ws->rx_ubuf_head); - if (wsi->pending_timeout == PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) { - lwsl_info("received expected PONG on wsi %p\n", wsi); + if (wsi->pending_timeout == + PENDING_TIMEOUT_WS_PONG_CHECK_GET_PONG) { + lwsl_info("received expected PONG on wsi %p\n", + wsi); lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0); } @@ -1619,23 +1621,24 @@ ping_drop: default: lwsl_parser("passing opc %x up to exts\n", - wsi->u.ws.opcode); + wsi->ws->opcode); /* * It's something special we can't understand here. * Pass the payload up to the extension's parsing * state machine. */ - eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE]; - eff_buf.token_len = wsi->u.ws.rx_ubuf_head; + eff_buf.token = &wsi->ws->rx_ubuf[LWS_PRE]; + eff_buf.token_len = wsi->ws->rx_ubuf_head; - if (lws_ext_cb_active(wsi, LWS_EXT_CB_EXTENDED_PAYLOAD_RX, + if (lws_ext_cb_active(wsi, + LWS_EXT_CB_EXTENDED_PAYLOAD_RX, &eff_buf, 0) <= 0) /* not handle or fail */ lwsl_ext("ext opc opcode 0x%x unknown\n", - wsi->u.ws.opcode); + wsi->ws->opcode); - wsi->u.ws.rx_ubuf_head = 0; + wsi->ws->rx_ubuf_head = 0; return 0; } @@ -1645,10 +1648,10 @@ ping_drop: * so it can be sent straight out again using lws_write */ - eff_buf.token = &wsi->u.ws.rx_ubuf[LWS_PRE]; - eff_buf.token_len = wsi->u.ws.rx_ubuf_head; + eff_buf.token = &wsi->ws->rx_ubuf[LWS_PRE]; + eff_buf.token_len = wsi->ws->rx_ubuf_head; - if (wsi->u.ws.opcode == LWSWSOPC_PONG && !eff_buf.token_len) + if (wsi->ws->opcode == LWSWSOPC_PONG && !eff_buf.token_len) goto already_done; drain_extension: @@ -1663,7 +1666,7 @@ drain_extension: * eff_buf may be pointing somewhere completely different now, * it's the output */ - wsi->u.ws.first_fragment = 0; + wsi->ws->first_fragment = 0; if (n < 0) { /* * we may rely on this to get RX, just drop connection @@ -1692,8 +1695,8 @@ drain_extension: ret = user_callback_handle_rxflow( wsi->protocol->callback, - wsi, - (enum lws_callback_reasons)callback_action, + wsi, (enum lws_callback_reasons) + callback_action, wsi->user_space, eff_buf.token, eff_buf.token_len); @@ -1703,7 +1706,7 @@ drain_extension: } already_done: - wsi->u.ws.rx_ubuf_head = 0; + wsi->ws->rx_ubuf_head = 0; break; } @@ -1719,7 +1722,7 @@ illegal_ctl_length: LWS_VISIBLE size_t lws_remaining_packet_payload(struct lws *wsi) { - return wsi->u.ws.rx_packet_length; + return wsi->ws->rx_packet_length; } /* Once we reach LWS_RXPS_PAYLOAD_UNTIL_LENGTH_EXHAUSTED, we know how much @@ -1739,11 +1742,11 @@ lws_payload_until_length_exhausted(struct lws *wsi, unsigned char **buf, buffer_size = (int)wsi->protocol->rx_buffer_size; else buffer_size = wsi->context->pt_serv_buf_size; - avail = buffer_size - wsi->u.ws.rx_ubuf_head; + avail = buffer_size - wsi->ws->rx_ubuf_head; /* do not consume more than we should */ - if (avail > wsi->u.ws.rx_packet_length) - avail = (unsigned int)wsi->u.ws.rx_packet_length; + if (avail > wsi->ws->rx_packet_length) + avail = (unsigned int)wsi->ws->rx_packet_length; /* do not consume more than what is in the buffer */ if (avail > *len) @@ -1754,13 +1757,13 @@ lws_payload_until_length_exhausted(struct lws *wsi, unsigned char **buf, return 0; avail--; - rx_ubuf = wsi->u.ws.rx_ubuf + LWS_PRE + wsi->u.ws.rx_ubuf_head; - if (wsi->u.ws.all_zero_nonce) + rx_ubuf = wsi->ws->rx_ubuf + LWS_PRE + wsi->ws->rx_ubuf_head; + if (wsi->ws->all_zero_nonce) memcpy(rx_ubuf, buffer, avail); else { for (n = 0; n < 4; n++) - mask[n] = wsi->u.ws.mask[(wsi->u.ws.mask_idx + n) & 3]; + mask[n] = wsi->ws->mask[(wsi->ws->mask_idx + n) & 3]; /* deal with 4-byte chunks using unwrapped loop */ n = avail >> 2; @@ -1774,12 +1777,12 @@ lws_payload_until_length_exhausted(struct lws *wsi, unsigned char **buf, for (n = 0; n < (int)(avail & 3); n++) *(rx_ubuf++) = *(buffer++) ^ mask[n]; - wsi->u.ws.mask_idx = (wsi->u.ws.mask_idx + avail) & 3; + wsi->ws->mask_idx = (wsi->ws->mask_idx + avail) & 3; } (*buf) += avail; - wsi->u.ws.rx_ubuf_head += avail; - wsi->u.ws.rx_packet_length -= avail; + wsi->ws->rx_ubuf_head += avail; + wsi->ws->rx_packet_length -= avail; *len -= avail; return avail; diff --git a/lib/server/server.c b/lib/server/server.c index 1f46d206..6ded8b4d 100644 --- a/lib/server/server.c +++ b/lib/server/server.c @@ -417,12 +417,12 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, spin++; fops = lws_vfs_select_fops(wsi->context->fops, path, &vpath); - if (wsi->u.http.fop_fd) - lws_vfs_file_close(&wsi->u.http.fop_fd); + if (wsi->http.fop_fd) + lws_vfs_file_close(&wsi->http.fop_fd); - wsi->u.http.fop_fd = fops->LWS_FOP_OPEN(wsi->context->fops, + wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->context->fops, path, vpath, &fflags); - if (!wsi->u.http.fop_fd) { + if (!wsi->http.fop_fd) { lwsl_err("Unable to open '%s'\n", path); return -1; @@ -435,7 +435,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, break; #endif #if !defined(WIN32) - if (fstat(wsi->u.http.fop_fd->fd, &st)) { + if (fstat(wsi->http.fop_fd->fd, &st)) { lwsl_info("unable to stat %s\n", path); goto bail; } @@ -453,7 +453,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, #endif #endif - wsi->u.http.fop_fd->mod_time = (uint32_t)st.st_mtime; + wsi->http.fop_fd->mod_time = (uint32_t)st.st_mtime; fflags |= LWS_FOP_FLAG_MOD_TIME_VALID; #if !defined(WIN32) && LWS_POSIX && !defined(LWS_WITH_ESP32) @@ -480,8 +480,8 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, lwsl_err("symlink loop %s \n", path); n = sprintf(sym, "%08llX%08lX", - (unsigned long long)lws_vfs_get_length(wsi->u.http.fop_fd), - (unsigned long)lws_vfs_get_mod_time(wsi->u.http.fop_fd)); + (unsigned long long)lws_vfs_get_length(wsi->http.fop_fd), + (unsigned long)lws_vfs_get_mod_time(wsi->http.fop_fd)); /* disable ranges if IF_RANGE token invalid */ @@ -523,7 +523,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, return -1; } - lws_vfs_file_close(&wsi->u.http.fop_fd); + lws_vfs_file_close(&wsi->http.fop_fd); return lws_http_transaction_completed(wsi); } @@ -817,21 +817,21 @@ lws_http_action(struct lws *wsi) /* HTTP header had a content length? */ - wsi->u.http.rx_content_length = 0; + wsi->http.rx_content_length = 0; if (lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) || lws_hdr_total_length(wsi, WSI_TOKEN_PATCH_URI) || lws_hdr_total_length(wsi, WSI_TOKEN_PUT_URI)) - wsi->u.http.rx_content_length = 100 * 1024 * 1024; + wsi->http.rx_content_length = 100 * 1024 * 1024; if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) { lws_hdr_copy(wsi, content_length_str, sizeof(content_length_str) - 1, WSI_TOKEN_HTTP_CONTENT_LENGTH); - wsi->u.http.rx_content_length = atoll(content_length_str); + wsi->http.rx_content_length = atoll(content_length_str); } if (wsi->http2_substream) { - wsi->u.http.request_version = HTTP_VERSION_2; + wsi->http.request_version = HTTP_VERSION_2; } else { /* http_version? Default to 1.0, override with token: */ request_version = HTTP_VERSION_1_0; @@ -846,7 +846,7 @@ lws_http_action(struct lws *wsi) http_version_str[7] == '1') request_version = HTTP_VERSION_1_1; } - wsi->u.http.request_version = request_version; + wsi->http.request_version = request_version; /* HTTP/1.1 defaults to "keep-alive", 1.0 to "close" */ if (request_version == HTTP_VERSION_1_1) @@ -866,7 +866,7 @@ lws_http_action(struct lws *wsi) if (!strcasecmp(http_conn_str, "close")) connection_type = HTTP_CONNECTION_CLOSE; } - wsi->u.http.connection_type = connection_type; + wsi->http.connection_type = connection_type; } n = wsi->protocol->callback(wsi, LWS_CALLBACK_FILTER_HTTP_CONNECTION, @@ -1251,15 +1251,15 @@ deal_body: */ if (wsi->state != LWSS_HTTP_ISSUING_FILE) { /* Prepare to read body if we have a content length: */ - lwsl_debug("wsi->u.http.rx_content_length %lld %d %d\n", - (long long)wsi->u.http.rx_content_length, + lwsl_debug("wsi->http.rx_content_length %lld %d %d\n", + (long long)wsi->http.rx_content_length, wsi->upgraded_to_http2, wsi->http2_substream); - if (wsi->u.http.rx_content_length > 0) { + if (wsi->http.rx_content_length > 0) { lwsl_notice("%s: %p: LWSS_HTTP_BODY state set\n", __func__, wsi); wsi->state = LWSS_HTTP_BODY; - wsi->u.http.rx_content_remain = - wsi->u.http.rx_content_length; + wsi->http.rx_content_remain = + wsi->http.rx_content_length; } } @@ -1298,12 +1298,12 @@ lws_server_init_wsi_for_ws(struct lws *wsi) if (!n) n = wsi->context->pt_serv_buf_size; n += LWS_PRE; - wsi->u.ws.rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */, "rx_ubuf"); - if (!wsi->u.ws.rx_ubuf) { + wsi->ws->rx_ubuf = lws_malloc(n + 4 /* 0x0000ffff zlib */, "rx_ubuf"); + if (!wsi->ws->rx_ubuf) { lwsl_err("Out of Mem allocating rx buffer %d\n", n); return 1; } - wsi->u.ws.rx_ubuf_alloc = n; + wsi->ws->rx_ubuf_alloc = n; lwsl_debug("Allocating RX buffer %d\n", n); #if LWS_POSIX && !defined(LWS_WITH_ESP32) @@ -1512,7 +1512,7 @@ raw_transition: lws_union_transition(wsi, LWSCM_HTTP_SERVING_ACCEPTED); wsi->state = LWSS_HTTP; - wsi->u.http.fop_fd = NULL; + wsi->http.fop_fd = NULL; lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi, (void *)wsi->ah); @@ -1543,10 +1543,10 @@ upgrade_h2c: lws_union_transition(wsi, LWSCM_HTTP2_SERVING); - if (!wsi->u.h2.h2n) { - wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n), + if (!wsi->h2.h2n) { + wsi->h2.h2n = lws_zalloc(sizeof(*wsi->h2.h2n), "h2n"); - if (!wsi->u.h2.h2n) + if (!wsi->h2.h2n) return 1; } @@ -1554,10 +1554,10 @@ upgrade_h2c: /* HTTP2 union */ - lws_h2_settings(wsi, &wsi->u.h2.h2n->set, + lws_h2_settings(wsi, &wsi->h2.h2n->set, (unsigned char *)protocol_list, n); - lws_hpack_dynamic_size(wsi, wsi->u.h2.h2n->set.s[ + lws_hpack_dynamic_size(wsi, wsi->h2.h2n->set.s[ H2SET_HEADER_TABLE_SIZE]); strcpy(protocol_list, "HTTP/1.1 101 Switching Protocols\x0d\x0a" @@ -1656,6 +1656,16 @@ upgrade_ws: (int)wsi->vhost->default_protocol_index]; } + /* allocate the ws struct for the wsi */ + wsi->ws = lws_zalloc(sizeof(*wsi->ws), "ws struct"); + if (!wsi->ws) { + lwsl_notice("OOM\n"); + goto bail_nuke_ah; + } + + /* set it from the parser temp */ + wsi->ws->ietf_spec_revision = wsi->rx_frame_type; + /* allocate wsi->user storage */ if (lws_ensure_user_space(wsi)) goto bail_nuke_ah; @@ -1677,7 +1687,7 @@ upgrade_ws: * client announced */ - switch (wsi->ietf_spec_revision) { + switch (wsi->ws->ietf_spec_revision) { case 13: lwsl_parser("lws_parse calling handshake_04\n"); if (handshake_0405(context, wsi)) { @@ -1688,7 +1698,7 @@ upgrade_ws: default: lwsl_info("Unknown client spec version %d\n", - wsi->ietf_spec_revision); + wsi->ws->ietf_spec_revision); goto bail_nuke_ah; } @@ -1721,7 +1731,7 @@ upgrade_ws: lws_server_init_wsi_for_ws(wsi); lwsl_parser("accepted v%02d connection\n", - wsi->ietf_spec_revision); + wsi->ws->ietf_spec_revision); /* !!! drop ah unreservedly after ESTABLISHED */ if (!wsi->more_rx_waiting) { @@ -1806,7 +1816,6 @@ lws_create_new_server_wsi(struct lws_vhost *vhost) */ new_wsi->protocol = vhost->protocols; new_wsi->user_space = NULL; - new_wsi->ietf_spec_revision = 0; new_wsi->desc.sockfd = LWS_SOCK_INVALID; new_wsi->position_in_fds_table = -1; @@ -1844,7 +1853,7 @@ lws_http_transaction_completed(struct lws *wsi) if (wsi->seen_zero_length_recv) return 1; - if (wsi->u.http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { + if (wsi->http.connection_type != HTTP_CONNECTION_KEEP_ALIVE) { lwsl_info("%s: %p: close connection\n", __func__, wsi); return 1; } @@ -1855,8 +1864,8 @@ lws_http_transaction_completed(struct lws *wsi) /* otherwise set ourselves up ready to go again */ wsi->state = LWSS_HTTP; wsi->mode = LWSCM_HTTP_SERVING; - wsi->u.http.tx_content_length = 0; - wsi->u.http.tx_content_remain = 0; + wsi->http.tx_content_length = 0; + wsi->http.tx_content_remain = 0; wsi->hdr_parsing_completed = 0; #ifdef LWS_WITH_ACCESS_LOG wsi->access_log.sent = 0; @@ -1912,11 +1921,11 @@ lws_http_transaction_completed(struct lws *wsi) lws_set_timeout(wsi, PENDING_TIMEOUT_HOLDING_AH, wsi->vhost->keepalive_timeout); } + /* If we're (re)starting on headers, need other implied init */ + if (wsi->ah) + wsi->ah->ues = URIES_IDLE; } - /* If we're (re)starting on headers, need other implied init */ - wsi->ah->ues = URIES_IDLE; - lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi); return 0; @@ -1996,6 +2005,12 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type, lwsl_debug("binding to %s\n", new_wsi->protocol->name); lws_bind_protocol(new_wsi, new_wsi->protocol); lws_union_transition(new_wsi, LWSCM_WS_SERVING); + /* allocate the ws struct for the wsi */ + new_wsi->ws = lws_zalloc(sizeof(*new_wsi->ws), "ws struct"); + if (!new_wsi->ws) { + lwsl_notice("OOM\n"); + goto bail; + } lws_server_init_wsi_for_ws(new_wsi); return new_wsi; @@ -2626,7 +2641,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, struct lws_context *context = lws_get_context(wsi); struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; #if defined(LWS_WITH_RANGES) - struct lws_range_parsing *rp = &wsi->u.http.range; + struct lws_range_parsing *rp = &wsi->http.range; #endif char cache_control[50], *cc = "no-store"; unsigned char *response = pt->serv_buf + LWS_PRE; @@ -2646,24 +2661,24 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, * or we call fops_zip .open with first arg platform fops, and fops_zip * open will decide whether to switch to fops_zip or stay with fops_def. * - * If wsi->u.http.fop_fd is already set, the caller already opened it + * If wsi->http.fop_fd is already set, the caller already opened it */ - if (!wsi->u.http.fop_fd) { + if (!wsi->http.fop_fd) { fops = lws_vfs_select_fops(wsi->context->fops, file, &vpath); fflags |= lws_vfs_prepare_flags(wsi); - wsi->u.http.fop_fd = fops->LWS_FOP_OPEN(wsi->context->fops, + wsi->http.fop_fd = fops->LWS_FOP_OPEN(wsi->context->fops, file, vpath, &fflags); - if (!wsi->u.http.fop_fd) { + if (!wsi->http.fop_fd) { lwsl_err("Unable to open '%s'\n", file); return -1; } } - wsi->u.http.filelen = lws_vfs_get_length(wsi->u.http.fop_fd); - total_content_length = wsi->u.http.filelen; + wsi->http.filelen = lws_vfs_get_length(wsi->http.fop_fd); + total_content_length = wsi->http.filelen; #if defined(LWS_WITH_RANGES) - ranges = lws_ranges_init(wsi, rp, wsi->u.http.filelen); + ranges = lws_ranges_init(wsi, rp, wsi->http.filelen); lwsl_debug("Range count %d\n", ranges); /* @@ -2680,7 +2695,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_http_transaction_completed(wsi)) return -1; /* <0 means just hang up */ - lws_vfs_file_close(&wsi->u.http.fop_fd); + lws_vfs_file_close(&wsi->http.fop_fd); return 0; /* == 0 means we dealt with the transaction complete */ } @@ -2691,7 +2706,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, if (lws_add_http_header_status(wsi, n, &p, end)) return -1; - if ((wsi->u.http.fop_fd->flags & (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | + if ((wsi->http.fop_fd->flags & (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | LWS_FOP_FLAG_COMPR_IS_GZIP)) == (LWS_FOP_FLAG_COMPR_ACCEPTABLE_GZIP | LWS_FOP_FLAG_COMPR_IS_GZIP)) { if (lws_add_http_header_by_token(wsi, @@ -2715,10 +2730,10 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, #if defined(LWS_WITH_RANGES) if (ranges >= 2) { /* multipart byteranges */ - strncpy(wsi->u.http.multipart_content_type, content_type, - sizeof(wsi->u.http.multipart_content_type) - 1); - wsi->u.http.multipart_content_type[ - sizeof(wsi->u.http.multipart_content_type) - 1] = '\0'; + strncpy(wsi->http.multipart_content_type, content_type, + sizeof(wsi->http.multipart_content_type) - 1); + wsi->http.multipart_content_type[ + sizeof(wsi->http.multipart_content_type) - 1] = '\0'; if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_CONTENT_TYPE, (unsigned char *) @@ -2774,7 +2789,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, return -1; } - wsi->u.http.range.inside = 0; + wsi->http.range.inside = 0; if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_ACCEPT_RANGES, (unsigned char *)"bytes", 5, &p, end)) @@ -2810,7 +2825,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, (unsigned char *)cc, cclen, &p, end)) return -1; - if (wsi->u.http.connection_type == HTTP_CONNECTION_KEEP_ALIVE) + if (wsi->http.connection_type == HTTP_CONNECTION_KEEP_ALIVE) if (lws_add_http_header_by_token(wsi, WSI_TOKEN_CONNECTION, (unsigned char *)"keep-alive", 10, &p, end)) return -1; @@ -2832,7 +2847,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type, return -1; } - wsi->u.http.filepos = 0; + wsi->http.filepos = 0; wsi->state = LWSS_HTTP_ISSUING_FILE; lws_callback_on_writable(wsi); @@ -2859,7 +2874,7 @@ lws_interpret_incoming_packet(struct lws *wsi, unsigned char **buf, size_t len) return 1; } - if (wsi->u.ws.rx_draining_ext) { + if (wsi->ws->rx_draining_ext) { m = lws_rx_sm(wsi, 0); if (m < 0) return -1; diff --git a/lib/service.c b/lib/service.c index ec449d09..93269170 100644 --- a/lib/service.c +++ b/lib/service.c @@ -117,13 +117,13 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd) /* * Priority 2: protocol packets */ - if (wsi->upgraded_to_http2 && wsi->u.h2.h2n->pps) { + if (wsi->upgraded_to_http2 && wsi->h2.h2n->pps) { lwsl_info("servicing pps\n"); if (lws_h2_do_pps_send(wsi)) { wsi->socket_is_permanently_unusable = 1; goto bail_die; } - if (wsi->u.h2.h2n->pps) + if (wsi->h2.h2n->pps) goto bail_ok; /* we can resume whatever we were doing */ @@ -154,8 +154,8 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd) if (wsi->state == LWSS_WAITING_TO_SEND_CLOSE_NOTIFICATION) { lwsl_debug("sending close packet\n"); wsi->waiting_to_send_close_frame = 0; - n = lws_write(wsi, &wsi->u.ws.ping_payload_buf[LWS_PRE], - wsi->u.ws.close_in_ping_buffer_len, + n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE], + wsi->ws->close_in_ping_buffer_len, LWS_WRITE_CLOSE); if (n >= 0) { wsi->state = LWSS_AWAITING_CLOSE_ACK; @@ -171,21 +171,21 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd) /* else, the send failed and we should just hang up */ if ((wsi->state == LWSS_ESTABLISHED && - wsi->u.ws.ping_pending_flag) || + wsi->ws->ping_pending_flag) || (wsi->state == LWSS_RETURNED_CLOSE_ALREADY && - wsi->u.ws.payload_is_close)) { + wsi->ws->payload_is_close)) { - if (wsi->u.ws.payload_is_close) + if (wsi->ws->payload_is_close) write_type = LWS_WRITE_CLOSE; - n = lws_write(wsi, &wsi->u.ws.ping_payload_buf[LWS_PRE], - wsi->u.ws.ping_payload_len, write_type); + n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE], + wsi->ws->ping_payload_len, write_type); if (n < 0) goto bail_die; /* well he is sent, mark him done */ - wsi->u.ws.ping_pending_flag = 0; - if (wsi->u.ws.payload_is_close) + wsi->ws->ping_pending_flag = 0; + if (wsi->ws->payload_is_close) /* oh... a close frame was it... then we are done */ goto bail_die; @@ -195,11 +195,11 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd) if (wsi->state == LWSS_ESTABLISHED && !wsi->socket_is_permanently_unusable && - wsi->u.ws.send_check_ping) { + wsi->ws->send_check_ping) { lwsl_info("issuing ping on wsi %p\n", wsi); - wsi->u.ws.send_check_ping = 0; - n = lws_write(wsi, &wsi->u.ws.ping_payload_buf[LWS_PRE], + wsi->ws->send_check_ping = 0; + n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE], 0, LWS_WRITE_PING); if (n < 0) goto bail_die; @@ -229,7 +229,7 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd) * payload ordering, but since they are always complete * fragments control packets can interleave OK. */ - if (wsi->state == LWSS_ESTABLISHED && wsi->u.ws.tx_draining_ext) { + if (wsi->state == LWSS_ESTABLISHED && wsi->ws->tx_draining_ext) { lwsl_ext("SERVICING TX EXT DRAINING\n"); if (lws_write(wsi, NULL, 0, LWS_WRITE_CONTINUATION) < 0) goto bail_die; @@ -387,8 +387,8 @@ user_service_go_again: goto notify; } - wsi->u.h2.requested_POLLOUT = 0; - if (!wsi->u.h2.initialized) { + wsi->h2.requested_POLLOUT = 0; + if (!wsi->h2.initialized) { lwsl_info("pollout on uninitialized http2 conn\n"); goto bail_ok; } @@ -399,25 +399,25 @@ user_service_go_again: // } lwsl_info("%s: %p: children waiting for POLLOUT service:\n", __func__, wsi); - wsi2a = wsi->u.h2.child_list; + wsi2a = wsi->h2.child_list; while (wsi2a) { - if (wsi2a->u.h2.requested_POLLOUT) + if (wsi2a->h2.requested_POLLOUT) lwsl_debug(" * %p\n", wsi2a); else lwsl_debug(" %p\n", wsi2a); - wsi2a = wsi2a->u.h2.sibling_list; + wsi2a = wsi2a->h2.sibling_list; } - wsi2 = &wsi->u.h2.child_list; + wsi2 = &wsi->h2.child_list; if (!*wsi2) goto bail_ok; do { struct lws *w, **wa; - wa = &(*wsi2)->u.h2.sibling_list; - if (!(*wsi2)->u.h2.requested_POLLOUT) { + wa = &(*wsi2)->h2.sibling_list; + if (!(*wsi2)->h2.requested_POLLOUT) { lwsl_debug(" child %p doesn't want POLLOUT\n", *wsi2); goto next_child; } @@ -431,37 +431,37 @@ user_service_go_again: w = *wsi2; while (w) { - if (!w->u.h2.sibling_list) { /* w is the current last */ + if (!w->h2.sibling_list) { /* w is the current last */ lwsl_debug("w=%p, *wsi2 = %p\n", w, *wsi2); if (w == *wsi2) /* we are already last */ break; /* last points to us as new last */ - w->u.h2.sibling_list = *wsi2; + w->h2.sibling_list = *wsi2; /* guy pointing to us until now points to * our old next */ - *wsi2 = (*wsi2)->u.h2.sibling_list; + *wsi2 = (*wsi2)->h2.sibling_list; /* we point to nothing because we are last */ - w->u.h2.sibling_list->u.h2.sibling_list = NULL; + w->h2.sibling_list->h2.sibling_list = NULL; /* w becomes us */ - w = w->u.h2.sibling_list; + w = w->h2.sibling_list; break; } - w = w->u.h2.sibling_list; + w = w->h2.sibling_list; } - w->u.h2.requested_POLLOUT = 0; + w->h2.requested_POLLOUT = 0; lwsl_info("%s: child %p (state %d)\n", __func__, (*wsi2), (*wsi2)->state); - if (w->u.h2.pending_status_body) { - w->u.h2.send_END_STREAM = 1; - n = lws_write(w, (uint8_t *)w->u.h2.pending_status_body + + if (w->h2.pending_status_body) { + w->h2.send_END_STREAM = 1; + n = lws_write(w, (uint8_t *)w->h2.pending_status_body + LWS_PRE, - strlen(w->u.h2.pending_status_body + + strlen(w->h2.pending_status_body + LWS_PRE), LWS_WRITE_HTTP_FINAL); - lws_free_set_NULL(w->u.h2.pending_status_body); + lws_free_set_NULL(w->h2.pending_status_body); lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS); - wa = &wsi->u.h2.child_list; + wa = &wsi->h2.child_list; goto next_child; } @@ -482,10 +482,10 @@ user_service_go_again: * We will often hear about out having sent the final * DATA here... if so close the actual wsi */ - if (n < 0 || w->u.h2.send_END_STREAM) { + if (n < 0 || w->h2.send_END_STREAM) { lwsl_debug("Closing POLLOUT child %p\n", w); lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS); - wa = &wsi->u.h2.child_list; + wa = &wsi->h2.child_list; goto next_child; } if (n > 0) @@ -493,16 +493,16 @@ user_service_go_again: goto bail_die; if (!n) { lws_callback_on_writable(w); - (w)->u.h2.requested_POLLOUT = 1; + (w)->h2.requested_POLLOUT = 1; } goto next_child; } - if (lws_calllback_as_writeable(w) || w->u.h2.send_END_STREAM) { + if (lws_calllback_as_writeable(w) || w->h2.send_END_STREAM) { lwsl_debug("Closing POLLOUT child\n"); lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS); - wa = &wsi->u.h2.child_list; + wa = &wsi->h2.child_list; } next_child: @@ -510,25 +510,25 @@ next_child: } while (wsi2 && *wsi2 && !lws_send_pipe_choked(wsi)); lwsl_info("%s: %p: children waiting for POLLOUT service: %p\n", - __func__, wsi, wsi->u.h2.child_list); - wsi2a = wsi->u.h2.child_list; + __func__, wsi, wsi->h2.child_list); + wsi2a = wsi->h2.child_list; while (wsi2a) { - if (wsi2a->u.h2.requested_POLLOUT) + if (wsi2a->h2.requested_POLLOUT) lwsl_debug(" * %p\n", wsi2a); else lwsl_debug(" %p\n", wsi2a); - wsi2a = wsi2a->u.h2.sibling_list; + wsi2a = wsi2a->h2.sibling_list; } - wsi2a = wsi->u.h2.child_list; + wsi2a = wsi->h2.child_list; while (wsi2a) { - if (wsi2a->u.h2.requested_POLLOUT) { + if (wsi2a->h2.requested_POLLOUT) { lws_change_pollfd(wsi, 0, LWS_POLLOUT); break; } - wsi2a = wsi2a->u.h2.sibling_list; + wsi2a = wsi2a->h2.sibling_list; } goto bail_ok; @@ -632,7 +632,7 @@ int lws_rxflow_cache(struct lws *wsi, unsigned char *buf, int n, int len) { #if defined(LWS_WITH_HTTP2) if (wsi->upgraded_to_http2) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; assert(h2n->rx_scratch); buf += n; @@ -751,7 +751,7 @@ lws_service_flag_pending(struct lws_context *context, int tsi) forced = 1; break; } - wsi = wsi->u.ws.rx_draining_ext_list; + wsi = wsi->ws->rx_draining_ext_list; } #ifdef LWS_OPENSSL_SUPPORT @@ -891,9 +891,9 @@ spin_chunks: if (wsi->chunked && !wsi->chunk_remaining) return 0; - if (wsi->u.http.rx_content_remain && - wsi->u.http.rx_content_remain < (unsigned int)*len) - n = (int)wsi->u.http.rx_content_remain; + if (wsi->http.rx_content_remain && + wsi->http.rx_content_remain < (unsigned int)*len) + n = (int)wsi->http.rx_content_remain; else n = *len; @@ -932,10 +932,10 @@ spin_chunks: return 0; /* if we know the content length, decrement the content remaining */ - if (wsi->u.http.rx_content_length > 0) - wsi->u.http.rx_content_remain -= n; + if (wsi->http.rx_content_length > 0) + wsi->http.rx_content_remain -= n; - if (wsi->u.http.rx_content_remain || !wsi->u.http.rx_content_length) + if (wsi->http.rx_content_remain || !wsi->http.rx_content_length) return 0; completed: @@ -1150,18 +1150,18 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, while (wsi) { if (wsi->state == LWSS_ESTABLISHED && !wsi->socket_is_permanently_unusable && - !wsi->u.ws.send_check_ping && - wsi->u.ws.time_next_ping_check && - wsi->u.ws.time_next_ping_check < now) { + !wsi->ws->send_check_ping && + wsi->ws->time_next_ping_check && + wsi->ws->time_next_ping_check < now) { lwsl_info("req pp on wsi %p\n", wsi); - wsi->u.ws.send_check_ping = 1; + wsi->ws->send_check_ping = 1; lws_set_timeout(wsi, PENDING_TIMEOUT_WS_PONG_CHECK_SEND_PING, context->timeout_secs); lws_callback_on_writable(wsi); - wsi->u.ws.time_next_ping_check = + wsi->ws->time_next_ping_check = now + wsi->context-> ws_ping_pong_interval; @@ -1360,10 +1360,11 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, * draining. */ lws_rx_flow_control(wsi, 1); - wsi->u.ws.tx_draining_ext = 0; + if (wsi->ws) + wsi->ws->tx_draining_ext = 0; } - if (wsi->u.ws.tx_draining_ext) + if (wsi->ws && wsi->ws->tx_draining_ext) /* we cannot deal with new RX until the TX ext * path has been drained. It's because new * rx will, eg, crap on the wsi rx buf that @@ -1397,7 +1398,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, */ if (wsi->state == LWSS_ESTABLISHED && - wsi->u.ws.rx_draining_ext) { + wsi->ws->rx_draining_ext) { lwsl_ext("%s: RX EXT DRAINING: Service\n", __func__); #ifndef LWS_NO_CLIENT @@ -1413,7 +1414,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, goto handled; } - if (wsi->u.ws.rx_draining_ext) + if (wsi->ws && wsi->ws->rx_draining_ext) /* * We have RX EXT content to drain, but can't do it * right now. That means we cannot do anything lower @@ -1438,7 +1439,7 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd, #if defined(LWS_WITH_HTTP2) if (wsi->upgraded_to_http2) { - struct lws_h2_netconn *h2n = wsi->u.h2.h2n; + struct lws_h2_netconn *h2n = wsi->h2.h2n; if (h2n->rx_scratch_len) { lwsl_info("%s: %p: h2 rx pos = %d len = %d\n", @@ -1488,15 +1489,15 @@ read: #if defined(LWS_WITH_HTTP2) if (wsi->upgraded_to_http2) { - if (!wsi->u.h2.h2n->rx_scratch) { - wsi->u.h2.h2n->rx_scratch = + if (!wsi->h2.h2n->rx_scratch) { + wsi->h2.h2n->rx_scratch = lws_malloc( LWS_H2_RX_SCRATCH_SIZE, "h2 rx scratch"); - if (!wsi->u.h2.h2n->rx_scratch) + if (!wsi->h2.h2n->rx_scratch) goto close_and_handled; } - eff_buf.token = wsi->u.h2.h2n->rx_scratch; + eff_buf.token = wsi->h2.h2n->rx_scratch; eff_buf.token_len = LWS_H2_RX_SCRATCH_SIZE; } else #endif @@ -1504,7 +1505,7 @@ read: eff_buf.token = (char *)pt->serv_buf; if (lws_is_ws_with_ext(wsi)) { eff_buf.token_len = - wsi->u.ws.rx_ubuf_alloc; + wsi->ws->rx_ubuf_alloc; } else { eff_buf.token_len = context->pt_serv_buf_size; @@ -1630,8 +1631,8 @@ drain: pending = lws_ssl_pending(wsi); if (pending) { if (lws_is_ws_with_ext(wsi)) - pending = pending > wsi->u.ws.rx_ubuf_alloc ? - wsi->u.ws.rx_ubuf_alloc : pending; + pending = pending > wsi->ws->rx_ubuf_alloc ? + wsi->ws->rx_ubuf_alloc : pending; else pending = pending > context->pt_serv_buf_size ? context->pt_serv_buf_size : pending;