diff --git a/lib/roles/h2/http2.c b/lib/roles/h2/http2.c index 6beef3e0b..403d013d6 100644 --- a/lib/roles/h2/http2.c +++ b/lib/roles/h2/http2.c @@ -1087,8 +1087,9 @@ lws_h2_parse_frame_header(struct lws *wsi) } break; case LWS_H2_FRAME_TYPE_CONTINUATION: - lwsl_info("LWS_H2_FRAME_TYPE_CONTINUATION: sid = %u\n", - (unsigned int)h2n->sid); + lwsl_info("LWS_H2_FRAME_TYPE_CONTINUATION: sid = %u %d %d\n", + (unsigned int)h2n->sid, (int)h2n->cont_exp, + (int)h2n->cont_exp_sid); if (!h2n->cont_exp || h2n->cont_exp_sid != h2n->sid || @@ -1098,6 +1099,7 @@ lws_h2_parse_frame_header(struct lws *wsi) "unexpected CONTINUATION"); break; } + if (h2n->swsi->h2.END_HEADERS) { lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR, "END_HEADERS already seen"); @@ -1435,6 +1437,8 @@ lws_h2_parse_end_of_frame(struct lws *wsi) if (!h2n->swsi->h2.END_HEADERS) { /* we are not finished yet */ lwsl_info("witholding http action for continuation\n"); + h2n->cont_exp_sid = h2n->sid; + h2n->cont_exp = 1; break; } diff --git a/lib/roles/http/client/client-handshake.c b/lib/roles/http/client/client-handshake.c index 705942172..056b3010b 100644 --- a/lib/roles/http/client/client-handshake.c +++ b/lib/roles/http/client/client-handshake.c @@ -956,7 +956,7 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, * we are going to detach and reattch */ - size += strlen(address) + 1 + strlen(host) + 1; + size += strlen(path) + 1 + strlen(address) + 1 + strlen(host) + 1 + 1; p = stash = lws_malloc(size, __func__); if (!stash) @@ -975,6 +975,9 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, p += strlen(address) + 1; memcpy(p, host, strlen(host) + 1); host = p; + p += strlen(host) + 1; + memcpy(p, path, strlen(path) + 1); + path = p; if (!port) { port = 443; @@ -1017,12 +1020,15 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, wsi->role_ops->protocol_unbind_cb[ !!lwsi_role_server(wsi)], wsi->user_space, (void *)__func__, 0); + wsi->protocol_bind_balance = 0; } wsi->desc.sockfd = LWS_SOCK_INVALID; lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, &role_ops_h1); // wsi->protocol = NULL; + if (wsi->protocol) + lws_bind_protocol(wsi, wsi->protocol, "client_reset"); wsi->pending_timeout = NO_PENDING_TIMEOUT; wsi->c_port = port; wsi->hdr_parsing_completed = 0; @@ -1047,7 +1053,7 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, } stash[0] = '/'; - lws_strncpy(&stash[1], path, size - 1); + memmove(&stash[1], path, size - 1 < strlen(path) + 1 ? size - 1 : strlen(path) + 1); if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash)) goto bail; diff --git a/lib/roles/http/client/client-http.c b/lib/roles/http/client/client-http.c index 8d452dbf0..b08d1dc44 100644 --- a/lib/roles/http/client/client-http.c +++ b/lib/roles/http/client/client-http.c @@ -1387,18 +1387,21 @@ spin_chunks: if ( #if defined(LWS_WITH_HTTP_PROXY) !wsi_eff->protocol_bind_balance == - !!wsi_eff->http.proxy_clientside && + !!wsi_eff->http.proxy_clientside #else - !!wsi_eff->protocol_bind_balance && + !!wsi_eff->protocol_bind_balance #endif - user_callback_handle_rxflow(wsi_eff->protocol->callback, + ) { + if (user_callback_handle_rxflow(wsi_eff->protocol->callback, wsi_eff, LWS_CALLBACK_RECEIVE_CLIENT_HTTP_READ, wsi_eff->user_space, *buf, n)) { - lwsl_info("%s: RECEIVE_CLIENT_HTTP_READ returned -1\n", - __func__); + lwsl_info("%s: RECEIVE_CLIENT_HTTP_READ returned -1\n", + __func__); - return -1; - } + return -1; + } + } else + lwsl_notice("%s: swallowed read (%d)\n", __func__, n); } (*buf) += n;