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:
parent
1eb4d335d2
commit
7221bc57b5
23 changed files with 551 additions and 452 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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__);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -212,7 +212,7 @@ postbody_completion:
|
|||
if (n)
|
||||
goto bail;
|
||||
|
||||
if (wsi->http2_substream)
|
||||
if (wsi->mux_substream)
|
||||
lwsi_set_state(wsi, LRS_ESTABLISHED);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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 &
|
||||
|
|
Loading…
Add table
Reference in a new issue