client: fix redirects and allow ssl / non-ssl redirects

This commit is contained in:
Andy Green 2017-02-09 15:25:01 +08:00
parent 5e25dc07c8
commit 31c5130802
5 changed files with 61 additions and 18 deletions

View file

@ -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,7 +390,32 @@ 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);
p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
if (p)
strncpy(protocol, p, sizeof(protocol) - 1);
p = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
if (p)
strncpy(method, p, sizeof(method) - 1);
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;
@ -400,13 +426,18 @@ lws_client_reset(struct lws *wsi, int ssl, const char *address, int port, const
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
return NULL;
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;
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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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.