mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
http: redo redirects to follow close flow
Until now although we can follow redirects, and they can promote the protocol from h1->h2, we couldn't handle h2 wsi reuse since there are many states in the wsi affected by being h2. This wipes the related states in lws_wsi_reset() and follows the generic wsi close flow before deviating into the redirect really close to the end, ensuring we cleaned out evidence of our previous life properly. h2->h2 redirects work properly after this. The max number of redirects is increased from 3 -> 4 since this was seen in the wild with www and then geographic-based redirects.
This commit is contained in:
parent
2f9bb7a30a
commit
272dba8307
16 changed files with 466 additions and 339 deletions
|
@ -60,7 +60,7 @@ lws_http_client_connect_via_info2(struct lws *wsi)
|
|||
for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames); n++)
|
||||
if (hnames[n] && stash->cis[n] &&
|
||||
lws_hdr_simple_create(wsi, hnames[n], stash->cis[n]))
|
||||
goto bail1;
|
||||
goto bail;
|
||||
|
||||
#if defined(LWS_WITH_SOCKS5)
|
||||
if (!wsi->a.vhost->socks_proxy_port)
|
||||
|
@ -70,15 +70,58 @@ lws_http_client_connect_via_info2(struct lws *wsi)
|
|||
no_ah:
|
||||
return lws_client_connect_2_dnsreq(wsi);
|
||||
|
||||
bail1:
|
||||
bail:
|
||||
#if defined(LWS_WITH_SOCKS5)
|
||||
if (!wsi->a.vhost->socks_proxy_port)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
#endif
|
||||
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
lws_client_stash_create(struct lws *wsi, const char **cisin)
|
||||
{
|
||||
size_t size;
|
||||
char *pc;
|
||||
int n;
|
||||
|
||||
size = sizeof(*wsi->stash);
|
||||
|
||||
/*
|
||||
* Let's overallocate the stash object with space for all the args
|
||||
* in one hit.
|
||||
*/
|
||||
for (n = 0; n < CIS_COUNT; n++)
|
||||
if (cisin[n])
|
||||
size += strlen(cisin[n]) + 1;
|
||||
|
||||
if (wsi->stash)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
|
||||
wsi->stash = lws_malloc(size, "client stash");
|
||||
if (!wsi->stash)
|
||||
return 1;
|
||||
|
||||
/* all the pointers default to NULL, but no need to zero the args */
|
||||
memset(wsi->stash, 0, sizeof(*wsi->stash));
|
||||
|
||||
pc = (char *)&wsi->stash[1];
|
||||
|
||||
for (n = 0; n < CIS_COUNT; n++)
|
||||
if (cisin[n]) {
|
||||
size_t mm;
|
||||
wsi->stash->cis[n] = pc;
|
||||
mm = strlen(cisin[n]) + 1;
|
||||
memcpy(pc, cisin[n], mm);
|
||||
pc += mm;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct lws *
|
||||
lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
||||
{
|
||||
|
@ -86,10 +129,8 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
struct lws *wsi, *safe = NULL;
|
||||
const struct lws_protocols *p;
|
||||
const char *cisin[CIS_COUNT];
|
||||
struct lws_vhost *vh, *v;
|
||||
size_t size;
|
||||
int n, tsi;
|
||||
char *pc;
|
||||
struct lws_vhost *vh;
|
||||
int tsi;
|
||||
|
||||
if (i->context->requested_stop_internal_loops)
|
||||
return NULL;
|
||||
|
@ -118,11 +159,10 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
wsi = __lws_wsi_create_with_role(i->context, tsi, NULL);
|
||||
lws_context_unlock(i->context);
|
||||
if (wsi == NULL)
|
||||
goto bail;
|
||||
return NULL;
|
||||
|
||||
vh = i->vhost;
|
||||
if (!vh) {
|
||||
|
||||
#if defined(LWS_WITH_TLS_JIT_TRUST)
|
||||
if (lws_tls_jit_trust_vhost_bind(i->context, i->address, &vh))
|
||||
#endif
|
||||
|
@ -199,23 +239,11 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
if (i->ssl_connection & LCCSCF_WAKE_SUSPEND__VALIDITY)
|
||||
wsi->conn_validity_wakesuspend = 1;
|
||||
|
||||
if (!i->vhost) {
|
||||
v = i->context->vhost_list;
|
||||
|
||||
if (!v) { /* coverity */
|
||||
lwsl_err("%s: no vhost\n", __func__);
|
||||
goto bail;
|
||||
}
|
||||
if (!strcmp(v->name, "system"))
|
||||
v = v->vhost_next;
|
||||
} else
|
||||
v = i->vhost;
|
||||
|
||||
lws_vhost_bind_wsi(v, wsi);
|
||||
lws_vhost_bind_wsi(vh, wsi);
|
||||
|
||||
#if defined(LWS_WITH_SYS_FAULT_INJECTION)
|
||||
/* additionally inerit from vhost we bound to */
|
||||
lws_fi_inherit_copy(&wsi->fic, &v->fic, "wsi", i->fi_wsi_name);
|
||||
lws_fi_inherit_copy(&wsi->fic, &vh->fic, "wsi", i->fi_wsi_name);
|
||||
#endif
|
||||
|
||||
if (!wsi->a.vhost) {
|
||||
|
@ -324,23 +352,13 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
cisin[CIS_IFACE] = i->iface;
|
||||
cisin[CIS_ALPN] = i->alpn;
|
||||
|
||||
size = sizeof(*wsi->stash);
|
||||
if (lws_client_stash_create(wsi, cisin))
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
* Let's overallocate the stash object with space for all the args
|
||||
* in one hit.
|
||||
*/
|
||||
for (n = 0; n < CIS_COUNT; n++)
|
||||
if (cisin[n])
|
||||
size += strlen(cisin[n]) + 1;
|
||||
|
||||
wsi->stash = lws_malloc(size, "client stash");
|
||||
if (!wsi->stash) {
|
||||
lwsl_err("%s: OOM\n", __func__);
|
||||
goto bail1;
|
||||
}
|
||||
/* all the pointers default to NULL, but no need to zero the args */
|
||||
memset(wsi->stash, 0, sizeof(*wsi->stash));
|
||||
#if defined(LWS_WITH_TLS)
|
||||
if (i->alpn)
|
||||
lws_strncpy(wsi->alpn, i->alpn, sizeof(wsi->alpn));
|
||||
#endif
|
||||
|
||||
wsi->a.opaque_user_data = wsi->stash->opaque_user_data =
|
||||
i->opaque_user_data;
|
||||
|
@ -382,17 +400,6 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
|
||||
lws_metrics_tag_wsi_add(wsi, "vh", wsi->a.vhost->name);
|
||||
|
||||
pc = (char *)&wsi->stash[1];
|
||||
|
||||
for (n = 0; n < CIS_COUNT; n++)
|
||||
if (cisin[n]) {
|
||||
size_t mm;
|
||||
wsi->stash->cis[n] = pc;
|
||||
mm = strlen(cisin[n]) + 1;
|
||||
memcpy(pc, cisin[n], mm);
|
||||
pc += mm;
|
||||
}
|
||||
|
||||
/*
|
||||
* at this point user callbacks like
|
||||
* LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER will be interested to
|
||||
|
@ -519,10 +526,8 @@ bail3:
|
|||
return NULL;
|
||||
#endif
|
||||
|
||||
bail1:
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
|
||||
bail:
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
lws_fi_destroy(&wsi->fic);
|
||||
lws_free(wsi);
|
||||
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
|
||||
|
|
|
@ -144,6 +144,26 @@ lws_client_connect_2_dnsreq(struct lws *wsi)
|
|||
return wsi;
|
||||
}
|
||||
|
||||
/*
|
||||
* clients who will create their own fresh connection keep a copy of
|
||||
* the hostname they originally connected to, in case other connections
|
||||
* want to use it too
|
||||
*/
|
||||
|
||||
if (!wsi->cli_hostname_copy) {
|
||||
if (wsi->stash && wsi->stash->cis[CIS_HOST])
|
||||
wsi->cli_hostname_copy =
|
||||
lws_strdup(wsi->stash->cis[CIS_HOST]);
|
||||
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
|
||||
else {
|
||||
char *pa = lws_hdr_simple_ptr(wsi,
|
||||
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
|
||||
if (pa)
|
||||
wsi->cli_hostname_copy = lws_strdup(pa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The first job is figure out if we want to pipeline on or just join
|
||||
* an existing "active connection" to the same place
|
||||
|
@ -213,26 +233,6 @@ lws_client_connect_2_dnsreq(struct lws *wsi)
|
|||
|
||||
solo:
|
||||
|
||||
/*
|
||||
* clients who will create their own fresh connection keep a copy of
|
||||
* the hostname they originally connected to, in case other connections
|
||||
* want to use it too
|
||||
*/
|
||||
|
||||
if (!wsi->cli_hostname_copy) {
|
||||
if (wsi->stash && wsi->stash->cis[CIS_HOST])
|
||||
wsi->cli_hostname_copy =
|
||||
lws_strdup(wsi->stash->cis[CIS_HOST]);
|
||||
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
|
||||
else {
|
||||
char *pa = lws_hdr_simple_ptr(wsi,
|
||||
_WSI_TOKEN_CLIENT_PEER_ADDRESS);
|
||||
if (pa)
|
||||
wsi->cli_hostname_copy = lws_strdup(pa);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* If we made our own connection, and we're doing a method that can
|
||||
* take a pipeline, we are an "active client connection".
|
||||
|
|
|
@ -475,7 +475,7 @@ ads_known:
|
|||
errno_copy = 999;
|
||||
#endif
|
||||
|
||||
lwsl_debug("%s: connect: errno: %d\n", __func__, errno_copy);
|
||||
lwsl_debug("%s: connect: fd %d errno: %d\n", __func__, wsi->desc.sockfd, errno_copy);
|
||||
|
||||
if (errno_copy &&
|
||||
errno_copy != LWS_EALREADY &&
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
|
@ -95,7 +95,8 @@ lws_client_connect_4_established(struct lws *wsi, struct lws *wsi_piggyback,
|
|||
goto failed;
|
||||
wsi->c_port = (uint16_t)wsi->a.vhost->http.http_proxy_port;
|
||||
|
||||
n = (int)send(wsi->desc.sockfd, (char *)pt->serv_buf, (unsigned int)plen,
|
||||
n = (int)send(wsi->desc.sockfd, (char *)pt->serv_buf,
|
||||
(unsigned int)plen,
|
||||
MSG_NOSIGNAL);
|
||||
if (n < 0) {
|
||||
lwsl_debug("ERROR writing to proxy socket\n");
|
||||
|
@ -161,14 +162,18 @@ send_hs:
|
|||
__func__, wsi->lc.gutag, lwsi_state(wsi_piggyback));
|
||||
} else {
|
||||
lwsl_info("%s: %s: %s %s client created own conn "
|
||||
"(raw %d) vh %sm st 0x%x\n",
|
||||
__func__, wsi->lc.gutag, wsi->role_ops->name,
|
||||
wsi->a.protocol->name, rawish, wsi->a.vhost->name,
|
||||
lwsi_state(wsi));
|
||||
"(raw %d) vh %sm st 0x%x\n", __func__, wsi->lc.gutag,
|
||||
wsi->role_ops->name, wsi->a.protocol->name, rawish,
|
||||
wsi->a.vhost->name, lwsi_state(wsi));
|
||||
|
||||
/* we are making our own connection */
|
||||
|
||||
if (!rawish) {
|
||||
if (!rawish
|
||||
#if defined(LWS_WITH_TLS)
|
||||
// && (!(wsi->tls.use_ssl & LCCSCF_USE_SSL) || wsi->tls.ssl)
|
||||
#endif
|
||||
) {
|
||||
|
||||
if (lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2)
|
||||
lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE);
|
||||
} else {
|
||||
|
@ -183,20 +188,24 @@ send_hs:
|
|||
(wsi->tls.use_ssl & LCCSCF_USE_SSL)) {
|
||||
int result;
|
||||
|
||||
//lwsi_set_state(wsi, LRS_WAITING_SSL);
|
||||
|
||||
/*
|
||||
* We can retry this... just cook the SSL BIO
|
||||
* the first time
|
||||
*/
|
||||
|
||||
result = lws_client_create_tls(wsi, &cce, 1);
|
||||
lwsl_debug("%s: create_tls said %d\n",
|
||||
__func__, result);
|
||||
switch (result) {
|
||||
case CCTLS_RETURN_DONE:
|
||||
break;
|
||||
case CCTLS_RETURN_RETRY:
|
||||
lwsl_debug("%s: create_tls RETRY\n",
|
||||
__func__);
|
||||
return wsi;
|
||||
default:
|
||||
lwsl_debug("%s: create_tls FAIL\n",
|
||||
__func__);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -207,9 +216,10 @@ send_hs:
|
|||
* LRS_H2_WAITING_TO_SEND_HEADERS already.
|
||||
*/
|
||||
|
||||
lwsl_notice("%s: %s: "
|
||||
"tls established st 0x%x\n",
|
||||
__func__, wsi->lc.gutag, lwsi_state(wsi));
|
||||
lwsl_notice("%s: %s: tls established st 0x%x, "
|
||||
"client_h2_alpn %d\n", __func__,
|
||||
wsi->lc.gutag, lwsi_state(wsi),
|
||||
wsi->client_h2_alpn);
|
||||
|
||||
if (lwsi_state(wsi) !=
|
||||
LRS_H2_WAITING_TO_SEND_HEADERS)
|
||||
|
@ -217,7 +227,13 @@ send_hs:
|
|||
LRS_H1C_ISSUE_HANDSHAKE2);
|
||||
lws_set_timeout(wsi,
|
||||
PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
|
||||
(int)wsi->a.context->timeout_secs);
|
||||
(int)wsi->a.context->timeout_secs);
|
||||
#if 0
|
||||
/* ensure pollin enabled */
|
||||
if (lws_change_pollfd(wsi, 0, LWS_POLLIN))
|
||||
lwsl_notice("%s: unable to set POLLIN\n",
|
||||
__func__);
|
||||
#endif
|
||||
|
||||
goto provoke_service;
|
||||
}
|
||||
|
@ -230,7 +246,8 @@ send_hs:
|
|||
if (m) {
|
||||
n = user_callback_handle_rxflow(
|
||||
wsi->a.protocol->callback, wsi,
|
||||
(enum lws_callback_reasons)m, wsi->user_space, NULL, 0);
|
||||
(enum lws_callback_reasons)m,
|
||||
wsi->user_space, NULL, 0);
|
||||
if (n < 0) {
|
||||
lwsl_info("RAW_PROXY_CLI_ADOPT err\n");
|
||||
goto failed;
|
||||
|
@ -240,7 +257,7 @@ send_hs:
|
|||
/* service.c pollout processing wants this */
|
||||
wsi->hdr_parsing_completed = 1;
|
||||
#if defined(LWS_ROLE_MQTT)
|
||||
if (!strcmp(meth, "MQTT")) {
|
||||
if (meth && !strcmp(meth, "MQTT")) {
|
||||
#if defined(LWS_WITH_TLS)
|
||||
if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
|
||||
lwsi_set_state(wsi, LRS_WAITING_SSL);
|
||||
|
@ -320,7 +337,7 @@ provoke_service:
|
|||
failed:
|
||||
lws_inform_client_conn_fail(wsi, (void *)cce, strlen(cce));
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect2");
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "client_connect4");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,8 @@ __lws_reset_wsi(struct lws *wsi)
|
|||
#if defined(LWS_WITH_CLIENT)
|
||||
lws_dll2_remove(&wsi->dll2_cli_txn_queue);
|
||||
lws_dll2_remove(&wsi->dll_cli_active_conns);
|
||||
if (wsi->cli_hostname_copy)
|
||||
lws_free_set_NULL(wsi->cli_hostname_copy);
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_SYS_ASYNC_DNS)
|
||||
|
@ -143,7 +145,7 @@ __lws_reset_wsi(struct lws *wsi)
|
|||
|
||||
__lws_same_vh_protocol_remove(wsi);
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
//lws_free_set_NULL(wsi->stash);
|
||||
lws_free_set_NULL(wsi->cli_hostname_copy);
|
||||
#endif
|
||||
|
||||
|
@ -166,6 +168,34 @@ __lws_reset_wsi(struct lws *wsi)
|
|||
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
|
||||
__lws_header_table_detach(wsi, 0);
|
||||
#endif
|
||||
|
||||
#if defined(LWS_ROLE_H2)
|
||||
/*
|
||||
* Let's try to clean out the h2-ness of the wsi
|
||||
*/
|
||||
|
||||
memset(&wsi->h2, 0, sizeof(wsi->h2));
|
||||
|
||||
wsi->hdr_parsing_completed = wsi->mux_substream =
|
||||
wsi->upgraded_to_http2 = wsi->mux_stream_immortal =
|
||||
wsi->h2_acked_settings = wsi->seen_nonpseudoheader =
|
||||
wsi->socket_is_permanently_unusable = wsi->favoured_pollin =
|
||||
wsi->already_did_cce = wsi->told_user_closed =
|
||||
wsi->waiting_to_send_close_frame = wsi->close_needs_ack =
|
||||
wsi->parent_pending_cb_on_writable = wsi->seen_zero_length_recv =
|
||||
wsi->close_when_buffered_out_drained = wsi->could_have_pending = 0;
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
wsi->do_ws = wsi->chunked = wsi->client_rx_avail =
|
||||
wsi->client_http_body_pending = wsi->transaction_from_pipeline_queue =
|
||||
wsi->keepalive_active = wsi->keepalive_rejected =
|
||||
wsi->redirected_to_get = wsi->client_pipeline = wsi->client_h2_alpn =
|
||||
wsi->client_mux_substream = wsi->client_mux_migrated =
|
||||
wsi->tls_session_reused = wsi->perf_done = 0;
|
||||
|
||||
wsi->immortal_substream_count = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* req cx lock */
|
||||
|
@ -194,17 +224,23 @@ __lws_free_wsi(struct lws *wsi)
|
|||
}
|
||||
#endif
|
||||
|
||||
vh = wsi->a.vhost;
|
||||
|
||||
__lws_reset_wsi(wsi);
|
||||
__lws_wsi_remove_from_sul(wsi);
|
||||
|
||||
vh = wsi->a.vhost;
|
||||
if (vh)
|
||||
/* this may destroy vh */
|
||||
__lws_vhost_unbind_wsi(wsi); /* req cx + vh lock */
|
||||
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
if (wsi->stash)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
#endif
|
||||
|
||||
if (wsi->a.context->event_loop_ops->destroy_wsi)
|
||||
wsi->a.context->event_loop_ops->destroy_wsi(wsi);
|
||||
|
||||
if (vh)
|
||||
__lws_vhost_unbind_wsi(wsi); /* req cx + vh lock */
|
||||
|
||||
lwsl_debug("%s: %s, tsi fds count %d\n", __func__,
|
||||
lws_wsi_tag(wsi),
|
||||
wsi->a.context->pt[(int)wsi->tsi].fds_count);
|
||||
|
@ -339,6 +375,7 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
|
|||
#if defined(LWS_WITH_CLIENT)
|
||||
|
||||
lws_free_set_NULL(wsi->cli_hostname_copy);
|
||||
wsi->client_mux_substream_was = wsi->client_mux_substream;
|
||||
|
||||
lws_addrinfo_clean(wsi);
|
||||
#endif
|
||||
|
@ -407,7 +444,8 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
|
|||
#endif
|
||||
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
if (!wsi->close_is_redirect)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
#endif
|
||||
|
||||
if (wsi->role_ops == &role_ops_raw_skt) {
|
||||
|
@ -565,7 +603,8 @@ just_kill_connection:
|
|||
#endif
|
||||
lwsi_state(wsi) == LRS_WAITING_DNS ||
|
||||
lwsi_state(wsi) == LRS_WAITING_CONNECT) &&
|
||||
!wsi->already_did_cce && wsi->a.protocol) {
|
||||
!wsi->already_did_cce && wsi->a.protocol &&
|
||||
!wsi->close_is_redirect) {
|
||||
static const char _reason[] = "closed before established";
|
||||
|
||||
lwsl_debug("%s: closing in unestablished state 0x%x\n",
|
||||
|
@ -624,6 +663,9 @@ just_kill_connection:
|
|||
#if !defined(_WIN32_WCE) && !defined(LWS_PLAT_FREERTOS)
|
||||
/* libuv: no event available to guarantee completion */
|
||||
if (!wsi->socket_is_permanently_unusable &&
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
!wsi->close_is_redirect &&
|
||||
#endif
|
||||
lws_socket_is_valid(wsi->desc.sockfd) &&
|
||||
lwsi_state(wsi) != LRS_SHUTDOWN &&
|
||||
(context->event_loop_ops->flags & LELOF_ISPOLL)) {
|
||||
|
@ -696,7 +738,7 @@ just_kill_connection:
|
|||
/*
|
||||
* He's a guy who go started with dns, but failed or is
|
||||
* caught with a shutdown before he got the result. We have
|
||||
* to issue him a close cb
|
||||
* to issclient_mux_substream_wasue him a close cb
|
||||
*/
|
||||
ccb = 1;
|
||||
|
||||
|
@ -712,12 +754,17 @@ just_kill_connection:
|
|||
ccb = 0;
|
||||
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
if (!ccb && (lwsi_state_PRE_CLOSE(wsi) & LWSIFS_NOT_EST) &&
|
||||
if (!wsi->close_is_redirect && !ccb &&
|
||||
(lwsi_state_PRE_CLOSE(wsi) & LWSIFS_NOT_EST) &&
|
||||
lwsi_role_client(wsi)) {
|
||||
lws_inform_client_conn_fail(wsi, "Closed before conn", 18);
|
||||
}
|
||||
#endif
|
||||
if (ccb) {
|
||||
if (ccb
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
&& !wsi->close_is_redirect
|
||||
#endif
|
||||
) {
|
||||
|
||||
if (!wsi->a.protocol && wsi->a.vhost && wsi->a.vhost->protocols)
|
||||
pro = &wsi->a.vhost->protocols[0];
|
||||
|
@ -831,10 +878,80 @@ __lws_close_free_wsi_final(struct lws *wsi)
|
|||
#endif
|
||||
|
||||
sanity_assert_no_sockfd_traces(wsi->a.context, wsi->desc.sockfd);
|
||||
|
||||
wsi->desc.sockfd = LWS_SOCK_INVALID;
|
||||
}
|
||||
|
||||
wsi->desc.sockfd = LWS_SOCK_INVALID;
|
||||
|
||||
#if defined(LWS_WITH_CLIENT)
|
||||
if (wsi->close_is_redirect) {
|
||||
|
||||
wsi->close_is_redirect = 0;
|
||||
|
||||
lwsl_info("%s: picking up redirection %s\n", __func__,
|
||||
wsi->lc.gutag);
|
||||
|
||||
lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED,
|
||||
&role_ops_h1);
|
||||
|
||||
#if defined(LWS_WITH_HTTP2)
|
||||
if (wsi->client_mux_substream_was)
|
||||
wsi->h2.END_STREAM = wsi->h2.END_HEADERS = 0;
|
||||
#endif
|
||||
#if defined(LWS_ROLE_H2) || defined(LWS_ROLE_MQTT)
|
||||
if (wsi->mux.parent_wsi) {
|
||||
lws_wsi_mux_sibling_disconnect(wsi);
|
||||
wsi->mux.parent_wsi = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
memset(&wsi->tls, 0, sizeof(wsi->tls));
|
||||
#endif
|
||||
|
||||
// wsi->a.protocol = NULL;
|
||||
if (wsi->a.protocol)
|
||||
lws_bind_protocol(wsi, wsi->a.protocol, "client_reset");
|
||||
wsi->pending_timeout = NO_PENDING_TIMEOUT;
|
||||
wsi->hdr_parsing_completed = 0;
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
if (wsi->stash->cis[CIS_ALPN])
|
||||
lws_strncpy(wsi->alpn, wsi->stash->cis[CIS_ALPN],
|
||||
sizeof(wsi->alpn));
|
||||
#endif
|
||||
|
||||
if (lws_header_table_attach(wsi, 0)) {
|
||||
lwsl_err("%s: failed to get ah\n", __func__);
|
||||
return;
|
||||
}
|
||||
// }
|
||||
//_lws_header_table_reset(wsi->http.ah);
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
wsi->tls.use_ssl = wsi->flags & LCCSCF_USE_SSL;
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_TLS_JIT_TRUST)
|
||||
if (wsi->stash && wsi->stash->cis[CIS_ADDRESS]) {
|
||||
struct lws_vhost *vh = NULL;
|
||||
lws_tls_jit_trust_vhost_bind(wsi->a.context,
|
||||
wsi->stash->cis[CIS_ADDRESS],
|
||||
&vh);
|
||||
if (vh) {
|
||||
if (!vh->count_bound_wsi && vh->grace_after_unref) {
|
||||
lwsl_info("%s: %s: in use\n", __func__, vh->lc.gutag);
|
||||
lws_sul_cancel(&vh->sul_unref);
|
||||
}
|
||||
vh->count_bound_wsi++;
|
||||
wsi->a.vhost = vh;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* outermost destroy notification for wsi (user_space still intact) */
|
||||
if (wsi->a.vhost)
|
||||
wsi->a.vhost->protocols[0].callback(wsi, LWS_CALLBACK_WSI_DESTROY,
|
||||
|
|
|
@ -540,7 +540,7 @@ struct lws_vhost {
|
|||
#endif
|
||||
|
||||
#if defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
|
||||
int8_t ss_refcount;
|
||||
int8_t ss_refcount;
|
||||
/**< refcount of number of ss connections with streamtypes using this
|
||||
* trust store */
|
||||
#endif
|
||||
|
@ -742,6 +742,7 @@ struct lws {
|
|||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
struct lws_lws_tls tls;
|
||||
char alpn[24];
|
||||
#endif
|
||||
|
||||
lws_sock_file_fd_type desc; /* .filefd / .sockfd */
|
||||
|
@ -759,6 +760,8 @@ struct lws {
|
|||
#endif
|
||||
unsigned int cache_secs;
|
||||
|
||||
short bugcatcher;
|
||||
|
||||
unsigned int hdr_parsing_completed:1;
|
||||
unsigned int mux_substream:1;
|
||||
unsigned int upgraded_to_http2:1;
|
||||
|
@ -837,6 +840,8 @@ struct lws {
|
|||
* this activity, and will report the failure */
|
||||
unsigned int tls_session_reused:1;
|
||||
unsigned int perf_done:1;
|
||||
unsigned int close_is_redirect:1;
|
||||
unsigned int client_mux_substream_was:1;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -1351,6 +1356,9 @@ __lws_same_vh_protocol_remove(struct lws *wsi);
|
|||
void
|
||||
lws_same_vh_protocol_insert(struct lws *wsi, int n);
|
||||
|
||||
int
|
||||
lws_client_stash_create(struct lws *wsi, const char **cisin);
|
||||
|
||||
void
|
||||
lws_seq_destroy_all_on_pt(struct lws_context_per_thread *pt);
|
||||
|
||||
|
|
|
@ -557,6 +557,7 @@ lws_create_vhost(struct lws_context *context,
|
|||
#endif
|
||||
struct lws_protocols *lwsp;
|
||||
int m, f = !info->pvo, fx = 0, abs_pcol_count = 0, sec_pcol_count = 0;
|
||||
const char *name = "default";
|
||||
char buf[96];
|
||||
char *p;
|
||||
#if defined(LWS_WITH_SYS_ASYNC_DNS)
|
||||
|
@ -564,10 +565,13 @@ lws_create_vhost(struct lws_context *context,
|
|||
#endif
|
||||
int n;
|
||||
|
||||
if (info->vhost_name)
|
||||
name = info->vhost_name;
|
||||
|
||||
if (lws_fi(&info->fic, "vh_create_oom"))
|
||||
vh = NULL;
|
||||
else
|
||||
vh = lws_zalloc(sizeof(*vh)
|
||||
vh = lws_zalloc(sizeof(*vh) + strlen(name) + 1
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
+ context->event_loop_ops->evlib_size_vh
|
||||
#endif
|
||||
|
@ -577,7 +581,12 @@ lws_create_vhost(struct lws_context *context,
|
|||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
vh->evlib_vh = (void *)&vh[1];
|
||||
vh->name = (const char *)vh->evlib_vh +
|
||||
context->event_loop_ops->evlib_size_vh;
|
||||
#else
|
||||
vh->name = (const char *)&vh[1];
|
||||
#endif
|
||||
memcpy((char *)vh->name, name, strlen(name) + 1);
|
||||
|
||||
#if LWS_MAX_SMP > 1
|
||||
lws_mutex_refcount_init(&vh->mr);
|
||||
|
@ -587,10 +596,6 @@ lws_create_vhost(struct lws_context *context,
|
|||
pcols = &protocols_dummy[0];
|
||||
|
||||
vh->context = context;
|
||||
if (!info->vhost_name)
|
||||
vh->name = "default";
|
||||
else
|
||||
vh->name = info->vhost_name;
|
||||
{
|
||||
char *end = buf + sizeof(buf) - 1;
|
||||
p = buf;
|
||||
|
|
|
@ -43,10 +43,12 @@ void lwsi_set_role(struct lws *wsi, lws_wsi_state_t role)
|
|||
|
||||
void lwsi_set_state(struct lws *wsi, lws_wsi_state_t lrs)
|
||||
{
|
||||
wsi->wsistate = (wsi->wsistate & (unsigned int)(~LRS_MASK)) | lrs;
|
||||
lws_wsi_state_t old = wsi->wsistate;
|
||||
|
||||
lwsl_debug("lwsi_set_state(%s, 0x%lx)\n", lws_wsi_tag(wsi),
|
||||
(unsigned long)wsi->wsistate);
|
||||
wsi->wsistate = (old & (unsigned int)(~LRS_MASK)) | lrs;
|
||||
|
||||
lwsl_debug("lwsi_set_state(%s): 0x%lx -> 0x%lx)\n", lws_wsi_tag(wsi),
|
||||
(unsigned long)old, (unsigned long)wsi->wsistate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -56,6 +58,7 @@ lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi)
|
|||
{
|
||||
if (wsi->a.vhost == vh)
|
||||
return;
|
||||
|
||||
lws_context_lock(vh->context, __func__); /* ---------- context { */
|
||||
wsi->a.vhost = vh;
|
||||
|
||||
|
@ -68,6 +71,7 @@ lws_vhost_bind_wsi(struct lws_vhost *vh, struct lws *wsi)
|
|||
|
||||
vh->count_bound_wsi++;
|
||||
lws_context_unlock(vh->context); /* } context ---------- */
|
||||
|
||||
lwsl_debug("%s: vh %s: wsi %s/%s, count_bound_wsi %d\n", __func__,
|
||||
vh->name, wsi->role_ops ? wsi->role_ops->name : "none",
|
||||
wsi->a.protocol ? wsi->a.protocol->name : "none",
|
||||
|
|
|
@ -395,12 +395,17 @@ lws_h2_issue_preface(struct lws *wsi)
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (h2n->sent_preface)
|
||||
return 1;
|
||||
|
||||
lwsl_debug("%s: %s: fd %d\n", __func__, lws_wsi_tag(wsi), (int)wsi->desc.sockfd);
|
||||
|
||||
if (lws_issue_raw(wsi, (uint8_t *)preface, strlen(preface)) !=
|
||||
(int)strlen(preface))
|
||||
return 1;
|
||||
|
||||
h2n->sent_preface = 1;
|
||||
|
||||
lws_role_transition(wsi, LWSIFR_CLIENT, LRS_H2_WAITING_TO_SEND_HEADERS,
|
||||
&role_ops_h2);
|
||||
|
||||
|
@ -1534,6 +1539,11 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
|
|||
h2n->swsi->txc.manual_initial_tx_credit =
|
||||
wsi->txc.manual_initial_tx_credit;
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
lws_strncpy(h2n->swsi->alpn, wsi->alpn,
|
||||
sizeof(wsi->alpn));
|
||||
#endif
|
||||
|
||||
wsi->user_space = NULL;
|
||||
|
||||
if (h2n->swsi->http.ah)
|
||||
|
@ -1631,8 +1641,17 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
|
|||
#if defined(LWS_WITH_CLIENT)
|
||||
if (h2n->swsi->client_mux_substream &&
|
||||
lws_client_interpret_server_handshake(h2n->swsi)) {
|
||||
lwsl_info("%s: cli int serv hs closed it\n", __func__);
|
||||
break;
|
||||
/*
|
||||
* This is more complicated than it looks, one exit from
|
||||
* interpret_server_handshake() is to do a close that
|
||||
* turns into a redirect.
|
||||
*
|
||||
* In that case, the wsi survives having being reset
|
||||
* and detached from any h2 identity. We need to get
|
||||
* our parents out from touching it any more
|
||||
*/
|
||||
lwsl_info("%s: cli int serv hs closed, or redir\n", __func__);
|
||||
return 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2032,7 +2051,7 @@ lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t _inlen,
|
|||
h2n->count++;
|
||||
|
||||
if (h2n->type == LWS_H2_FRAME_TYPE_COUNT) { /* IGNORING FRAME */
|
||||
lwsl_debug("%s: consuming for ignored %u %u\n", __func__, (unsigned int)h2n->count, (unsigned int)h2n->length);
|
||||
//lwsl_debug("%s: consuming for ignored %u %u\n", __func__, (unsigned int)h2n->count, (unsigned int)h2n->length);
|
||||
goto frame_end;
|
||||
}
|
||||
|
||||
|
@ -2372,7 +2391,7 @@ do_windows:
|
|||
break;
|
||||
|
||||
case LWS_H2_FRAME_TYPE_COUNT: /* IGNORING FRAME */
|
||||
lwsl_debug("%s: consuming for ignored %u %u\n", __func__, (unsigned int)h2n->count, (unsigned int)h2n->length);
|
||||
//lwsl_debug("%s: consuming for ignored %u %u\n", __func__, (unsigned int)h2n->count, (unsigned int)h2n->length);
|
||||
h2n->count++;
|
||||
break;
|
||||
|
||||
|
@ -2396,7 +2415,13 @@ frame_end:
|
|||
/*
|
||||
* end of frame just happened
|
||||
*/
|
||||
if (lws_h2_parse_end_of_frame(wsi))
|
||||
n = lws_h2_parse_end_of_frame(wsi);
|
||||
if (n == 2) {
|
||||
*inused = (lws_filepos_t)lws_ptr_diff_size_t(in, oldin);
|
||||
|
||||
return 2;
|
||||
}
|
||||
if (n)
|
||||
goto fail;
|
||||
|
||||
break;
|
||||
|
@ -2442,7 +2467,7 @@ try_frame_start:
|
|||
|
||||
default:
|
||||
if (h2n->type == LWS_H2_FRAME_TYPE_COUNT) { /* IGNORING FRAME */
|
||||
lwsl_debug("%s: consuming for ignored %u %u\n", __func__, (unsigned int)h2n->count, (unsigned int)h2n->length);
|
||||
//lwsl_debug("%s: consuming for ignored %u %u\n", __func__, (unsigned int)h2n->count, (unsigned int)h2n->length);
|
||||
h2n->count++;
|
||||
}
|
||||
break;
|
||||
|
@ -2480,6 +2505,7 @@ lws_h2_client_handshake(struct lws *wsi)
|
|||
char *meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD),
|
||||
*uri = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI), *simp;
|
||||
struct lws *nwsi = lws_get_network_wsi(wsi);
|
||||
const char *path = "/";
|
||||
int n, m;
|
||||
/*
|
||||
* The identifier of a newly established stream MUST be numerically
|
||||
|
@ -2517,6 +2543,8 @@ lws_h2_client_handshake(struct lws *wsi)
|
|||
if (!meth)
|
||||
meth = "GET";
|
||||
|
||||
/* h2 pseudoheaders must be in a bunch at the start */
|
||||
|
||||
if (lws_add_http_header_by_token(wsi,
|
||||
WSI_TOKEN_HTTP_COLON_METHOD,
|
||||
(unsigned char *)meth,
|
||||
|
@ -2529,31 +2557,49 @@ lws_h2_client_handshake(struct lws *wsi)
|
|||
&p, end))
|
||||
goto fail_length;
|
||||
|
||||
|
||||
n = lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_URI);
|
||||
if (n)
|
||||
path = uri;
|
||||
else
|
||||
if (wsi->stash && wsi->stash->cis[CIS_PATH]) {
|
||||
path = wsi->stash->cis[CIS_PATH];
|
||||
n = (int)strlen(path);
|
||||
} else
|
||||
n = 1;
|
||||
|
||||
if (n > 1 && path[0] == '/' && path[1] == '/') {
|
||||
path++;
|
||||
n--;
|
||||
}
|
||||
|
||||
if (n && lws_add_http_header_by_token(wsi,
|
||||
WSI_TOKEN_HTTP_COLON_PATH,
|
||||
(unsigned char *)uri, n, &p, end))
|
||||
goto fail_length;
|
||||
|
||||
n = lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
|
||||
simp = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
|
||||
if (n && simp && lws_add_http_header_by_token(wsi,
|
||||
WSI_TOKEN_HTTP_COLON_AUTHORITY,
|
||||
(unsigned char *)simp, n, &p, end))
|
||||
(unsigned char *)path, n, &p, end))
|
||||
goto fail_length;
|
||||
|
||||
n = lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_HOST);
|
||||
simp = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_HOST);
|
||||
if (!n && wsi->stash && wsi->stash->cis[CIS_ADDRESS]) {
|
||||
n = (int)strlen(wsi->stash->cis[CIS_ADDRESS]);
|
||||
simp = wsi->stash->cis[CIS_ADDRESS];
|
||||
}
|
||||
|
||||
if (!wsi->client_h2_alpn && n && simp &&
|
||||
// n = lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
|
||||
// simp = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_ORIGIN);
|
||||
#if 0
|
||||
if (n && simp && lws_add_http_header_by_token(wsi,
|
||||
WSI_TOKEN_HTTP_COLON_AUTHORITY,
|
||||
(unsigned char *)simp, n, &p, end))
|
||||
goto fail_length;
|
||||
#endif
|
||||
|
||||
|
||||
if (/*!wsi->client_h2_alpn && */n && simp &&
|
||||
lws_add_http_header_by_token(wsi, WSI_TOKEN_HOST,
|
||||
(unsigned char *)simp, n, &p, end))
|
||||
goto fail_length;
|
||||
|
||||
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_HTTP_USER_AGENT,
|
||||
(unsigned char *)"lwsss", 5,
|
||||
&p, end))
|
||||
goto fail_length;
|
||||
|
||||
if (wsi->flags & LCCSCF_HTTP_MULTIPART_MIME) {
|
||||
p1 = lws_http_multipart_headers(wsi, p);
|
||||
|
|
|
@ -113,8 +113,20 @@ rops_handle_POLLIN_h2(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
}
|
||||
#endif
|
||||
|
||||
lwsl_info("%s: wsistate 0x%x, pollout %d\n", __func__,
|
||||
(unsigned int)wsi->wsistate, pollfd->revents & LWS_POLLOUT);
|
||||
lwsl_info("%s: %s wsistate 0x%x, events %d, revents %d, pollout %d\n", __func__,
|
||||
wsi->lc.gutag, (unsigned int)wsi->wsistate,
|
||||
pollfd->events, pollfd->revents,
|
||||
pollfd->revents & LWS_POLLOUT);
|
||||
|
||||
/* !!! */
|
||||
if (wsi->wsistate == 0x10000013) {
|
||||
wsi->bugcatcher++;
|
||||
if (wsi->bugcatcher == 250) {
|
||||
lwsl_err("%s: BUGCATCHER\n", __func__);
|
||||
return LWS_HPI_RET_PLEASE_CLOSE_ME;
|
||||
}
|
||||
} else
|
||||
wsi->bugcatcher = 0;
|
||||
|
||||
/*
|
||||
* something went wrong with parsing the handshake, and
|
||||
|
@ -170,7 +182,9 @@ rops_handle_POLLIN_h2(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
|
||||
if (wsi->mux_substream || wsi->upgraded_to_http2) {
|
||||
wsi1 = lws_get_network_wsi(wsi);
|
||||
if (wsi1 && lws_has_buffered_out(wsi1))
|
||||
if (wsi1 && lws_has_buffered_out(wsi1)) {
|
||||
|
||||
lwsl_info("%s: has buffered out\n", __func__);
|
||||
/*
|
||||
* We cannot deal with any kind of new RX
|
||||
* because we are dealing with a partial send
|
||||
|
@ -178,6 +192,7 @@ rops_handle_POLLIN_h2(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
* expect to be able to send)
|
||||
*/
|
||||
return LWS_HPI_RET_HANDLED;
|
||||
}
|
||||
}
|
||||
|
||||
read:
|
||||
|
@ -205,8 +220,11 @@ read:
|
|||
!(pollfd->revents & pollfd->events & LWS_POLLIN))
|
||||
return LWS_HPI_RET_HANDLED;
|
||||
|
||||
/* We have something to read... */
|
||||
|
||||
if (!(lwsi_role_client(wsi) &&
|
||||
(lwsi_state(wsi) != LRS_ESTABLISHED &&
|
||||
// lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2 &&
|
||||
lwsi_state(wsi) != LRS_H2_WAITING_TO_SEND_HEADERS))) {
|
||||
|
||||
ebuf.token = pt->serv_buf;
|
||||
|
@ -228,7 +246,8 @@ read:
|
|||
// lwsl_notice("%s: Actual RX %d\n", __func__, ebuf.len);
|
||||
// if (ebuf.len > 0)
|
||||
// lwsl_hexdump_notice(ebuf.token, ebuf.len);
|
||||
}
|
||||
} else
|
||||
lwsl_info("%s: skipped read\n", __func__);
|
||||
|
||||
if (ebuf.len < 0)
|
||||
return LWS_HPI_RET_PLEASE_CLOSE_ME;
|
||||
|
@ -484,9 +503,9 @@ rops_write_role_protocol_h2(struct lws *wsi, unsigned char *buf, size_t len,
|
|||
}
|
||||
|
||||
if (base == LWS_WRITE_HTTP_FINAL || ((*wp) & LWS_WRITE_H2_STREAM_END)) {
|
||||
lwsl_info("%s: %s: setting END_STREAM\n", __func__,
|
||||
lws_wsi_tag(wsi));
|
||||
flags |= LWS_H2_FLAG_END_STREAM;
|
||||
lwsl_info("%s: %s: setting END_STREAM, 0x%x\n", __func__,
|
||||
lws_wsi_tag(wsi), flags);
|
||||
wsi->h2.send_END_STREAM = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -272,6 +272,7 @@ struct lws_h2_netconn {
|
|||
unsigned int is_first_header_char:1;
|
||||
unsigned int zero_huff_padding:1;
|
||||
unsigned int last_action_dyntable_resize:1;
|
||||
unsigned int sent_preface:1;
|
||||
|
||||
uint32_t hdr_idx;
|
||||
uint32_t hpack_len;
|
||||
|
|
|
@ -217,7 +217,9 @@ start_ws_handshake:
|
|||
#endif
|
||||
|
||||
#if defined (LWS_WITH_HTTP2)
|
||||
if (wsi->client_h2_alpn && lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2) {
|
||||
if (wsi->client_h2_alpn //&&
|
||||
//lwsi_state(wsi) != LRS_H1C_ISSUE_HANDSHAKE2
|
||||
) {
|
||||
/*
|
||||
* We connected to the server and set up tls and
|
||||
* negotiated "h2" or connected as clear text
|
||||
|
@ -227,16 +229,18 @@ start_ws_handshake:
|
|||
* now, not an h1 client connection.
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
if (wsi->tls.use_ssl & LCCSCF_USE_SSL)
|
||||
lws_tls_server_conn_alpn(wsi);
|
||||
#endif
|
||||
lwsl_info("%s: doing h2 hello path\n", __func__);
|
||||
|
||||
/* send the H2 preface to legitimize the connection */
|
||||
if (lws_h2_issue_preface(wsi)) {
|
||||
cce = "error sending h2 preface";
|
||||
goto bail3;
|
||||
}
|
||||
/*
|
||||
* send the H2 preface to legitimize the connection
|
||||
*
|
||||
* transitions us to LRS_H2_WAITING_TO_SEND_HEADERS
|
||||
*/
|
||||
if (wsi->client_h2_alpn)
|
||||
if (lws_h2_issue_preface(wsi)) {
|
||||
cce = "error sending h2 preface";
|
||||
goto bail3;
|
||||
}
|
||||
|
||||
// lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2);
|
||||
lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_CLIENT_HS_SEND,
|
||||
|
@ -800,7 +804,18 @@ lws_client_interpret_server_handshake(struct lws *wsi)
|
|||
/* wsi has closed */
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* We are redirecting, let's close in order to extricate
|
||||
* ourselves from the current wsi usage, eg, h2 mux cleanly.
|
||||
*
|
||||
* We will notice close_is_redirect and switch to redirect
|
||||
* flow late in the close action.
|
||||
*/
|
||||
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "redir");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* if h1 KA is allowed, enable the queued pipeline guys */
|
||||
|
@ -1094,7 +1109,7 @@ char *
|
|||
lws_generate_client_handshake(struct lws *wsi, char *pkt)
|
||||
{
|
||||
const char *meth, *pp = lws_hdr_simple_ptr(wsi,
|
||||
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS);
|
||||
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS), *path;
|
||||
char *p = pkt, *p1, *end = p + wsi->a.context->pt_serv_buf_size;
|
||||
|
||||
meth = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_METHOD);
|
||||
|
@ -1147,9 +1162,17 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
|
|||
* Sec-WebSocket-Version: 4
|
||||
*/
|
||||
|
||||
path = lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI);
|
||||
if (!path) {
|
||||
if (wsi->stash && wsi->stash->cis[CIS_PATH] &&
|
||||
wsi->stash->cis[CIS_PATH][0])
|
||||
path = wsi->stash->cis[CIS_PATH];
|
||||
else
|
||||
path = "/";
|
||||
}
|
||||
|
||||
p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
|
||||
"%s %s HTTP/1.1\x0d\x0a", meth,
|
||||
lws_hdr_simple_ptr(wsi, _WSI_TOKEN_CLIENT_URI));
|
||||
"%s %s HTTP/1.1\x0d\x0a", meth, path);
|
||||
|
||||
p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
|
||||
"Pragma: no-cache\x0d\x0a"
|
||||
|
@ -1168,7 +1191,9 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
|
|||
_WSI_TOKEN_CLIENT_ORIGIN));
|
||||
else
|
||||
p += lws_snprintf(p, lws_ptr_diff_size_t(end, p),
|
||||
"Origin: http://%s\x0d\x0a",
|
||||
"Origin: %s://%s\x0d\x0a",
|
||||
wsi->flags & LCCSCF_USE_SSL ?
|
||||
"https" : "http",
|
||||
lws_hdr_simple_ptr(wsi,
|
||||
_WSI_TOKEN_CLIENT_ORIGIN));
|
||||
}
|
||||
|
@ -1523,8 +1548,7 @@ static uint8_t hnames2[] = {
|
|||
_WSI_TOKEN_CLIENT_ORIGIN,
|
||||
_WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
|
||||
_WSI_TOKEN_CLIENT_METHOD,
|
||||
_WSI_TOKEN_CLIENT_IFACE,
|
||||
_WSI_TOKEN_CLIENT_ALPN
|
||||
_WSI_TOKEN_CLIENT_IFACE
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1545,9 +1569,9 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
|
|||
#if defined(LWS_ROLE_WS)
|
||||
struct _lws_websocket_related *ws;
|
||||
#endif
|
||||
char *stash, *p;
|
||||
const char *cisin[CIS_COUNT];
|
||||
struct lws *wsi;
|
||||
size_t size = 0;
|
||||
size_t o;
|
||||
int n;
|
||||
|
||||
if (!pwsi)
|
||||
|
@ -1559,7 +1583,7 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
|
|||
lwsl_debug("%s: %s: redir %d: %s\n", __func__, lws_wsi_tag(wsi),
|
||||
wsi->redirects, address);
|
||||
|
||||
if (wsi->redirects == 3) {
|
||||
if (wsi->redirects == 4) {
|
||||
lwsl_err("%s: Too many redirects\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1570,52 +1594,24 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
|
|||
* but leave our wsi extant and still bound to whatever vhost it was
|
||||
*/
|
||||
|
||||
o = path[0] == '/' && path[1] == '/';
|
||||
|
||||
memset((char *)cisin, 0, sizeof(cisin));
|
||||
|
||||
cisin[CIS_ADDRESS] = address;
|
||||
cisin[CIS_PATH] = path + o;
|
||||
cisin[CIS_HOST] = host;
|
||||
|
||||
for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames2); n++)
|
||||
size += (unsigned int)lws_hdr_total_length(wsi, hnames2[n]) + 1u;
|
||||
cisin[n + 3] = lws_hdr_simple_ptr(wsi, hnames2[n]);
|
||||
|
||||
if (size < (size_t)lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_URI) + 1)
|
||||
size = (unsigned int)lws_hdr_total_length(wsi, _WSI_TOKEN_CLIENT_URI) + 1u;
|
||||
#if defined(LWS_WITH_TLS)
|
||||
cisin[CIS_ALPN] = wsi->alpn;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The incoming address and host can be from inside the existing ah
|
||||
* we are going to detach and reattch
|
||||
*/
|
||||
|
||||
size += strlen(path) + 1 + strlen(address) + 1 + strlen(host) + 1 + 1;
|
||||
|
||||
p = stash = lws_malloc(size, __func__);
|
||||
if (!stash)
|
||||
if (lws_client_stash_create(wsi, cisin))
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
* _WSI_TOKEN_CLIENT_ORIGIN,
|
||||
* _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
|
||||
* _WSI_TOKEN_CLIENT_METHOD,
|
||||
* _WSI_TOKEN_CLIENT_IFACE,
|
||||
* _WSI_TOKEN_CLIENT_ALPN
|
||||
* address
|
||||
* host
|
||||
* path
|
||||
*/
|
||||
|
||||
for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames2); n++)
|
||||
if (lws_hdr_total_length(wsi, hnames2[n]) &&
|
||||
lws_hdr_simple_ptr(wsi, hnames2[n])) {
|
||||
memcpy(p, lws_hdr_simple_ptr(wsi, hnames2[n]), (size_t)(
|
||||
lws_hdr_total_length(wsi, hnames2[n]) + 1));
|
||||
p += (size_t)(lws_hdr_total_length(wsi, hnames2[n]) + 1);
|
||||
} else
|
||||
*p++ = '\0';
|
||||
|
||||
memcpy(p, address, strlen(address) + (size_t)1);
|
||||
address = p;
|
||||
p += strlen(address) + 1;
|
||||
memcpy(p, host, strlen(host) + (size_t)1);
|
||||
host = p;
|
||||
p += strlen(host) + 1;
|
||||
memcpy(p, path, strlen(path) + (size_t)1);
|
||||
path = p;
|
||||
|
||||
if (!port) {
|
||||
lwsl_info("%s: forcing port 443\n", __func__);
|
||||
|
||||
|
@ -1623,8 +1619,16 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
|
|||
ssl = 1;
|
||||
}
|
||||
|
||||
lwsl_info("redirect ads='%s', port=%d, path='%s', ssl = %d, pifds %d\n",
|
||||
address, port, path, ssl, wsi->position_in_fds_table);
|
||||
wsi->c_port = (uint16_t)port;
|
||||
|
||||
wsi->flags = (wsi->flags & (~LCCSCF_USE_SSL)) |
|
||||
(ssl ? LCCSCF_USE_SSL : 0);
|
||||
|
||||
lwsl_notice("%s: REDIRECT %s:%d, path='%s', ssl = %d, alpn='%s'\n",
|
||||
__func__, address, port, path, ssl, cisin[CIS_ALPN]);
|
||||
|
||||
if (!cisin[CIS_ALPN][0])
|
||||
assert(0);
|
||||
|
||||
lws_pt_lock(pt, __func__);
|
||||
__remove_wsi_socket_from_fds(wsi);
|
||||
|
@ -1636,6 +1640,14 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
|
|||
wsi->ws = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* After this point we can't trust the incoming strings like address,
|
||||
* path any more, since they may have been pointing into the old ah.
|
||||
*
|
||||
* We must use the copies in the wsi->stash instead if we want them.
|
||||
*/
|
||||
|
||||
__lws_reset_wsi(wsi); /* detaches ah here */
|
||||
#if defined(LWS_ROLE_WS)
|
||||
if (weak)
|
||||
|
@ -1643,102 +1655,11 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
|
|||
#endif
|
||||
wsi->client_pipeline = 1;
|
||||
|
||||
/* close the connection by hand */
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
lws_ssl_close(wsi);
|
||||
#endif
|
||||
|
||||
if (wsi->role_ops &&
|
||||
lws_rops_fidx(wsi->role_ops, LWS_ROPS_close_kill_connection))
|
||||
lws_rops_func_fidx(wsi->role_ops, LWS_ROPS_close_kill_connection).
|
||||
close_kill_connection(wsi, 1);
|
||||
|
||||
if (wsi->a.context->event_loop_ops->close_handle_manually)
|
||||
wsi->a.context->event_loop_ops->close_handle_manually(wsi);
|
||||
else
|
||||
if (wsi->desc.sockfd != LWS_SOCK_INVALID)
|
||||
compatible_close(wsi->desc.sockfd);
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
if (!ssl)
|
||||
wsi->tls.use_ssl &= (unsigned int)~LCCSCF_USE_SSL;
|
||||
else
|
||||
wsi->tls.use_ssl |= LCCSCF_USE_SSL;
|
||||
#else
|
||||
if (ssl) {
|
||||
lwsl_err("%s: not configured for ssl\n", __func__);
|
||||
goto bail;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (wsi->a.protocol && wsi->role_ops && wsi->protocol_bind_balance) {
|
||||
wsi->a.protocol->callback(wsi,
|
||||
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->a.protocol = NULL;
|
||||
if (wsi->a.protocol)
|
||||
lws_bind_protocol(wsi, wsi->a.protocol, "client_reset");
|
||||
wsi->pending_timeout = NO_PENDING_TIMEOUT;
|
||||
wsi->c_port = (uint16_t)port;
|
||||
wsi->hdr_parsing_completed = 0;
|
||||
|
||||
if (lws_header_table_attach(wsi, 0)) {
|
||||
lwsl_err("%s: failed to get ah\n", __func__);
|
||||
goto bail;
|
||||
}
|
||||
//_lws_header_table_reset(wsi->http.ah);
|
||||
|
||||
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
|
||||
goto bail;
|
||||
|
||||
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_HOST, host))
|
||||
goto bail;
|
||||
|
||||
/*
|
||||
* _WSI_TOKEN_CLIENT_ORIGIN,
|
||||
* _WSI_TOKEN_CLIENT_SENT_PROTOCOLS,
|
||||
* _WSI_TOKEN_CLIENT_METHOD,
|
||||
* _WSI_TOKEN_CLIENT_IFACE,
|
||||
* _WSI_TOKEN_CLIENT_ALPN
|
||||
* address
|
||||
* host
|
||||
* path
|
||||
* Will complete at close flow
|
||||
*/
|
||||
|
||||
p = stash;
|
||||
for (n = 0; n < (int)LWS_ARRAY_SIZE(hnames2); n++) {
|
||||
if (lws_hdr_simple_create(wsi, hnames2[n], p))
|
||||
goto bail;
|
||||
p += lws_hdr_total_length(wsi, hnames2[n]) + 1;
|
||||
}
|
||||
|
||||
stash[0] = '/';
|
||||
memmove(&stash[1], path, size - 1 < strlen(path) + 1 ?
|
||||
size - 1 : strlen(path) + (size_t)1);
|
||||
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_URI, stash))
|
||||
goto bail;
|
||||
|
||||
lws_free_set_NULL(stash);
|
||||
|
||||
#if defined(LWS_WITH_HTTP2)
|
||||
if (wsi->client_mux_substream)
|
||||
wsi->h2.END_STREAM = wsi->h2.END_HEADERS = 0;
|
||||
#endif
|
||||
|
||||
*pwsi = lws_client_connect_2_dnsreq(wsi);
|
||||
wsi->close_is_redirect = 1;
|
||||
|
||||
return *pwsi;
|
||||
|
||||
bail:
|
||||
lws_free_set_NULL(stash);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ lws_ssl_client_connect2(struct lws *wsi, char *errbuf, size_t len)
|
|||
lwsi_set_state(wsi, LRS_WAITING_SSL);
|
||||
/* fallthru */
|
||||
case LWS_SSL_CAPABLE_MORE_SERVICE:
|
||||
return 0;
|
||||
return 0; /* retry */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,7 +89,7 @@ lws_ssl_client_connect2(struct lws *wsi, char *errbuf, size_t len)
|
|||
(lws_now_usecs() - wsi->conmon_datum);
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
return 1; /* connected */
|
||||
}
|
||||
|
||||
|
||||
|
@ -176,7 +176,6 @@ int lws_context_init_client_ssl(const struct lws_context_creation_info *info,
|
|||
int
|
||||
lws_client_create_tls(struct lws *wsi, const char **pcce, int do_c1)
|
||||
{
|
||||
|
||||
/* we can retry this... just cook the SSL BIO the first time */
|
||||
|
||||
if (wsi->tls.use_ssl & LCCSCF_USE_SSL) {
|
||||
|
@ -198,7 +197,7 @@ lws_client_create_tls(struct lws *wsi, const char **pcce, int do_c1)
|
|||
}
|
||||
|
||||
if (!do_c1)
|
||||
return 0;
|
||||
return CCTLS_RETURN_DONE;
|
||||
|
||||
lws_metrics_caliper_report(wsi->cal_conn, METRES_GO);
|
||||
lws_metrics_caliper_bind(wsi->cal_conn, wsi->a.context->mt_conn_tls);
|
||||
|
@ -211,39 +210,18 @@ lws_client_create_tls(struct lws *wsi, const char **pcce, int do_c1)
|
|||
lwsl_debug("%s: lws_ssl_client_connect1: %d\n", __func__, n);
|
||||
if (!n)
|
||||
return CCTLS_RETURN_RETRY; /* caller should return 0 */
|
||||
|
||||
if (n < 0) {
|
||||
*pcce = (const char *)wsi->a.context->pt[(int)wsi->tsi].serv_buf;
|
||||
lws_metrics_caliper_report(wsi->cal_conn, METRES_NOGO);
|
||||
return CCTLS_RETURN_ERROR;
|
||||
}
|
||||
/* ...connect1 already handled caliper if SSL_accept done */
|
||||
|
||||
lws_tls_server_conn_alpn(wsi);
|
||||
|
||||
} else
|
||||
wsi->tls.ssl = NULL;
|
||||
|
||||
#if 0
|
||||
#if defined (LWS_WITH_HTTP2)
|
||||
if (wsi->client_h2_alpn) {
|
||||
/*
|
||||
* We connected to the server and set up tls, and
|
||||
* negotiated "h2".
|
||||
*
|
||||
* So this is it, we are an h2 nwsi client connection
|
||||
* now, not an h1 client connection.
|
||||
*/
|
||||
#if defined(LWS_WITH_TLS)
|
||||
lws_tls_server_conn_alpn(wsi);
|
||||
#endif
|
||||
|
||||
/* send the H2 preface to legitimize the connection */
|
||||
if (lws_h2_issue_preface(wsi)) {
|
||||
*pcce = "error sending h2 preface";
|
||||
return CCTLS_RETURN_ERROR;
|
||||
}
|
||||
|
||||
lwsi_set_state(wsi, LRS_H1C_ISSUE_HANDSHAKE2);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return CCTLS_RETURN_DONE; /* OK */
|
||||
}
|
||||
|
|
|
@ -116,8 +116,12 @@ lws_tls_server_conn_alpn(struct lws *wsi)
|
|||
char cstr[10];
|
||||
unsigned len;
|
||||
|
||||
if (!wsi->tls.ssl)
|
||||
lwsl_info("%s\n", __func__);
|
||||
|
||||
if (!wsi->tls.ssl) {
|
||||
lwsl_err("%s: non-ssl\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SSL_get0_alpn_selected(wsi->tls.ssl, &name, &len);
|
||||
if (!len) {
|
||||
|
@ -131,10 +135,12 @@ lws_tls_server_conn_alpn(struct lws *wsi)
|
|||
memcpy(cstr, name, len);
|
||||
cstr[len] = '\0';
|
||||
|
||||
lwsl_info("negotiated '%s' using ALPN\n", cstr);
|
||||
lwsl_info("%s: negotiated '%s' using ALPN\n", __func__, cstr);
|
||||
wsi->tls.use_ssl |= LCCSCF_USE_SSL;
|
||||
|
||||
return lws_role_call_alpn_negotiated(wsi, (const char *)cstr);
|
||||
#else
|
||||
lwsl_err("%s: openssl too old\n", __func__);
|
||||
#endif // OPENSSL_VERSION_NUMBER >= 0x10002000L
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -119,17 +119,17 @@ endif()
|
|||
add_test(NAME http-client-multi-h1 COMMAND lws-minimal-http-client-multi
|
||||
--h1 -l --port ${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-pipe COMMAND lws-minimal-http-client-multi
|
||||
-p -l --port ${PORT_HCM_SRV})
|
||||
-p -l --port ${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-h1-pipe COMMAND lws-minimal-http-client-multi
|
||||
--h1 -p -l --port ${PORT_HCM_SRV})
|
||||
--h1 -p -l --port ${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-stag COMMAND lws-minimal-http-client-multi
|
||||
-s -l --port ${PORT_HCM_SRV})
|
||||
-s -l --port ${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-stag-h1 COMMAND lws-minimal-http-client-multi
|
||||
--h1 -s -l --port ${PORT_HCM_SRV})
|
||||
--h1 -s -l --port ${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-stag-pipe COMMAND lws-minimal-http-client-multi
|
||||
-p -s -l --port ${PORT_HCM_SRV})
|
||||
-p -s -l --port ${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-stag-h1-pipe COMMAND lws-minimal-http-client-multi
|
||||
--h1 -p -s -l --port ${PORT_HCM_SRV})
|
||||
--h1 -p -s -l --port ${PORT_HCM_SRV} -d1151)
|
||||
|
||||
# confirm that the pipelined mode really is doing it in one connection
|
||||
add_test(NAME http-client-multi-restrict-pipe COMMAND lws-minimal-http-client-multi -d1151 --limit 1 -p -l --port ${PORT_HCM_SRV})
|
||||
|
@ -137,9 +137,9 @@ endif()
|
|||
add_test(NAME http-client-multi-restrict-stag-pipe COMMAND lws-minimal-http-client-multi -d1151 --limit 1 -p -s -l --port ${PORT_HCM_SRV})
|
||||
add_test(NAME http-client-multi-restrict-stag-h1-pipe COMMAND lws-minimal-http-client-multi -d1151 --limit 1 --h1 -p -s -l --port ${PORT_HCM_SRV})
|
||||
# confirm that we do fail with a one connection limit and no pipelining
|
||||
add_test(NAME http-client-multi-restrict-nopipe-fail COMMAND lws-minimal-http-client-multi --limit 1 -l --port ${PORT_HCM_SRV})
|
||||
add_test(NAME http-client-multi-restrict-nopipe-fail COMMAND lws-minimal-http-client-multi --limit 1 -l --port ${PORT_HCM_SRV} -d1151)
|
||||
set_property(TEST http-client-multi-restrict-nopipe-fail PROPERTY WILL_FAIL TRUE)
|
||||
add_test(NAME http-client-multi-restrict-h1-nopipe-fail COMMAND lws-minimal-http-client-multi --limit 1 --h1 -l --port ${PORT_HCM_SRV})
|
||||
add_test(NAME http-client-multi-restrict-h1-nopipe-fail COMMAND lws-minimal-http-client-multi --limit 1 --h1 -l --port ${PORT_HCM_SRV} -d1151)
|
||||
set_property(TEST http-client-multi-restrict-h1-nopipe-fail PROPERTY WILL_FAIL TRUE)
|
||||
|
||||
set_tests_properties(http-client-multi-restrict-pipe
|
||||
|
@ -163,21 +163,21 @@ endif()
|
|||
|
||||
# POSTs against local http-server-form-post
|
||||
add_test(NAME http-client-multi-post COMMAND lws-minimal-http-client-multi
|
||||
--post -l --port 1${PORT_HCM_SRV})
|
||||
--post -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-h1 COMMAND lws-minimal-http-client-multi
|
||||
--post --h1 -l --port 1${PORT_HCM_SRV})
|
||||
--post --h1 -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-pipe COMMAND lws-minimal-http-client-multi
|
||||
--post -p -l --port 1${PORT_HCM_SRV})
|
||||
--post -p -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-h1-pipe COMMAND lws-minimal-http-client-multi
|
||||
--post --h1 -p -l --port 1${PORT_HCM_SRV})
|
||||
--post --h1 -p -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-stag COMMAND lws-minimal-http-client-multi
|
||||
--post -s -l -d1151 --port 1${PORT_HCM_SRV})
|
||||
--post -s -l -d1151 --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-stag-h1 COMMAND lws-minimal-http-client-multi
|
||||
--post --h1 -d1151 -s -l --port 1${PORT_HCM_SRV})
|
||||
--post --h1 -d1151 -s -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-stag-pipe COMMAND lws-minimal-http-client-multi
|
||||
--post -p -s -l --port 1${PORT_HCM_SRV})
|
||||
--post -p -s -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
add_test(NAME http-client-multi-post-stag-h1-pipe COMMAND lws-minimal-http-client-multi
|
||||
--post --h1 -p -s -l --port 1${PORT_HCM_SRV})
|
||||
--post --h1 -p -s -l --port 1${PORT_HCM_SRV} -d1151)
|
||||
set_tests_properties(http-client-multi-post
|
||||
http-client-multi-post-h1
|
||||
http-client-multi-post-pipe
|
||||
|
|
|
@ -259,7 +259,7 @@ system_notify_cb(lws_state_manager_t *mgr, lws_state_notify_link_t *link,
|
|||
LCCSCF_ACCEPT_TLS_DOWNGRADE_REDIRECTS |
|
||||
LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM;
|
||||
|
||||
i.alpn = "h2";
|
||||
i.alpn = "h2,http/1.1";
|
||||
if (lws_cmdline_option(a->argc, a->argv, "--h1"))
|
||||
i.alpn = "http/1.1";
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue