diff --git a/lib/client-handshake.c b/lib/client-handshake.c index a407d9c1bfb839115136240e66d24fab476968bc..306c3928295e59e4bcb357503be6a29dcebf48d3 100644 --- a/lib/client-handshake.c +++ b/lib/client-handshake.c @@ -63,7 +63,7 @@ lws_client_connect_2(struct lws *wsi) /* * prepare the actual connection (to the proxy, if any) */ - lwsl_client("%s: address %s\n", __func__, ads); + lwsl_notice("%s: address %s\n", __func__, ads); #ifdef LWS_USE_IPV6 if (LWS_IPV6_ENABLED(wsi->vhost)) { @@ -374,6 +374,7 @@ failed1: LWS_VISIBLE struct lws * lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const char *path, const char *host) { + char origin[300] = "", protocol[300] = "", method[32] = "", *p; if (wsi->u.hdr.redirects == 3) { lwsl_err("%s: Too many redirects\n", __func__); return NULL; @@ -389,24 +390,54 @@ lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const } #endif - lwsl_notice("redirect ads='%s', port=%d, path='%s'\n", address, port, path); + p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN); + if (p) + strncpy(origin, p, sizeof(origin) - 1); - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address)) - return NULL; + p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS); + if (p) + strncpy(protocol, p, sizeof(protocol) - 1); - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path)) - return NULL; + p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD); + if (p) + strncpy(method, p, sizeof(method) - 1); - if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host)) - return NULL; + lwsl_notice("redirect ads='%s', port=%d, path='%s', ssl = %d\n", address, port, path, ssl); + + /* close the connection by hand */ compatible_close(wsi->sock); remove_wsi_socket_from_fds(wsi); + wsi->sock = LWS_SOCK_INVALID; wsi->state = LWSS_CLIENT_UNCONNECTED; wsi->protocol = NULL; wsi->pending_timeout = NO_PENDING_TIMEOUT; wsi->u.hdr.c_port = port; + wsi->hdr_parsing_completed = 0; + _lws_header_table_reset(wsi->u.hdr.ah); + + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address)) + return NULL; + + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, path)) + return NULL; + + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host)) + return NULL; + + if (origin[0]) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_ORIGIN, + origin)) + return NULL; + if (protocol[0]) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS, + protocol)) + return NULL; + if (method[0]) + if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_METHOD, + method)) + return NULL; return lws_client_connect_2(wsi); } diff --git a/lib/client.c b/lib/client.c index c819fe75c0fda65a807b225be7f69416537e3c64..4ffb1fac2b8e6a72c666f9d0eb7186b21bfd4738 100755 --- a/lib/client.c +++ b/lib/client.c @@ -480,10 +480,12 @@ lws_client_interpret_server_handshake(struct lws *wsi) goto bail3; } - if (!strcmp(prot, "wss://") || !strcmp(prot, "https://")) + if (!strcmp(prot, "wss") || !strcmp(prot, "https")) ssl = 1; - if (lws_client_reset(wsi, ssl, ads, port, path, ads)) { + lwsl_notice("ssl %d %s\n", ssl, prot); + + if (!lws_client_reset(wsi, ssl, ads, port, path, ads)) { lwsl_err("Redirect failed\n"); cce = "HS: Redirect failed"; goto bail3; diff --git a/lib/parsers.c b/lib/parsers.c index 72e35dd930e7aa22ef14f7f9d1bd6960e16f7ae3..14cbbd98acac66ae21e997437783ddc3351eec25 100644 --- a/lib/parsers.c +++ b/lib/parsers.c @@ -60,6 +60,16 @@ lextable_decode(int pos, char c) } } +void +_lws_header_table_reset(struct allocated_headers *ah) +{ + /* init the ah to reflect no headers or data have appeared yet */ + memset(ah->frag_index, 0, sizeof(ah->frag_index)); + ah->nfrag = 0; + ah->pos = 0; + ah->http_response = 0; +} + // doesn't scrub the ah rxbuffer by default, parent must do if needed void @@ -74,11 +84,7 @@ lws_header_table_reset(struct lws *wsi, int autoservice) /* ah also concurs with ownership */ assert(ah->wsi == wsi); - /* init the ah to reflect no headers or data have appeared yet */ - memset(ah->frag_index, 0, sizeof(ah->frag_index)); - ah->nfrag = 0; - ah->pos = 0; - ah->http_response = 0; + _lws_header_table_reset(ah); /* since we will restart the ah, our new headers are not completed */ // wsi->hdr_parsing_completed = 0; diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index ec33639a13b5e2e2502d8e513594c2dbed01703a..0041557893ee2c555a4b33c6fd8bf22b206c0bb8 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -1718,6 +1718,8 @@ lws_header_table_detach(struct lws *wsi, int autoservice); LWS_EXTERN void lws_header_table_reset(struct lws *wsi, int autoservice); +void +_lws_header_table_reset(struct allocated_headers *ah); LWS_EXTERN char * LWS_WARN_UNUSED_RESULT lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h); diff --git a/test-server/test-client.c b/test-server/test-client.c index cfea0f8e08e5553f86c2a7cc14e9114ddd74e180..b90a388e88a001ef90fa46aa581b34f26c56f93e 100644 --- a/test-server/test-client.c +++ b/test-server/test-client.c @@ -558,9 +558,11 @@ int main(int argc, char **argv) info.ws_ping_pong_interval = pp_secs; info.extensions = exts; - if (use_ssl) { - info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; +#if defined(LWS_OPENSSL_SUPPORT) + info.options |= LWS_SERVER_OPTION_DO_SSL_GLOBAL_INIT; +#endif + if (use_ssl) { /* * If the server wants us to present a valid SSL client certificate * then we can set it up here.