1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

mux children: generalize helpers out of h2 implementation

This should be a NOP for h2 support and only affects internal
apis.  But it lets us reuse the working and reliable h2 mux
arrangements directly in other protocols later, and share code
so building for h2 + new protocols can take advantage of common
mux child handling struct and code.

Break out common mux handling struct into its own type.

Convert all uses of members that used to be in wsi->h2 to wsi->mux

Audit all references to the members and break out generic helpers
for anything that is useful for other mux-capable protocols to
reuse wsi->mux related features.
This commit is contained in:
Andy Green 2019-12-23 11:31:57 +00:00
parent 1eb4d335d2
commit 7221bc57b5
23 changed files with 551 additions and 452 deletions

View file

@ -264,7 +264,7 @@ __lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
#endif
#if defined(LWS_WITH_HTTP2)
if (wsi->h2_stream_immortal)
if (wsi->mux_stream_immortal)
lws_http_close_immortal(wsi);
#endif

View file

@ -57,7 +57,7 @@ stream_close(struct lws *wsi)
wsi->http.did_stream_close = 1;
if (wsi->http2_substream) {
if (wsi->mux_substream) {
if (lws_write(wsi, (unsigned char *)buf + LWS_PRE, 0,
LWS_WRITE_HTTP_FINAL) < 0) {
lwsl_info("%s: COMPL_CLIENT_HTTP: h2 fin wr failed\n",
@ -115,7 +115,7 @@ lws_callback_ws_proxy(struct lws *wsi, enum lws_callback_reasons reason,
lws_process_ws_upgrade2(wsi->parent);
#if defined(LWS_WITH_HTTP2)
if (wsi->parent->http2_substream)
if (wsi->parent->mux_substream)
lwsl_info("%s: proxied h2 -> h1 ws established\n", __func__);
#endif
break;
@ -330,7 +330,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
}
if (wsi->reason_bf & LWS_CB_REASON_AUX_BF__CGI_CHUNK_END) {
if (!wsi->http2_substream) {
if (!wsi->mux_substream) {
memcpy(buf + LWS_PRE, "0\x0d\x0a\x0d\x0a", 5);
lwsl_debug("writing chunk term and exiting\n");
n = lws_write(wsi, (unsigned char *)buf +
@ -508,7 +508,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
proxy_header(parent, wsi, end, 256,
WSI_TOKEN_HTTP_LOCATION, &p, end);
if (!parent->http2_substream)
if (!parent->mux_substream)
if (lws_add_http_header_by_token(parent,
WSI_TOKEN_CONNECTION, (unsigned char *)"close",
5, &p, end))
@ -522,7 +522,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
* our own chunking since we still don't know the size.
*/
if (!parent->http2_substream &&
if (!parent->mux_substream &&
!lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_CONTENT_LENGTH)) {
lwsl_debug("downstream parent chunked\n");
if (lws_add_http_header_by_token(parent,
@ -661,7 +661,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: %d %" PRIu64 "\n",
wsi->http.cgi->explicitly_chunked,
(uint64_t)wsi->http.cgi->content_length);
if (!(wsi->http.cgi->explicitly_chunked && wsi->http2_substream) &&
if (!(wsi->http.cgi->explicitly_chunked && wsi->mux_substream) &&
!wsi->http.cgi->content_length) {
/* send terminating chunk */
lwsl_debug("LWS_CALLBACK_CGI_TERMINATED: ending\n");
@ -670,7 +670,7 @@ lws_callback_http_dummy(struct lws *wsi, enum lws_callback_reasons reason,
lws_set_timeout(wsi, PENDING_TIMEOUT_CGI, 3);
break;
}
if (wsi->http2_substream && !wsi->cgi_stdout_zero_length)
if (wsi->mux_substream && !wsi->cgi_stdout_zero_length)
lws_write(wsi, (unsigned char *)buf + LWS_PRE, 0,
LWS_WRITE_HTTP_FINAL);

View file

@ -93,7 +93,7 @@ lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
if (!len || !buf)
return 0;
if (!wsi->http2_substream && !lws_socket_is_valid(wsi->desc.sockfd))
if (!wsi->mux_substream && !lws_socket_is_valid(wsi->desc.sockfd))
lwsl_warn("** error invalid sock but expected to send\n");
/* limit sending */

View file

@ -147,7 +147,7 @@ _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)
pa->prev_events = pfd->events;
pa->events = pfd->events = (pfd->events & ~_and) | _or;
if (wsi->http2_substream)
if (wsi->mux_substream)
return 0;
#if defined(LWS_WITH_EXTERNAL_POLL)

View file

@ -29,6 +29,21 @@
#define _POSIX_C_SOURCE 200112L
#endif
/*
* Generic pieces needed to manage muxable stream protocols like h2
*/
struct lws_muxable {
struct lws *parent_wsi;
struct lws *child_list;
struct lws *sibling_list;
unsigned int my_sid;
unsigned int child_count;
uint8_t requested_POLLOUT;
};
#include "private-lib-roles.h"
#ifdef LWS_WITH_IPV6
@ -576,6 +591,32 @@ struct lws_vhost {
void
__lws_vhost_destroy2(struct lws_vhost *vh);
#define mux_to_wsi(_m) lws_container_of(_m, struct lws, mux)
void
lws_wsi_mux_insert(struct lws *wsi, struct lws *parent_wsi, int sid);
int
lws_wsi_mux_mark_parents_needing_writeable(struct lws *wsi);
struct lws *
lws_wsi_mux_move_child_to_tail(struct lws **wsi2);
int
lws_wsi_mux_action_pending_writeable_reqs(struct lws *wsi);
void
lws_wsi_mux_dump_children(struct lws *wsi);
void
lws_wsi_mux_close_children(struct lws *wsi, int reason);
void
lws_wsi_mux_sibling_disconnect(struct lws *wsi);
void
lws_wsi_mux_dump_waiting_children(struct lws *wsi);
int
lws_wsi_mux_apply_queue(struct lws *wsi);
/*
* struct lws
*/
@ -584,47 +625,51 @@ struct lws {
/* structs */
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
struct _lws_http_mode_related http;
struct _lws_http_mode_related http;
#endif
#if defined(LWS_ROLE_H2)
struct _lws_h2_related h2;
struct _lws_h2_related h2;
#endif
#if defined(LWS_ROLE_WS)
struct _lws_websocket_related *ws; /* allocated if we upgrade to ws */
struct _lws_websocket_related *ws; /* allocated if we upgrade to ws */
#endif
#if defined(LWS_ROLE_DBUS)
struct _lws_dbus_mode_related dbus;
struct _lws_dbus_mode_related dbus;
#endif
#if defined(LWS_ROLE_H2)
struct lws_muxable mux;
#endif
/* lifetime members */
#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || \
defined(LWS_WITH_LIBEVENT)
struct lws_io_watcher w_read;
struct lws_io_watcher w_read;
#endif
#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBEVENT)
struct lws_io_watcher w_write;
struct lws_io_watcher w_write;
#endif
#if defined(LWS_WITH_DETAILED_LATENCY)
lws_detlat_t detlat;
#endif
lws_sorted_usec_list_t sul_timeout;
lws_sorted_usec_list_t sul_hrtimer;
lws_sorted_usec_list_t sul_validity;
lws_sorted_usec_list_t sul_timeout;
lws_sorted_usec_list_t sul_hrtimer;
lws_sorted_usec_list_t sul_validity;
struct lws_dll2 dll_buflist; /* guys with pending rxflow */
struct lws_dll2 same_vh_protocol;
struct lws_dll2 vh_awaiting_socket;
struct lws_dll2 dll_buflist; /* guys with pending rxflow */
struct lws_dll2 same_vh_protocol;
struct lws_dll2 vh_awaiting_socket;
#if defined(LWS_WITH_SYS_ASYNC_DNS)
struct lws_dll2 adns; /* on adns list of guys to tell result */
lws_async_dns_cb_t adns_cb; /* callback with result */
struct lws_dll2 adns; /* on adns list of guys to tell result */
lws_async_dns_cb_t adns_cb; /* callback with result */
#endif
#if defined(LWS_WITH_CLIENT)
struct lws_dll2 dll_cli_active_conns;
struct lws_dll2_owner dll2_cli_txn_queue_owner;
struct lws_dll2 dll2_cli_txn_queue;
struct lws_dll2 dll_cli_active_conns;
struct lws_dll2 dll2_cli_txn_queue;
struct lws_dll2_owner dll2_cli_txn_queue_owner;
#endif
#if defined(LWS_WITH_ACCESS_LOG)
@ -632,134 +677,134 @@ struct lws {
#endif
/* pointers */
struct lws_context *context;
struct lws_vhost *vhost;
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 */
const struct lws_role_ops *role_ops;
const struct lws_protocols *protocol;
struct lws_sequencer *seq; /* associated sequencer if any */
const lws_retry_bo_t *retry_policy;
struct lws_context *context;
struct lws_vhost *vhost;
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 */
const struct lws_role_ops *role_ops;
const struct lws_protocols *protocol;
struct lws_sequencer *seq; /* associated sequencer if any */
const lws_retry_bo_t *retry_policy;
#if defined(LWS_WITH_THREADPOOL)
struct lws_threadpool_task *tp_task;
struct lws_threadpool_task *tp_task;
#endif
#if defined(LWS_WITH_PEER_LIMITS)
struct lws_peer *peer;
struct lws_peer *peer;
#endif
#if defined(LWS_WITH_UDP)
struct lws_udp *udp;
struct lws_udp *udp;
#endif
#if defined(LWS_WITH_CLIENT)
struct client_info_stash *stash;
char *cli_hostname_copy;
const struct addrinfo *dns_results;
const struct addrinfo *dns_results_next;
struct client_info_stash *stash;
char *cli_hostname_copy;
const struct addrinfo *dns_results;
const struct addrinfo *dns_results_next;
#endif
void *user_space;
void *opaque_parent_data;
void *opaque_user_data;
void *user_space;
void *opaque_parent_data;
void *opaque_user_data;
struct lws_buflist *buflist; /* input-side buflist */
struct lws_buflist *buflist_out; /* output-side buflist */
struct lws_buflist *buflist; /* input-side buflist */
struct lws_buflist *buflist_out; /* output-side buflist */
#if defined(LWS_WITH_TLS)
struct lws_lws_tls tls;
struct lws_lws_tls tls;
#endif
lws_sock_file_fd_type desc; /* .filefd / .sockfd */
lws_sock_file_fd_type desc; /* .filefd / .sockfd */
#if defined(LWS_WITH_STATS)
uint64_t active_writable_req_us;
#if defined(LWS_WITH_TLS)
uint64_t accept_start_us;
#endif
#endif
lws_wsi_state_t wsistate;
lws_wsi_state_t wsistate_pre_close;
lws_wsi_state_t wsistate;
lws_wsi_state_t wsistate_pre_close;
/* ints */
#define LWS_NO_FDS_POS (-1)
int position_in_fds_table;
int position_in_fds_table;
#if defined(LWS_WITH_CLIENT)
int chunk_remaining;
int flags;
int chunk_remaining;
int flags;
#endif
unsigned int cache_secs;
unsigned int cache_secs;
unsigned int hdr_parsing_completed:1;
unsigned int http2_substream:1;
unsigned int upgraded_to_http2:1;
unsigned int h2_stream_immortal:1;
unsigned int h2_stream_carries_ws:1; /* immortal set as well */
unsigned int h2_stream_carries_sse:1; /* immortal set as well */
unsigned int h2_acked_settings:1;
unsigned int seen_nonpseudoheader:1;
unsigned int listener:1;
unsigned int pf_packet:1;
unsigned int do_broadcast:1;
unsigned int user_space_externally_allocated:1;
unsigned int socket_is_permanently_unusable:1;
unsigned int rxflow_change_to:2;
unsigned int conn_stat_done:1;
unsigned int cache_reuse:1;
unsigned int cache_revalidate:1;
unsigned int cache_intermediaries:1;
unsigned int favoured_pollin:1;
unsigned int sending_chunked:1;
unsigned int interpreting:1;
unsigned int already_did_cce:1;
unsigned int told_user_closed:1;
unsigned int told_event_loop_closed:1;
unsigned int waiting_to_send_close_frame:1;
unsigned int close_needs_ack:1;
unsigned int ipv6:1;
unsigned int parent_pending_cb_on_writable:1;
unsigned int cgi_stdout_zero_length:1;
unsigned int seen_zero_length_recv:1;
unsigned int rxflow_will_be_applied:1;
unsigned int event_pipe:1;
unsigned int handling_404:1;
unsigned int protocol_bind_balance:1;
unsigned int unix_skt:1;
unsigned int close_when_buffered_out_drained:1;
unsigned int h1_ws_proxied:1;
unsigned int proxied_ws_parent:1;
unsigned int do_bind:1;
unsigned int oom4:1;
unsigned int validity_hup:1;
unsigned int hdr_parsing_completed:1;
unsigned int mux_substream:1;
unsigned int upgraded_to_http2:1;
unsigned int mux_stream_immortal:1;
unsigned int h2_stream_carries_ws:1; /* immortal set as well */
unsigned int h2_stream_carries_sse:1; /* immortal set as well */
unsigned int h2_acked_settings:1;
unsigned int seen_nonpseudoheader:1;
unsigned int listener:1;
unsigned int pf_packet:1;
unsigned int do_broadcast:1;
unsigned int user_space_externally_allocated:1;
unsigned int socket_is_permanently_unusable:1;
unsigned int rxflow_change_to:2;
unsigned int conn_stat_done:1;
unsigned int cache_reuse:1;
unsigned int cache_revalidate:1;
unsigned int cache_intermediaries:1;
unsigned int favoured_pollin:1;
unsigned int sending_chunked:1;
unsigned int interpreting:1;
unsigned int already_did_cce:1;
unsigned int told_user_closed:1;
unsigned int told_event_loop_closed:1;
unsigned int waiting_to_send_close_frame:1;
unsigned int close_needs_ack:1;
unsigned int ipv6:1;
unsigned int parent_pending_cb_on_writable:1;
unsigned int cgi_stdout_zero_length:1;
unsigned int seen_zero_length_recv:1;
unsigned int rxflow_will_be_applied:1;
unsigned int event_pipe:1;
unsigned int handling_404:1;
unsigned int protocol_bind_balance:1;
unsigned int unix_skt:1;
unsigned int close_when_buffered_out_drained:1;
unsigned int h1_ws_proxied:1;
unsigned int proxied_ws_parent:1;
unsigned int do_bind:1;
unsigned int oom4:1;
unsigned int validity_hup:1;
unsigned int could_have_pending:1; /* detect back-to-back writes */
unsigned int outer_will_close:1;
unsigned int shadow:1; /* we do not control fd lifecycle at all */
unsigned int could_have_pending:1; /* detect back-to-back writes */
unsigned int outer_will_close:1;
unsigned int shadow:1; /* we do not control fd lifecycle at all */
#ifdef LWS_WITH_ACCESS_LOG
unsigned int access_log_pending:1;
unsigned int access_log_pending:1;
#endif
#if defined(LWS_WITH_CLIENT)
unsigned int do_ws:1; /* whether we are doing http or ws flow */
unsigned int chunked:1; /* if the clientside connection is chunked */
unsigned int client_rx_avail:1;
unsigned int client_http_body_pending:1;
unsigned int transaction_from_pipeline_queue:1;
unsigned int keepalive_active:1;
unsigned int keepalive_rejected:1;
unsigned int redirected_to_get:1;
unsigned int client_pipeline:1;
unsigned int client_h2_alpn:1;
unsigned int client_h2_substream:1;
unsigned int client_h2_migrated:1;
unsigned int do_ws:1; /* whether we are doing http or ws flow */
unsigned int chunked:1; /* if the clientside connection is chunked */
unsigned int client_rx_avail:1;
unsigned int client_http_body_pending:1;
unsigned int transaction_from_pipeline_queue:1;
unsigned int keepalive_active:1;
unsigned int keepalive_rejected:1;
unsigned int redirected_to_get:1;
unsigned int client_pipeline:1;
unsigned int client_h2_alpn:1;
unsigned int client_mux_substream:1;
unsigned int client_mux_migrated:1;
#endif
#ifdef _WIN32
unsigned int sock_send_blocking:1;
#endif
uint16_t ocport, c_port;
uint16_t retry;
uint16_t ocport, c_port;
uint16_t retry;
/* chars */
@ -1110,7 +1155,7 @@ lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int len, int meth);
#endif
void
lws_http_mark_immortal(struct lws *wsi);
lws_mux_mark_immortal(struct lws *wsi);
void
lws_http_close_immortal(struct lws *wsi);

View file

@ -156,8 +156,8 @@ lws_set_timeout(struct lws *wsi, enum pending_timeout reason, int secs)
if (secs == LWS_TO_KILL_ASYNC)
secs = 0;
// assert(!secs || !wsi->h2_stream_immortal);
if (secs && wsi->h2_stream_immortal)
// assert(!secs || !wsi->mux_stream_immortal);
if (secs && wsi->mux_stream_immortal)
lwsl_err("%s: on immortal stream %d %d\n", __func__, reason, secs);
lws_pt_lock(pt, __func__);

View file

@ -86,29 +86,29 @@ lws_vhost_unbind_wsi(struct lws *wsi)
lws_context_unlock(wsi->context); /* } context ---------- */
}
LWS_VISIBLE struct lws *
struct lws *
lws_get_network_wsi(struct lws *wsi)
{
if (!wsi)
return NULL;
#if defined(LWS_WITH_HTTP2)
if (!wsi->http2_substream
if (!wsi->mux_substream
#if defined(LWS_WITH_CLIENT)
&& !wsi->client_h2_substream
&& !wsi->client_mux_substream
#endif
)
return wsi;
while (wsi->h2.parent_wsi)
wsi = wsi->h2.parent_wsi;
while (wsi->mux.parent_wsi)
wsi = wsi->mux.parent_wsi;
#endif
return wsi;
}
LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
const struct lws_protocols *
lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name)
{
int n;
@ -222,7 +222,7 @@ lws_rx_flow_control(struct lws *wsi, int _enable)
int en = _enable;
// h2 ignores rx flow control atm
if (lwsi_role_h2(wsi) || wsi->http2_substream ||
if (lwsi_role_h2(wsi) || wsi->mux_substream ||
lwsi_role_h2_ENCAPSULATION(wsi))
return 0; // !!!
@ -312,7 +312,7 @@ __lws_rx_flow_control(struct lws *wsi)
struct lws *wsic = wsi->child_list;
// h2 ignores rx flow control atm
if (lwsi_role_h2(wsi) || wsi->http2_substream ||
if (lwsi_role_h2(wsi) || wsi->mux_substream ||
lwsi_role_h2_ENCAPSULATION(wsi))
return 0; // !!!
@ -898,11 +898,11 @@ lws_http_close_immortal(struct lws *wsi)
{
struct lws *nwsi;
if (!wsi->http2_substream)
if (!wsi->mux_substream)
return;
assert(wsi->h2_stream_immortal);
wsi->h2_stream_immortal = 0;
assert(wsi->mux_stream_immortal);
wsi->mux_stream_immortal = 0;
nwsi = lws_get_network_wsi(wsi);
lwsl_debug("%s: %p %p %d\n", __func__, wsi, nwsi,
@ -920,15 +920,15 @@ lws_http_close_immortal(struct lws *wsi)
}
void
lws_http_mark_immortal(struct lws *wsi)
lws_mux_mark_immortal(struct lws *wsi)
{
struct lws *nwsi;
lws_set_timeout(wsi, NO_PENDING_TIMEOUT, 0);
if (!wsi->http2_substream
if (!wsi->mux_substream
#if defined(LWS_WITH_CLIENT)
&& !wsi->client_h2_substream
&& !wsi->client_mux_substream
#endif
) {
lwsl_err("%s: not h2 substream\n", __func__);
@ -940,7 +940,7 @@ lws_http_mark_immortal(struct lws *wsi)
lwsl_debug("%s: %p %p %d\n", __func__, wsi, nwsi,
nwsi->immortal_substream_count);
wsi->h2_stream_immortal = 1;
wsi->mux_stream_immortal = 1;
assert(nwsi->immortal_substream_count < 255); /* largest count */
nwsi->immortal_substream_count++;
if (nwsi->immortal_substream_count == 1)
@ -952,14 +952,15 @@ int
lws_http_mark_sse(struct lws *wsi)
{
lws_http_headers_detach(wsi);
lws_http_mark_immortal(wsi);
lws_mux_mark_immortal(wsi);
if (wsi->http2_substream)
if (wsi->mux_substream)
wsi->h2_stream_carries_sse = 1;
return 0;
}
#if defined(LWS_WITH_CLIENT)
const char *
lws_wsi_client_stash_item(struct lws *wsi, int stash_idx, int hdr_idx)
@ -975,3 +976,216 @@ lws_wsi_client_stash_item(struct lws *wsi, int stash_idx, int hdr_idx)
return NULL;
#endif
}
#endif
#if defined(LWS_ROLE_H2)
void
lws_wsi_mux_insert(struct lws *wsi, struct lws *parent_wsi, int sid)
{
wsi->mux.my_sid = sid;
wsi->mux.parent_wsi = parent_wsi;
wsi->role_ops = parent_wsi->role_ops;
/* new guy's sibling is whoever was the first child before */
wsi->mux.sibling_list = parent_wsi->mux.child_list;
/* first child is now the new guy */
parent_wsi->mux.child_list = wsi;
parent_wsi->mux.child_count++;
}
struct lws *
lws_wsi_mux_from_id(struct lws *parent_wsi, unsigned int sid)
{
lws_start_foreach_ll(struct lws *, wsi, parent_wsi->mux.child_list) {
if (wsi->mux.my_sid == sid)
return wsi;
} lws_end_foreach_ll(wsi, mux.sibling_list);
return NULL;
}
void
lws_wsi_mux_dump_children(struct lws *wsi)
{
#if defined(_DEBUG)
if (!wsi->mux.parent_wsi || !lwsl_visible(LLL_INFO))
return;
lws_start_foreach_llp(struct lws **, w,
wsi->mux.parent_wsi->mux.child_list) {
lwsl_info(" \\---- child %s %p\n",
(*w)->role_ops ? (*w)->role_ops->name : "?", *w);
} lws_end_foreach_llp(w, mux.sibling_list);
#endif
}
void
lws_wsi_mux_close_children(struct lws *wsi, int reason)
{
struct lws *wsi2;
if (!wsi->mux.child_list)
return;
lws_start_foreach_llp(struct lws **, w, wsi->mux.child_list) {
lwsl_info(" closing child %p\n", *w);
/* disconnect from siblings */
wsi2 = (*w)->mux.sibling_list;
(*w)->mux.sibling_list = NULL;
(*w)->socket_is_permanently_unusable = 1;
__lws_close_free_wsi(*w, reason, "mux child recurse");
*w = wsi2;
continue;
} lws_end_foreach_llp(w, mux.sibling_list);
}
void
lws_wsi_mux_sibling_disconnect(struct lws *wsi)
{
struct lws *wsi2;
lws_start_foreach_llp(struct lws **, w,
wsi->mux.parent_wsi->mux.child_list) {
/* disconnect from siblings */
if (*w == wsi) {
wsi2 = (*w)->mux.sibling_list;
(*w)->mux.sibling_list = NULL;
*w = wsi2;
lwsl_debug(" %p disentangled from sibling %p\n",
wsi, wsi2);
break;
}
} lws_end_foreach_llp(w, mux.sibling_list);
wsi->mux.parent_wsi->mux.child_count--;
wsi->mux.parent_wsi = NULL;
}
void
lws_wsi_mux_dump_waiting_children(struct lws *wsi)
{
#if defined(_DEBUG)
lwsl_info("%s: %p: children waiting for POLLOUT service:\n",
__func__, wsi);
wsi = wsi->mux.child_list;
while (wsi) {
lwsl_info(" %c %p %s %s\n",
wsi->mux.requested_POLLOUT ? '*' : ' ',
wsi, wsi->role_ops->name, wsi->protocol ?
wsi->protocol->name : "noprotocol");
wsi = wsi->mux.sibling_list;
}
#endif
}
int
lws_wsi_mux_mark_parents_needing_writeable(struct lws *wsi)
{
struct lws *network_wsi = lws_get_network_wsi(wsi), *wsi2;
int already = network_wsi->mux.requested_POLLOUT;
/* mark everybody above him as requesting pollout */
wsi2 = wsi;
while (wsi2) {
wsi2->mux.requested_POLLOUT = 1;
lwsl_info("mark %p pending writable\n", wsi2);
wsi2 = wsi2->mux.parent_wsi;
}
return already;
}
struct lws *
lws_wsi_mux_move_child_to_tail(struct lws **wsi2)
{
struct lws *w = *wsi2;
while (w) {
if (!w->mux.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->mux.sibling_list = *wsi2;
/* guy pointing to us until now points to
* our old next */
*wsi2 = (*wsi2)->mux.sibling_list;
/* we point to nothing because we are last */
w->mux.sibling_list->mux.sibling_list = NULL;
/* w becomes us */
w = w->mux.sibling_list;
break;
}
w = w->mux.sibling_list;
}
/* clear the waiting for POLLOUT on the guy that was chosen */
if (w)
w->mux.requested_POLLOUT = 0;
return w;
}
int
lws_wsi_mux_action_pending_writeable_reqs(struct lws *wsi)
{
struct lws *w = wsi->mux.child_list;
while (w) {
if (w->mux.requested_POLLOUT) {
if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
return -1;
break;
}
w = w->mux.sibling_list;
}
return 0;
}
#if defined(LWS_WITH_CLIENT)
int
lws_wsi_mux_apply_queue(struct lws *wsi)
{
/* we have a transaction queue that wants to pipeline */
lws_vhost_lock(wsi->vhost);
lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
wsi->dll2_cli_txn_queue_owner.head) {
struct lws *w = lws_container_of(d, struct lws,
dll2_cli_txn_queue);
if (lwsi_role_http(wsi) &&
lwsi_state(w) == LRS_H1C_ISSUE_HANDSHAKE2) {
lwsl_info("%s: cli pipeq %p to be h2\n", __func__, w);
/* remove ourselves from client queue */
lws_dll2_remove(&w->dll2_cli_txn_queue);
/* attach ourselves as an h2 stream */
lws_wsi_h2_adopt(wsi, w);
}
} lws_end_foreach_dll_safe(d, d1);
lws_vhost_unlock(wsi->vhost);
return 0;
}
#endif
#endif

View file

@ -597,7 +597,7 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi)
WSI_TOKEN_HTTP_TRANSFER_ENCODING,
(unsigned char *)"chunked", 7, &p, end))
return 1;
if (!(wsi->http2_substream))
if (!(wsi->mux_substream))
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_CONNECTION,
(unsigned char *)"close", 5,
@ -615,7 +615,7 @@ lws_cgi_write_split_stdout_headers(struct lws *wsi)
* Let's redo them at headers_pos forward using the
* correct coding for http/1 or http/2
*/
if (!wsi->http2_substream)
if (!wsi->mux_substream)
goto post_hpack_recode;
p = wsi->http.cgi->headers_start;
@ -750,7 +750,7 @@ post_hpack_recode:
if (!wsi->http.cgi->headers_buf) {
/* if we don't already have a headers buf, cook one */
n = 2048;
if (wsi->http2_substream)
if (wsi->mux_substream)
n = 4096;
wsi->http.cgi->headers_buf = lws_malloc(n + LWS_PRE,
"cgi hdr buf");
@ -921,7 +921,7 @@ agin:
/* payload processing */
m = !wsi->http.cgi->implied_chunked && !wsi->http2_substream &&
m = !wsi->http.cgi->implied_chunked && !wsi->mux_substream &&
// !wsi->http.cgi->explicitly_chunked &&
!wsi->http.cgi->content_length;
n = lws_get_socket_fd(wsi->http.cgi->stdwsi[LWS_STDOUT]);
@ -936,7 +936,7 @@ agin:
if (n > 0) {
// lwsl_hexdump_notice(buf, n);
if (!wsi->http2_substream && m) {
if (!wsi->mux_substream && m) {
char chdr[LWS_HTTP_CHUNK_HDR_SIZE];
m = lws_snprintf(chdr, LWS_HTTP_CHUNK_HDR_SIZE - 3,
"%X\x0d\x0a", n);
@ -948,7 +948,7 @@ agin:
#if defined(LWS_WITH_HTTP2)
if (wsi->http2_substream) {
if (wsi->mux_substream) {
struct lws *nwsi = lws_get_network_wsi(wsi);
__lws_set_timeout(wsi,
@ -974,7 +974,7 @@ agin:
wsi->http.cgi->content_length_seen += n;
} else {
if (!wsi->http2_substream && m) {
if (!wsi->mux_substream && m) {
uint8_t term[LWS_PRE + 6];
lwsl_notice("%s: sent trailer\n", __func__);
@ -991,7 +991,7 @@ agin:
if (wsi->cgi_stdout_zero_length) {
lwsl_debug("%s: stdout is POLLHUP'd\n", __func__);
if (wsi->http2_substream)
if (wsi->mux_substream)
m = lws_write(wsi, (unsigned char *)start, 0,
LWS_WRITE_HTTP_FINAL);
else

View file

@ -212,7 +212,7 @@ postbody_completion:
if (n)
goto bail;
if (wsi->http2_substream)
if (wsi->mux_substream)
lwsi_set_state(wsi, LRS_ESTABLISHED);
}

View file

@ -1363,7 +1363,7 @@ int lws_add_http2_header_by_name(struct lws *wsi, const unsigned char *name,
if (name[len - 1] == ':')
len--;
if (wsi->http2_substream && !strncmp((const char *)name,
if (wsi->mux_substream && !strncmp((const char *)name,
"transfer-encoding", len)) {
lwsl_header("rejecting %s\n", name);

View file

@ -173,7 +173,7 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi,
}
/* no more children allowed by parent */
if (parent_wsi->h2.child_count + 1 >
if (parent_wsi->mux.child_count + 1 >
parent_wsi->h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) {
lwsl_notice("reached concurrent stream limit\n");
return NULL;
@ -185,19 +185,12 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi,
}
h2n->highest_sid_opened = sid;
wsi->h2.my_sid = sid;
wsi->http2_substream = 1;
lws_wsi_mux_insert(wsi, parent_wsi, sid);
wsi->mux_substream = 1;
wsi->seen_nonpseudoheader = 0;
wsi->h2.parent_wsi = parent_wsi;
wsi->role_ops = parent_wsi->role_ops;
/* new guy's sibling is whoever was the first child before */
wsi->h2.sibling_list = parent_wsi->h2.child_list;
/* first child is now the new guy */
parent_wsi->h2.child_list = wsi;
parent_wsi->h2.child_count++;
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->h2.set.s[H2SET_INITIAL_WINDOW_SIZE];
@ -225,8 +218,8 @@ lws_wsi_server_new(struct lws_vhost *vh, struct lws *parent_wsi,
bail1:
/* undo the insert */
parent_wsi->h2.child_list = wsi->h2.sibling_list;
parent_wsi->h2.child_count--;
parent_wsi->mux.child_list = wsi->mux.sibling_list;
parent_wsi->mux.child_count--;
vh->context->count_wsi_allocated--;
@ -245,7 +238,7 @@ lws_wsi_h2_adopt(struct lws *parent_wsi, struct lws *wsi)
struct lws *nwsi = lws_get_network_wsi(parent_wsi);
/* no more children allowed by parent */
if (parent_wsi->h2.child_count + 1 >
if (parent_wsi->mux.child_count + 1 >
parent_wsi->h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) {
lwsl_notice("reached concurrent stream limit\n");
return NULL;
@ -255,18 +248,12 @@ lws_wsi_h2_adopt(struct lws *parent_wsi, struct lws *wsi)
wsi->seen_nonpseudoheader = 0;
#if defined(LWS_WITH_CLIENT)
wsi->client_h2_substream = 1;
wsi->client_mux_substream = 1;
#endif
wsi->h2.initialized = 1;
wsi->h2.parent_wsi = parent_wsi;
/* new guy's sibling is whoever was the first child before */
wsi->h2.sibling_list = parent_wsi->h2.child_list;
/* first child is now the new guy */
parent_wsi->h2.child_list = wsi;
parent_wsi->h2.child_count++;
lws_wsi_mux_insert(wsi, parent_wsi, wsi->mux.my_sid);
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->h2.set.s[H2SET_INITIAL_WINDOW_SIZE];
@ -287,8 +274,8 @@ lws_wsi_h2_adopt(struct lws *parent_wsi, struct lws *wsi)
bail1:
/* undo the insert */
parent_wsi->h2.child_list = wsi->h2.sibling_list;
parent_wsi->h2.child_count--;
parent_wsi->mux.child_list = wsi->mux.sibling_list;
parent_wsi->mux.child_count--;
if (wsi->user_space)
lws_free_set_NULL(wsi->user_space);
@ -326,32 +313,6 @@ int lws_h2_issue_preface(struct lws *wsi)
return 0;
}
struct lws *
lws_h2_wsi_from_id(struct lws *parent_wsi, unsigned int 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, 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->h2.child_list) {
if (*w == wsi) {
*w = wsi->h2.sibling_list;
(wsi->h2.parent_wsi)->h2.child_count--;
return 0;
}
} lws_end_foreach_llp(w, h2.sibling_list);
lwsl_err("%s: can't find %p\n", __func__, wsi);
return 1;
}
void
lws_pps_schedule(struct lws *wsi, struct lws_h2_protocol_send *pps)
{
@ -408,9 +369,9 @@ lws_h2_rst_stream(struct lws *wsi, uint32_t err, const char *reason)
return 1;
lwsl_info("%s: RST_STREAM 0x%x, sid %d, REASON '%s'\n", __func__, (int)err,
wsi->h2.my_sid, reason);
wsi->mux.my_sid, reason);
pps->u.rs.sid = wsi->h2.my_sid;
pps->u.rs.sid = wsi->mux.my_sid;
pps->u.rs.err = err;
lws_pps_schedule(wsi, pps);
@ -486,7 +447,7 @@ lws_h2_settings(struct lws *wsi, struct http2_settings *settings,
*/
lws_start_foreach_ll(struct lws *, w,
nwsi->h2.child_list) {
nwsi->mux.child_list) {
lwsl_info("%s: adi child tc cr %d +%d -> %d",
__func__,
w->h2.tx_cr, b - (unsigned int)settings->s[a],
@ -496,7 +457,7 @@ lws_h2_settings(struct lws *wsi, struct http2_settings *settings,
w->h2.tx_cr <=
(int32_t)(b - settings->s[a]))
lws_callback_on_writable(w);
} lws_end_foreach_ll(w, h2.sibling_list);
} lws_end_foreach_ll(w, mux.sibling_list);
break;
case H2SET_MAX_FRAME_SIZE:
@ -553,7 +514,7 @@ lws_h2_tx_cr_get(struct lws *wsi)
int c = wsi->h2.tx_cr;
struct lws *nwsi = lws_get_network_wsi(wsi);
if (!wsi->http2_substream && !nwsi->upgraded_to_http2)
if (!wsi->mux_substream && !nwsi->upgraded_to_http2)
return ~0x80000000;
lwsl_info ("%s: %p: own tx credit %d: nwsi credit %d\n",
@ -794,7 +755,7 @@ int lws_h2_do_pps_send(struct lws *wsi)
lwsl_info("send %d %d\n", n, m);
goto bail;
}
cwsi = lws_h2_wsi_from_id(wsi, pps->u.rs.sid);
cwsi = lws_wsi_mux_from_id(wsi, pps->u.rs.sid);
if (cwsi) {
lwsl_debug("%s: closing cwsi %p %s %s (wsi %p)\n",
__func__, cwsi, cwsi->role_ops->name,
@ -870,7 +831,7 @@ lws_h2_parse_frame_header(struct lws *wsi)
wsi->vhost->keepalive_timeout : 31);
if (h2n->sid)
h2n->swsi = lws_h2_wsi_from_id(wsi, h2n->sid);
h2n->swsi = lws_wsi_mux_from_id(wsi, h2n->sid);
lwsl_debug("%p (%p): fr hdr: typ 0x%x, fla 0x%x, sid 0x%x, len 0x%x\n",
wsi, h2n->swsi, h2n->type, h2n->flags, (unsigned int)h2n->sid,
@ -1127,7 +1088,7 @@ lws_h2_parse_frame_header(struct lws *wsi)
#if defined(LWS_WITH_CLIENT)
if (wsi->client_h2_alpn) {
if (h2n->sid) {
h2n->swsi = lws_h2_wsi_from_id(wsi, h2n->sid);
h2n->swsi = lws_wsi_mux_from_id(wsi, h2n->sid);
lwsl_info("HEADERS: nwsi %p: sid %u mapped "
"to wsi %p\n", wsi,
(unsigned int)h2n->sid, h2n->swsi);
@ -1140,7 +1101,7 @@ lws_h2_parse_frame_header(struct lws *wsi)
if (!h2n->swsi) {
/* no more children allowed by parent */
if (wsi->h2.child_count + 1 >
if (wsi->mux.child_count + 1 >
wsi->h2.h2n->set.s[H2SET_MAX_CONCURRENT_STREAMS]) {
lws_h2_goaway(wsi, H2_ERR_PROTOCOL_ERROR,
"Another stream not allowed");
@ -1195,12 +1156,12 @@ 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->h2.child_list) {
if (w->h2.my_sid < h2n->sid &&
lws_start_foreach_ll(struct lws *, w, wsi->mux.child_list) {
if (w->mux.my_sid < h2n->sid &&
w->h2.h2_state == LWS_H2_STATE_IDLE)
lws_close_free_wsi(w, 0, "h2 sid close");
assert(w->h2.sibling_list != w);
} lws_end_foreach_ll(w, h2.sibling_list);
assert(w->mux.sibling_list != w);
} lws_end_foreach_ll(w, mux.sibling_list);
if (lws_check_opt(h2n->swsi->vhost->options,
LWS_SERVER_OPTION_VH_H2_HALF_CLOSED_LONG_POLL)) {
@ -1210,7 +1171,7 @@ lws_h2_parse_frame_header(struct lws *wsi)
* half-closed remote state, allowing immortal long
* poll
*/
lws_http_mark_immortal(h2n->swsi);
lws_mux_mark_immortal(h2n->swsi);
lwsl_info("%s: %p: h2 stream entering long poll\n",
__func__, h2n->swsi);
@ -1299,7 +1260,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
h2n->count = 0;
if (h2n->sid)
h2n->swsi = lws_h2_wsi_from_id(wsi, h2n->sid);
h2n->swsi = lws_wsi_mux_from_id(wsi, h2n->sid);
if (h2n->sid > h2n->highest_sid)
h2n->highest_sid = h2n->sid;
@ -1322,7 +1283,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
case LWS_H2_FRAME_TYPE_SETTINGS:
#if defined(LWS_WITH_CLIENT)
if (wsi->client_h2_alpn && !wsi->client_h2_migrated &&
if (wsi->client_h2_alpn && !wsi->client_mux_migrated &&
!(h2n->flags & LWS_H2_FLAG_SETTINGS_ACK)) {
struct lws_h2_protocol_send *pps;
@ -1331,7 +1292,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
wsi->http.fop_fd = NULL;
#endif
lwsl_info("%s: migrating\n", __func__);
wsi->client_h2_migrated = 1;
wsi->client_mux_migrated = 1;
/*
* we need to treat the headers from the upgrade as the
* first job. So these need to get shifted to sid 1.
@ -1341,7 +1302,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
return 1;
h2n->sid = 1;
assert(lws_h2_wsi_from_id(wsi, 1) == h2n->swsi);
assert(lws_wsi_mux_from_id(wsi, 1) == h2n->swsi);
lws_role_transition(wsi, LWSIFR_CLIENT,
LRS_H2_WAITING_TO_SEND_HEADERS,
@ -1353,7 +1314,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
/* pass on the initial headers to SID 1 */
h2n->swsi->http.ah = wsi->http.ah;
h2n->swsi->client_h2_substream = 1;
h2n->swsi->client_mux_substream = 1;
#if defined(LWS_WITH_CLIENT)
h2n->swsi->flags = wsi->flags;
#endif
@ -1383,39 +1344,20 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
lws_callback_on_writable(h2n->swsi);
if (!wsi->h2_acked_settings
#if defined(LWS_WITH_CLIENT)
|| !(wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM)
#endif
if (!wsi->h2_acked_settings ||
!(wsi->flags & LCCSCF_H2_QUIRK_NGHTTP2_END_STREAM)
) {
pps = lws_h2_new_pps(LWS_H2_PPS_ACK_SETTINGS);
if (!pps)
return 1;
lws_pps_schedule(wsi, pps);
lwsl_info("%s: scheduled settings ack PPS\n", __func__);
lwsl_info("%s: SETTINGS ack PPS\n", __func__);
wsi->h2_acked_settings = 1;
}
/* also attach any queued guys */
/* we have a transaction queue that wants to pipeline */
lws_vhost_lock(wsi->vhost);
lws_start_foreach_dll_safe(struct lws_dll2 *, d, d1,
wsi->dll2_cli_txn_queue_owner.head) {
struct lws *w = lws_container_of(d, struct lws,
dll2_cli_txn_queue);
if (lwsi_state(w) == LRS_H1C_ISSUE_HANDSHAKE2) {
lwsl_info("%s: cli pipeq %p to be h2\n",
__func__, w);
/* remove ourselves from client queue */
lws_dll2_remove(&w->dll2_cli_txn_queue);
/* attach ourselves as an h2 stream */
lws_wsi_h2_adopt(wsi, w);
}
} lws_end_foreach_dll_safe(d, d1);
lws_vhost_unlock(wsi->vhost);
lws_wsi_mux_apply_queue(wsi);
}
#endif
break;
@ -1468,7 +1410,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
h2n->swsi->hdr_parsing_completed = 1;
#if defined(LWS_WITH_CLIENT)
if (h2n->swsi->client_h2_substream) {
if (h2n->swsi->client_mux_substream) {
if (lws_client_interpret_server_handshake(h2n->swsi)) {
lwsl_info("%s: cli int serv hs closed it\n", __func__);
break;
@ -1538,7 +1480,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
}
#if defined(LWS_WITH_CLIENT)
if (h2n->swsi->client_h2_substream) {
if (h2n->swsi->client_mux_substream) {
lwsl_info("%s: headers: client path\n", __func__);
break;
}
@ -1622,7 +1564,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
* send anything else anyway.
*/
if (h2n->swsi->client_h2_substream &&
if (h2n->swsi->client_mux_substream &&
(h2n->flags & LWS_H2_FLAG_END_STREAM)) {
lwsl_info("%s: %p: DATA: end stream\n",
__func__, h2n->swsi);
@ -1719,9 +1661,9 @@ 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->h2.child_list) {
lws_start_foreach_ll(struct lws *, w, wsi->mux.child_list) {
lws_callback_on_writable(w);
} lws_end_foreach_ll(w, h2.sibling_list);
} lws_end_foreach_ll(w, mux.sibling_list);
if (eff_wsi->h2.skint && lws_h2_tx_cr_get(eff_wsi)) {
lwsl_info("%s: %p: skint\n", __func__, wsi);
@ -1974,7 +1916,7 @@ lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen,
lwsl_debug("---- restricting len to %d vs %ld\n", n, (long)inlen + 1);
}
#if defined(LWS_WITH_CLIENT)
if (h2n->swsi->client_h2_substream) {
if (h2n->swsi->client_mux_substream) {
if (!h2n->swsi->protocol) {
lwsl_err("%s: swsi %pdoesn't have protocol\n", __func__, h2n->swsi);
m = 1;
@ -2245,10 +2187,10 @@ lws_h2_client_handshake(struct lws *wsi)
int sid = nwsi->h2.h2n->highest_sid_opened + 2;
nwsi->h2.h2n->highest_sid_opened = sid;
wsi->h2.my_sid = sid;
wsi->mux.my_sid = sid;
lwsl_info("%s: CLIENT_WAITING_TO_SEND_HEADERS: pollout (sid %d)\n",
__func__, wsi->h2.my_sid);
__func__, wsi->mux.my_sid);
pps = lws_h2_new_pps(LWS_H2_PPS_UPDATE_WINDOW);
if (!pps)
@ -2526,7 +2468,7 @@ int
lws_h2_client_stream_long_poll_rxonly(struct lws *wsi)
{
if (!wsi->http2_substream)
if (!wsi->mux_substream)
return 1;
/*

View file

@ -164,7 +164,7 @@ rops_handle_POLLIN_h2(struct lws_context_per_thread *pt, struct lws *wsi,
#endif
}
if (wsi->http2_substream || wsi->upgraded_to_http2) {
if (wsi->mux_substream || wsi->upgraded_to_http2) {
wsi1 = lws_get_network_wsi(wsi);
if (wsi1 && lws_has_buffered_out(wsi1))
/*
@ -386,7 +386,7 @@ rops_write_role_protocol_h2(struct lws *wsi, unsigned char *buf, size_t len,
/* if not in a state to send stuff, then just send nothing */
if (!lwsi_role_ws(wsi) && !wsi->h2_stream_immortal &&
if (!lwsi_role_ws(wsi) && !wsi->mux_stream_immortal &&
base != LWS_WRITE_HTTP &&
base != LWS_WRITE_HTTP_FINAL &&
base != LWS_WRITE_HTTP_HEADERS_CONTINUATION &&
@ -477,7 +477,7 @@ rops_write_role_protocol_h2(struct lws *wsi, unsigned char *buf, size_t len,
wsi->h2.send_END_STREAM = 1;
}
n = lws_h2_frame_write(wsi, n, flags, wsi->h2.my_sid, (int)len, buf);
n = lws_h2_frame_write(wsi, n, flags, wsi->mux.my_sid, (int)len, buf);
if (n < 0)
return n;
@ -500,7 +500,7 @@ rops_check_upgrades_h2(struct lws *wsi)
*/
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
if (!wsi->vhost->h2.set.s[H2SET_ENABLE_CONNECT_PROTOCOL] ||
!wsi->http2_substream || !p || strcmp(p, "CONNECT"))
!wsi->mux_substream || !p || strcmp(p, "CONNECT"))
return LWS_UPG_RET_CONTINUE;
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_COLON_PROTOCOL);
@ -511,7 +511,7 @@ rops_check_upgrades_h2(struct lws *wsi)
wsi->vhost->conn_stats.ws_upg++;
#endif
lwsl_info("Upgrade h2 to ws\n");
lws_http_mark_immortal(wsi);
lws_mux_mark_immortal(wsi);
wsi->h2_stream_carries_ws = 1;
if (lws_process_ws_upgrade(wsi))
@ -599,7 +599,7 @@ rops_destroy_role_h2(struct lws *wsi)
lws_http_compression_destroy(wsi);
#endif
if (wsi->upgraded_to_http2 || wsi->http2_substream) {
if (wsi->upgraded_to_http2 || wsi->mux_substream) {
lws_hpack_destroy_dynamic_header(wsi);
if (wsi->h2.h2n)
@ -612,7 +612,6 @@ rops_destroy_role_h2(struct lws *wsi)
static int
rops_close_kill_connection_h2(struct lws *wsi, enum lws_close_status reason)
{
struct lws *wsi2;
#if defined(LWS_WITH_HTTP_PROXY)
if (wsi->http.proxy_clientside) {
@ -628,53 +627,28 @@ rops_close_kill_connection_h2(struct lws *wsi, enum lws_close_status reason)
}
#endif
if (wsi->http2_substream && wsi->h2_stream_carries_ws)
if (wsi->mux_substream && wsi->h2_stream_carries_ws)
lws_h2_rst_stream(wsi, 0, "none");
/* else
if (wsi->http2_substream)
if (wsi->mux_substream)
lws_h2_rst_stream(wsi, H2_ERR_STREAM_CLOSED, "swsi got closed");
*/
if (wsi->h2.parent_wsi && lwsl_visible(LLL_INFO)) {
lwsl_info(" wsi: %p, his parent %p: siblings:\n", wsi,
wsi->h2.parent_wsi);
lws_start_foreach_llp(struct lws **, w,
wsi->h2.parent_wsi->h2.child_list) {
lwsl_info(" \\---- child %s %p\n",
(*w)->role_ops ? (*w)->role_ops->name : "?", *w);
} lws_end_foreach_llp(w, h2.sibling_list);
}
lwsl_info(" wsi: %p, his parent %p: siblings:\n", wsi, wsi->mux.parent_wsi);
lws_wsi_mux_dump_children(wsi);
if (wsi->upgraded_to_http2 || wsi->http2_substream
if (wsi->upgraded_to_http2 || wsi->mux_substream
#if defined(LWS_WITH_CLIENT)
|| wsi->client_h2_substream
|| wsi->client_mux_substream
#endif
) {
lwsl_info("closing %p: parent %p\n", wsi, wsi->h2.parent_wsi);
lwsl_info("closing %p: parent %p\n", wsi, wsi->mux.parent_wsi);
if (wsi->h2.child_list && lwsl_visible(LLL_INFO)) {
if (wsi->mux.child_list && lwsl_visible(LLL_INFO)) {
lwsl_info(" parent %p: closing children: list:\n", wsi);
lws_start_foreach_llp(struct lws **, w,
wsi->h2.child_list) {
lwsl_info(" \\---- child %s %p\n",
(*w)->role_ops ? (*w)->role_ops->name : "?",
*w);
} lws_end_foreach_llp(w, h2.sibling_list);
}
if (wsi->h2.child_list) {
/* trigger closing of all of our http2 children first */
lws_start_foreach_llp(struct lws **, w,
wsi->h2.child_list) {
lwsl_info(" closing child %p\n", *w);
/* disconnect from siblings */
wsi2 = (*w)->h2.sibling_list;
(*w)->h2.sibling_list = NULL;
(*w)->socket_is_permanently_unusable = 1;
__lws_close_free_wsi(*w, reason, "h2 child recurse");
*w = wsi2;
continue;
} lws_end_foreach_llp(w, h2.sibling_list);
lws_wsi_mux_dump_children(wsi);
}
lws_wsi_mux_close_children(wsi, reason);
}
if (wsi->upgraded_to_http2) {
@ -691,25 +665,11 @@ rops_close_kill_connection_h2(struct lws *wsi, enum lws_close_status reason)
if ((
#if defined(LWS_WITH_CLIENT)
wsi->client_h2_substream ||
wsi->client_mux_substream ||
#endif
wsi->http2_substream) &&
wsi->h2.parent_wsi) {
lws_start_foreach_llp(struct lws **, w,
wsi->h2.parent_wsi->h2.child_list) {
/* disconnect from siblings */
if (*w == wsi) {
wsi2 = (*w)->h2.sibling_list;
(*w)->h2.sibling_list = NULL;
*w = wsi2;
lwsl_debug(" %p disentangled from sibling %p\n",
wsi, wsi2);
break;
}
} lws_end_foreach_llp(w, h2.sibling_list);
wsi->h2.parent_wsi->h2.child_count--;
wsi->h2.parent_wsi = NULL;
wsi->mux_substream) &&
wsi->mux.parent_wsi) {
lws_wsi_mux_sibling_disconnect(wsi);
if (wsi->h2.pending_status_body)
lws_free_set_NULL(wsi->h2.pending_status_body);
}
@ -720,7 +680,9 @@ rops_close_kill_connection_h2(struct lws *wsi, enum lws_close_status reason)
static int
rops_callback_on_writable_h2(struct lws *wsi)
{
struct lws *network_wsi, *wsi2;
#if defined(LWS_WITH_CLIENT)
struct lws *network_wsi;
#endif
int already;
//lwsl_notice("%s: %p (wsistate 0x%x)\n", __func__, wsi, wsi->wsistate);
@ -728,7 +690,7 @@ rops_callback_on_writable_h2(struct lws *wsi)
// if (!lwsi_role_h2(wsi) && !lwsi_role_h2_ENCAPSULATION(wsi))
// return 0;
if (wsi->h2.requested_POLLOUT
if (wsi->mux.requested_POLLOUT
#if defined(LWS_WITH_CLIENT)
&& !wsi->client_h2_alpn
#endif
@ -755,24 +717,17 @@ rops_callback_on_writable_h2(struct lws *wsi)
}
wsi->h2.skint = 0;
#if defined(LWS_WITH_CLIENT)
network_wsi = lws_get_network_wsi(wsi);
already = network_wsi->h2.requested_POLLOUT;
/* mark everybody above him as requesting pollout */
wsi2 = wsi;
while (wsi2) {
wsi2->h2.requested_POLLOUT = 1;
lwsl_info("mark %p pending writable\n", wsi2);
wsi2 = wsi2->h2.parent_wsi;
}
#endif
already = lws_wsi_mux_mark_parents_needing_writeable(wsi);
/* for network action, act only on the network wsi */
if (already
#if defined(LWS_WITH_CLIENT)
&& !network_wsi->client_h2_alpn
&& !network_wsi->client_h2_substream
&& !network_wsi->client_mux_substream
#endif
)
return 1;
@ -780,25 +735,6 @@ rops_callback_on_writable_h2(struct lws *wsi)
return 0;
}
static void
lws_h2_dump_waiting_children(struct lws *wsi)
{
#if defined(_DEBUG)
lwsl_info("%s: %p: children waiting for POLLOUT service:\n",
__func__, wsi);
wsi = wsi->h2.child_list;
while (wsi) {
lwsl_info(" %c %p %s %s\n",
wsi->h2.requested_POLLOUT ? '*' : ' ',
wsi, wsi->role_ops->name, wsi->protocol ?
wsi->protocol->name : "noprotocol");
wsi = wsi->h2.sibling_list;
}
#endif
}
#if defined(LWS_WITH_SERVER)
static int
lws_h2_bind_for_post_before_action(struct lws *wsi)
@ -859,7 +795,7 @@ lws_h2_bind_for_post_before_action(struct lws *wsi)
static int
rops_perform_user_POLLOUT_h2(struct lws *wsi)
{
struct lws **wsi2, *wsi2a;
struct lws **wsi2;
#if defined(LWS_ROLE_WS)
int write_type = LWS_WRITE_PONG;
#endif
@ -867,23 +803,23 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
wsi = lws_get_network_wsi(wsi);
wsi->h2.requested_POLLOUT = 0;
wsi->mux.requested_POLLOUT = 0;
if (!wsi->h2.initialized) {
lwsl_info("pollout on uninitialized http2 conn\n");
return 0;
}
lws_h2_dump_waiting_children(wsi);
lws_wsi_mux_dump_waiting_children(wsi);
wsi2 = &wsi->h2.child_list;
wsi2 = &wsi->mux.child_list;
if (!*wsi2)
return 0;
do {
struct lws *w, **wa;
wa = &(*wsi2)->h2.sibling_list;
if (!(*wsi2)->h2.requested_POLLOUT)
wa = &(*wsi2)->mux.sibling_list;
if (!(*wsi2)->mux.requested_POLLOUT)
goto next_child;
/*
@ -893,32 +829,13 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lwsl_debug("servicing child %p\n", *wsi2);
w = *wsi2;
while (w) {
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->h2.sibling_list = *wsi2;
/* guy pointing to us until now points to
* our old next */
*wsi2 = (*wsi2)->h2.sibling_list;
/* we point to nothing because we are last */
w->h2.sibling_list->h2.sibling_list = NULL;
/* w becomes us */
w = w->h2.sibling_list;
break;
}
w = w->h2.sibling_list;
}
w = lws_wsi_mux_move_child_to_tail(wsi2);
if (!w) {
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
w->h2.requested_POLLOUT = 0;
lwsl_info("%s: child %p (wsistate 0x%x)\n", __func__, w,
(unsigned int)w->wsistate);
@ -930,11 +847,11 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lwsl_info("%s signalling to close\n", __func__);
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"h2 end stream 1");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
lws_callback_on_writable(w);
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
@ -956,7 +873,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
"comp write fail");
}
lws_callback_on_writable(w);
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
#endif
@ -967,7 +884,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
w->socket_is_permanently_unusable = 1;
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"h2 end stream 1");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
@ -984,7 +901,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lws_free_set_NULL(w->h2.pending_status_body);
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"h2 end stream 1");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
@ -1031,11 +948,11 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lwsl_info("closing stream after h2 action\n");
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"h2 end stream");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
}
if (n < 0)
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
@ -1063,7 +980,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lwsl_debug("Closing POLLOUT child %p\n", w);
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"h2 end stream file");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
if (n > 0)
@ -1071,7 +988,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
return -1;
if (!n) {
lws_callback_on_writable(w);
(w)->h2.requested_POLLOUT = 1;
(w)->mux.requested_POLLOUT = 1;
}
goto next_child;
@ -1126,12 +1043,12 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
lwsi_set_state(w, LRS_RETURNED_CLOSE);
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"returned close packet");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
goto next_child;
}
lws_callback_on_writable(w);
(w)->h2.requested_POLLOUT = 1;
(w)->mux.requested_POLLOUT = 1;
/* otherwise for PING, leave POLLOUT active both ways */
goto next_child;
@ -1154,7 +1071,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
&wp)) {
lwsl_info("%s: wsi %p: entering ro long poll\n",
__func__, w);
lws_http_mark_immortal(w);
lws_mux_mark_immortal(w);
} else
lwsl_err("%s: wsi %p: failed to set long poll\n",
__func__, w);
@ -1166,7 +1083,7 @@ rops_perform_user_POLLOUT_h2(struct lws *wsi)
w->h2.send_END_STREAM);
lws_close_free_wsi(w, LWS_CLOSE_STATUS_NOSTATUS,
"h2 pollout handle");
wa = &wsi->h2.child_list;
wa = &wsi->mux.child_list;
} else
if (w->h2.send_END_STREAM)
lws_h2_state(w, LWS_H2_STATE_HALF_CLOSED_LOCAL);
@ -1175,17 +1092,10 @@ next_child:
wsi2 = wa;
} while (wsi2 && *wsi2 && !lws_send_pipe_choked(wsi));
// lws_h2_dump_waiting_children(wsi);
// lws_wsi_mux_dump_waiting_children(wsi);
wsi2a = wsi->h2.child_list;
while (wsi2a) {
if (wsi2a->h2.requested_POLLOUT) {
if (lws_change_pollfd(wsi, 0, LWS_POLLOUT))
return -1;
break;
}
wsi2a = wsi2a->h2.sibling_list;
}
if (lws_wsi_mux_action_pending_writeable_reqs(wsi))
return -1;
return 0;
}
@ -1193,8 +1103,8 @@ next_child:
static struct lws *
rops_encapsulation_parent_h2(struct lws *wsi)
{
if (wsi->h2.parent_wsi)
return wsi->h2.parent_wsi;
if (wsi->mux.parent_wsi)
return wsi->mux.parent_wsi;
return NULL;
}

View file

@ -315,37 +315,25 @@ struct lws_h2_netconn {
struct _lws_h2_related {
struct lws_h2_netconn *h2n; /* malloc'd for root net conn */
struct lws *parent_wsi;
struct lws *child_list;
struct lws *sibling_list;
struct lws_h2_netconn *h2n; /* malloc'd for root net conn */
char *pending_status_body;
char *pending_status_body;
int tx_cr;
int peer_tx_cr_est;
unsigned int my_sid;
unsigned int child_count;
int my_priority;
uint32_t dependent_on;
int tx_cr;
int peer_tx_cr_est;
uint16_t END_STREAM:1;
uint16_t END_HEADERS:1;
uint16_t send_END_STREAM:1;
uint16_t long_poll:1;
uint16_t GOING_AWAY;
uint16_t requested_POLLOUT:1;
uint16_t skint:1;
uint8_t END_STREAM:1;
uint8_t END_HEADERS:1;
uint8_t send_END_STREAM:1;
uint8_t long_poll:1;
uint8_t GOING_AWAY;
uint8_t skint:1;
uint8_t initialized:1;
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;
uint8_t h2_state; /* RFC7540 state of the connection */
};
#define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->h2.parent_wsi)
#define HTTP2_IS_TOPLEVEL_WSI(wsi) (!wsi->mux.parent_wsi)
int
lws_h2_rst_stream(struct lws *wsi, uint32_t err, const char *reason);
@ -363,7 +351,7 @@ LWS_EXTERN int
lws_h2_frame_write(struct lws *wsi, int type, int flags, unsigned int sid,
unsigned int len, unsigned char *buf);
LWS_EXTERN struct lws *
lws_h2_wsi_from_id(struct lws *wsi, unsigned int sid);
lws_wsi_mux_from_id(struct lws *wsi, unsigned int sid);
LWS_EXTERN int
lws_hpack_interpret(struct lws *wsi, unsigned char c);
LWS_EXTERN int

View file

@ -1099,7 +1099,7 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port,
lws_free_set_NULL(stash);
#if defined(LWS_WITH_HTTP2)
if (wsi->client_h2_substream)
if (wsi->client_mux_substream)
wsi->h2.END_STREAM = wsi->h2.END_HEADERS = 0;
#endif

View file

@ -642,7 +642,7 @@ lws_http_transaction_completed_client(struct lws *wsi)
n = _lws_generic_transaction_completed_active_conn(wsi);
if (wsi->http.ah) {
if (wsi->client_h2_substream)
if (wsi->client_mux_substream)
/*
* As an h2 client, once we did our transaction, that is
* it for us. Further transactions will happen as new
@ -729,7 +729,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
/* we are being an http client...
*/
#if defined(LWS_ROLE_H2)
if (wsi->client_h2_alpn || wsi->client_h2_substream) {
if (wsi->client_h2_alpn || wsi->client_mux_substream) {
lwsl_debug("%s: %p: transitioning to h2 client\n",
__func__, wsi);
lws_role_transition(wsi, LWSIFR_CLIENT,
@ -767,7 +767,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
*/
wsi->http.conn_type = HTTP_CONNECTION_KEEP_ALIVE;
if (!wsi->client_h2_substream) {
if (!wsi->client_mux_substream) {
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP);
if (wsi->do_ws && !p) {
lwsl_info("no URI\n");
@ -910,7 +910,7 @@ lws_client_interpret_server_handshake(struct lws *wsi)
/* if h1 KA is allowed, enable the queued pipeline guys */
if (!wsi->client_h2_alpn && !wsi->client_h2_substream &&
if (!wsi->client_h2_alpn && !wsi->client_mux_substream &&
w == wsi) { /* ie, coming to this for the first time */
if (wsi->http.conn_type == HTTP_CONNECTION_KEEP_ALIVE)
wsi->keepalive_active = 1;

View file

@ -186,7 +186,7 @@ lws_add_http_common_headers(struct lws *wsi, unsigned int code,
/* there was no length... it normally means CONNECTION_CLOSE */
#if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
if (!wsi->http2_substream && wsi->http.lcs) {
if (!wsi->mux_substream && wsi->http.lcs) {
/* so...
* - h1 connection
* - http compression transform active
@ -208,7 +208,7 @@ lws_add_http_common_headers(struct lws *wsi, unsigned int code,
t = 1;
}
#endif
if (!wsi->http2_substream) {
if (!wsi->mux_substream) {
if (lws_add_http_header_by_token(wsi,
WSI_TOKEN_CONNECTION,
(unsigned char *)ka[t],
@ -437,7 +437,7 @@ lws_return_http_status(struct lws *wsi, unsigned int code,
return 1;
#if defined(LWS_WITH_HTTP2)
if (wsi->http2_substream) {
if (wsi->mux_substream) {
/*
* for HTTP/2, the headers must be sent separately, since they

View file

@ -575,7 +575,7 @@ lws_hdr_custom_length(struct lws *wsi, const char *name, int nlen)
{
ah_data_idx_t ll;
if (!wsi->http.ah || wsi->http2_substream)
if (!wsi->http.ah || wsi->mux_substream)
return -1;
ll = wsi->http.ah->unk_ll_head;
@ -601,7 +601,7 @@ lws_hdr_custom_copy(struct lws *wsi, char *dst, int len, const char *name,
ah_data_idx_t ll;
int n;
if (!wsi->http.ah || wsi->http2_substream)
if (!wsi->http.ah || wsi->mux_substream)
return -1;
*dst = '\0';
@ -1085,7 +1085,7 @@ swallow:
* a known header, we'll snip this.
*/
if (!wsi->http2_substream && !ah->unk_pos) {
if (!wsi->mux_substream && !ah->unk_pos) {
ah->unk_pos = ah->pos;
/*
* Prepare new unknown header linked-list entry
@ -1107,7 +1107,7 @@ swallow:
pos = ah->lextable_pos;
#if defined(LWS_WITH_CUSTOM_HEADERS)
if (!wsi->http2_substream && pos < 0 && c == ':') {
if (!wsi->mux_substream && pos < 0 && c == ':') {
#if defined(_DEBUG)
char dotstar[64];
int uhlen;
@ -1181,7 +1181,7 @@ nope:
/* b7 = 0, end or 3-byte */
if (lextable[pos] < FAIL_CHAR) {
#if defined(LWS_WITH_CUSTOM_HEADERS)
if (!wsi->http2_substream) {
if (!wsi->mux_substream) {
/*
* We hit a terminal marker, so
* we recognized this header...
@ -1227,7 +1227,7 @@ nope:
#if !defined(LWS_WITH_CUSTOM_HEADERS)
ah->parser_state = WSI_TOKEN_SKIPPING;
#endif
if (wsi->http2_substream)
if (wsi->mux_substream)
ah->parser_state = WSI_TOKEN_SKIPPING;
break;
}
@ -1238,7 +1238,7 @@ nope:
* We have the method, this is just an
* unknown header then
*/
if (!wsi->http2_substream)
if (!wsi->mux_substream)
goto unknown_hdr;
else
break;
@ -1266,7 +1266,7 @@ nope:
}
if (ah->lextable_pos < 0) {
#if defined(LWS_WITH_CUSTOM_HEADERS)
if (!wsi->http2_substream)
if (!wsi->mux_substream)
goto unknown_hdr;
#endif
/*
@ -1321,7 +1321,7 @@ nope:
unknown_hdr:
//ah->parser_state = WSI_TOKEN_SKIPPING;
//break;
if (!wsi->http2_substream)
if (!wsi->mux_substream)
break;
#endif

View file

@ -70,7 +70,7 @@ lws_prepare_access_log_info(struct lws *wsi, char *uri_ptr, int uri_len, int met
else
strcpy(da, "01/Jan/1970:00:00:00 +0000");
if (wsi->http2_substream)
if (wsi->mux_substream)
me = lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_COLON_METHOD);
else
me = method_names[meth];

View file

@ -697,7 +697,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin,
if (n > (int)strlen(pvo->name) &&
!strcmp(&path[n - strlen(pvo->name)], pvo->name)) {
wsi->interpreting = 1;
if (!wsi->http2_substream)
if (!wsi->mux_substream)
wsi->sending_chunked = 1;
wsi->protocol_interpret_idx = (char)(
@ -777,7 +777,7 @@ lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len)
lws_hdr_total_length(wsi, WSI_TOKEN_GET_URI) ||
lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI) ||
lws_hdr_total_length(wsi, WSI_TOKEN_HEAD_URI) ||
(wsi->http2_substream &&
(wsi->mux_substream &&
lws_hdr_total_length(wsi,
WSI_TOKEN_HTTP_COLON_PATH)) ||
hm->protocol) &&
@ -930,7 +930,7 @@ lws_http_get_uri_and_method(struct lws *wsi, char **puri_ptr, int *puri_len)
}
if (count != 1 &&
!((wsi->http2_substream || wsi->h2_stream_carries_ws) &&
!((wsi->mux_substream || wsi->h2_stream_carries_ws) &&
lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_COLON_PATH))) {
lwsl_warn("multiple methods?\n");
return -1;
@ -1311,7 +1311,7 @@ lws_http_action(struct lws *wsi)
}
}
if (wsi->http2_substream) {
if (wsi->mux_substream) {
wsi->http.request_version = HTTP_VERSION_2;
} else {
/* http_version? Default to 1.0, override with token: */
@ -1359,7 +1359,7 @@ lws_http_action(struct lws *wsi)
* if there is content supposed to be coming,
* put a timeout on it having arrived
*/
if (!wsi->h2_stream_immortal)
if (!wsi->mux_stream_immortal)
lws_set_timeout(wsi, PENDING_TIMEOUT_HTTP_CONTENT,
wsi->context->timeout_secs);
#ifdef LWS_WITH_TLS
@ -1659,7 +1659,7 @@ deal_body:
/* Prepare to read body if we have a 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);
wsi->upgraded_to_http2, wsi->mux_substream);
if (wsi->http.content_length_explicitly_zero &&
lws_hdr_total_length(wsi, WSI_TOKEN_POST_URI)) {
@ -2265,7 +2265,7 @@ lws_http_transaction_completed(struct lws *wsi)
#endif
/* if we can't go back to accept new headers, drop the connection */
if (wsi->http2_substream)
if (wsi->mux_substream)
return 1;
if (wsi->seen_zero_length_recv)
@ -2414,7 +2414,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
if (lws_return_http_status(wsi, HTTP_STATUS_NOT_FOUND,
NULL))
return -1;
return !wsi->http2_substream;
return !wsi->mux_substream;
}
}
@ -2558,7 +2558,7 @@ lws_serve_http_file(struct lws *wsi, const char *file, const char *content_type,
goto bail;
#endif
if (!wsi->http2_substream) {
if (!wsi->mux_substream) {
/* for http/1.1 ... */
if (!wsi->sending_chunked
#if defined(LWS_WITH_HTTP_STREAM_COMPRESSION)
@ -2686,7 +2686,7 @@ LWS_VISIBLE int lws_serve_http_file_fragment(struct lws *wsi)
#endif
int n, m;
lwsl_debug("wsi->http2_substream %d\n", wsi->http2_substream);
lwsl_debug("wsi->mux_substream %d\n", wsi->mux_substream);
do {
@ -2924,7 +2924,7 @@ all_sent:
* state, not the root connection at the
* network level
*/
if (wsi->http2_substream)
if (wsi->mux_substream)
return 1;
else
return -1;

View file

@ -257,7 +257,7 @@ lws_client_ws_upgrade(struct lws *wsi, const char **cce)
wsi->detlat.earliest_write_req_pre_write = 0;
#endif
if (wsi->client_h2_substream) {/* !!! client ws-over-h2 not there yet */
if (wsi->client_mux_substream) {/* !!! client ws-over-h2 not there yet */
lwsl_warn("%s: client ws-over-h2 upgrade not supported yet\n",
__func__);
*cce = "HS: h2 / ws upgrade unsupported";

View file

@ -1052,7 +1052,7 @@ rops_handle_POLLIN_ws(struct lws_context_per_thread *pt, struct lws *wsi,
return LWS_HPI_RET_HANDLED;
#if defined(LWS_WITH_HTTP2)
if (wsi->http2_substream || wsi->upgraded_to_http2) {
if (wsi->mux_substream || wsi->upgraded_to_http2) {
wsi1 = lws_get_network_wsi(wsi);
if (wsi1 && lws_has_buffered_out(wsi1))
/* We cannot deal with any kind of new RX
@ -1329,7 +1329,7 @@ int rops_handle_POLLOUT_ws(struct lws *wsi)
lwsl_info("%s: issuing ping on wsi %p: %s %s h2: %d\n", __func__, wsi,
wsi->role_ops->name, wsi->protocol->name,
wsi->http2_substream);
wsi->mux_substream);
wsi->ws->send_check_ping = 0;
n = lws_write(wsi, &wsi->ws->ping_payload_buf[LWS_PRE],
0, LWS_WRITE_PING);
@ -1914,7 +1914,7 @@ rops_close_kill_connection_ws(struct lws *wsi, enum lws_close_status reason)
{
/* deal with ws encapsulation in h2 */
#if defined(LWS_WITH_HTTP2)
if (wsi->http2_substream && wsi->h2_stream_carries_ws)
if (wsi->mux_substream && wsi->h2_stream_carries_ws)
return role_ops_h2.close_kill_connection(wsi, reason);
return 0;

View file

@ -420,7 +420,7 @@ lws_process_ws_upgrade(struct lws *wsi)
*/
#if defined(LWS_WITH_HTTP2)
if (!wsi->http2_substream) {
if (!wsi->mux_substream) {
#endif
lws_tokenize_init(&ts, buf, LWS_TOKENIZE_F_COMMA_SEP_LIST |

View file

@ -57,7 +57,7 @@ dotest() {
T=$3
(
{
/usr/bin/time -p /usr/bin/valgrind $1/lws-$MYTEST $4 $5 $6 $7 $8 $9 > $2/$MYTEST/$T.log 2> $2/$MYTEST/$T.log ;
/usr/bin/time -p /usr/bin/valgrind -q $1/lws-$MYTEST $4 $5 $6 $7 $8 $9 > $2/$MYTEST/$T.log 2> $2/$MYTEST/$T.log ;
echo $? > $2/$MYTEST/$T.result
} 2> $2/$MYTEST/$T.time >/dev/null
) >/dev/null 2> /dev/null &