diff --git a/CMakeLists.txt b/CMakeLists.txt index b545af316..79223f4a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ set(LWS_WITH_BUNDLED_ZLIB_DEFAULT OFF) if(WIN32) set(LWS_WITH_BUNDLED_ZLIB_DEFAULT ON) endif() -set(LWS_ROLE_H1 1) + set(LWS_ROLE_RAW 1) # @@ -20,6 +20,7 @@ option(LWS_WITH_DISTRO_RECOMMENDED "Enable features recommended for distro packa # # Major individual features # +option(LWS_ROLE_H1 "Compile with support for http/1 (needed for ws)" ON) option(LWS_ROLE_WS "Compile with support for websockets" ON) option(LWS_WITH_HTTP2 "Compile with server support for HTTP/2" OFF) option(LWS_WITH_LWSWS "Libwebsockets Webserver" OFF) diff --git a/lib/context.c b/lib/context.c index ad79b28d5..6ae802951 100644 --- a/lib/context.c +++ b/lib/context.c @@ -560,7 +560,9 @@ lws_create_vhost(struct lws_context *context, else vh->name = info->vhost_name; - vh->error_document_404 = info->error_document_404; +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + vh->http.error_document_404 = info->error_document_404; +#endif if (info->options & LWS_SERVER_OPTION_ONLY_RAW) lwsl_info("%s set to only support RAW\n", vh->name); @@ -684,8 +686,9 @@ lws_create_vhost(struct lws_context *context, vh->same_vh_protocol_list = (struct lws **) lws_zalloc(sizeof(struct lws *) * vh->count_protocols, "same vh list"); - - vh->mount_list = info->mounts; +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + vh->http.mount_list = info->mounts; +#endif #ifdef LWS_WITH_UNIX_SOCK if (LWS_UNIX_SOCK_ENABLED(context)) { @@ -736,22 +739,26 @@ lws_create_vhost(struct lws_context *context, } vh->listen_port = info->port; - vh->http_proxy_port = 0; - vh->http_proxy_address[0] = '\0'; +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + vh->http.http_proxy_port = 0; + vh->http.http_proxy_address[0] = '\0'; +#endif #if defined(LWS_WITH_SOCKS5) vh->socks_proxy_port = 0; vh->socks_proxy_address[0] = '\0'; #endif /* either use proxy from info, or try get it from env var */ - +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) /* http proxy */ if (info->http_proxy_address) { /* override for backwards compatibility */ if (info->http_proxy_port) - vh->http_proxy_port = info->http_proxy_port; + vh->http.http_proxy_port = info->http_proxy_port; lws_set_proxy(vh, info->http_proxy_address); - } else { + } else +#endif + { #ifdef LWS_HAVE_GETENV p = getenv("http_proxy"); if (p) @@ -1143,8 +1150,8 @@ lws_create_context(const struct lws_context_creation_info *info) context->pt[n].context = context; #endif context->pt[n].tid = n; - context->pt[n].ah_list = NULL; - context->pt[n].ah_pool_length = 0; + context->pt[n].http.ah_list = NULL; + context->pt[n].http.ah_pool_length = 0; lws_pt_mutex_init(&context->pt[n]); } @@ -1716,8 +1723,8 @@ lws_context_destroy(struct lws_context *context) lws_free_set_NULL(context->pt[n].serv_buf); - while (pt->ah_list) - _lws_destroy_ah(pt, pt->ah_list); + while (pt->http.ah_list) + _lws_destroy_ah(pt, pt->http.ah_list); } lws_plat_context_early_destroy(context); diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index 0be9b13ae..f883f0aaf 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -104,13 +104,13 @@ __lws_free_wsi(struct lws *wsi) if (wsi->vhost && wsi->vhost->lserv_wsi == wsi) wsi->vhost->lserv_wsi = NULL; - ah = pt->ah_list; + ah = pt->http.ah_list; while (ah) { if (ah->in_use && ah->wsi == wsi) { lwsl_err("%s: ah leak: wsi %p\n", __func__, wsi); ah->in_use = 0; ah->wsi = NULL; - pt->ah_count_in_use--; + pt->http.ah_count_in_use--; break; } ah = ah->next; @@ -1740,24 +1740,25 @@ lws_set_proxy(struct lws_vhost *vhost, const char *proxy) } else vhost->proxy_basic_auth_token[0] = '\0'; - lws_strncpy(vhost->http_proxy_address, proxy, - sizeof(vhost->http_proxy_address)); +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + lws_strncpy(vhost->http.http_proxy_address, proxy, + sizeof(vhost->http.http_proxy_address)); - p = strchr(vhost->http_proxy_address, ':'); - if (!p && !vhost->http_proxy_port) { + p = strchr(vhost->http.http_proxy_address, ':'); + if (!p && !vhost->http.http_proxy_port) { lwsl_err("http_proxy needs to be ads:port\n"); return -1; } else { if (p) { *p = '\0'; - vhost->http_proxy_port = atoi(p + 1); + vhost->http.http_proxy_port = atoi(p + 1); } } - lwsl_info(" Proxy %s:%u\n", vhost->http_proxy_address, - vhost->http_proxy_port); - + lwsl_info(" Proxy %s:%u\n", vhost->http.http_proxy_address, + vhost->http.http_proxy_port); +#endif return 0; auth_too_long: @@ -2991,9 +2992,9 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len) vh->conn_stats.h2_alpn, vh->conn_stats.h2_subs ); - - if (vh->mount_list) { - const struct lws_http_mount *m = vh->mount_list; +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + if (vh->http.mount_list) { + const struct lws_http_mount *m = vh->http.mount_list; buf += lws_snprintf(buf, end - buf, ",\n \"mounts\":["); while (m) { @@ -3024,7 +3025,7 @@ lws_json_dump_vhost(const struct lws_vhost *vh, char *buf, int len) } buf += lws_snprintf(buf, end - buf, "\n ]"); } - +#endif if (vh->protocols) { n = 0; first = 1; @@ -3117,8 +3118,8 @@ lws_json_dump_context(const struct lws_context *context, char *buf, int len, " \"ah_wait_list\":\"%d\"\n" " }", pt->fds_count, - pt->ah_count_in_use, - pt->ah_wait_list_length); + pt->http.ah_count_in_use, + pt->http.ah_wait_list_length); } buf += lws_snprintf(buf, end - buf, "]"); @@ -3169,7 +3170,7 @@ lws_json_dump_context(const struct lws_context *context, char *buf, int len, #ifdef LWS_WITH_CGI for (n = 0; n < context->count_threads; n++) { pt = &context->pt[n]; - pcgi = &pt->cgi_list; + pcgi = &pt->http.cgi_list; while (*pcgi) { pcgi = &(*pcgi)->cgi_list; @@ -3343,17 +3344,17 @@ lws_stats_log_dump(struct lws_context *context) lws_pt_lock(pt, __func__); lwsl_notice(" AH in use / max: %d / %d\n", - pt->ah_count_in_use, + pt->http.ah_count_in_use, context->max_http_header_pool); - wl = pt->ah_wait_list; + wl = pt->http.ah_wait_list; while (wl) { m++; wl = wl->ah_wait_list; } lwsl_notice(" AH wait list count / actual: %d / %d\n", - pt->ah_wait_list_length, m); + pt->http.ah_wait_list_length, m); lws_pt_unlock(pt); } @@ -3384,9 +3385,13 @@ lws_stats_log_dump(struct lws_context *context) if (!lws_plat_inet_ntop(df->af, df->addr, buf, sizeof(buf) - 1)) strcpy(buf, "unknown"); - +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) lwsl_notice(" peer %s: count wsi: %d, count ah: %d\n", buf, df->count_wsi, df->count_ah); +#else + lwsl_notice(" peer %s: count wsi: %d\n", + buf, df->count_wsi); +#endif if (!--m) break; diff --git a/lib/misc/peer-limits.c b/lib/misc/peer-limits.c index 2fcb8bb83..741505ce2 100644 --- a/lib/misc/peer-limits.c +++ b/lib/misc/peer-limits.c @@ -210,7 +210,11 @@ lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer) assert(peer->count_wsi); peer->count_wsi--; - if (!peer->count_wsi && !peer->count_ah) { + if (!peer->count_wsi +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + && !peer->http.count_ah +#endif + ) { /* * in order that we can accumulate peer activity correctly * allowing for periods when the peer has no connections, @@ -226,13 +230,14 @@ lws_peer_track_wsi_close(struct lws_context *context, struct lws_peer *peer) lws_context_unlock(context); /* ====================================> */ } +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) int lws_peer_confirm_ah_attach_ok(struct lws_context *context, struct lws_peer *peer) { if (!peer) return 0; - if (context->ip_limit_ah && peer->count_ah >= context->ip_limit_ah) { + if (context->ip_limit_ah && peer->http.count_ah >= context->ip_limit_ah) { lwsl_info("peer reached ah limit %d, deferring\n", context->ip_limit_ah); @@ -249,8 +254,8 @@ lws_peer_track_ah_detach(struct lws_context *context, struct lws_peer *peer) return; lws_context_lock(context); /* <====================================== */ - assert(peer->count_ah); - peer->count_ah--; + assert(peer->http.count_ah); + peer->http.count_ah--; lws_context_unlock(context); /* ====================================> */ } - +#endif diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h index c488950e7..f514d1fb8 100644 --- a/lib/private-libwebsockets.h +++ b/lib/private-libwebsockets.h @@ -779,25 +779,26 @@ struct lws_context_per_thread { #endif struct lws_pollfd *fds; volatile struct lws_foreign_thread_pollfd * volatile foreign_pfd_list; + #if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) struct lws_pt_role_ws ws; #endif +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + struct lws_pt_role_http http; +#endif + struct lws_dll_lws dll_head_timeout; struct lws_dll_lws dll_head_hrtimer; struct lws_dll_lws dll_head_buflist; /* guys with pending rxflow */ #if defined(LWS_WITH_LIBUV) || defined(LWS_WITH_LIBEVENT) struct lws_context *context; #endif -#ifdef LWS_WITH_CGI - struct lws_cgi *cgi_list; -#endif - void *http_header_data; - struct allocated_headers *ah_list; - struct lws *ah_wait_list; + + #if defined(LWS_HAVE_PTHREAD_H) const char *last_lock_reason; #endif - int ah_wait_list_length; + #if defined(LWS_WITH_TLS) struct lws *pending_read_list; /* linked list */ #endif @@ -837,9 +838,7 @@ struct lws_context_per_thread { volatile unsigned char foreign_spinlock; unsigned int fds_count; - uint32_t ah_pool_length; - short ah_count_in_use; unsigned char tid; unsigned char lock_depth; #if LWS_MAX_SMP > 1 @@ -889,7 +888,6 @@ struct alpn_ctx { }; struct lws_vhost { - char http_proxy_address[128]; char proxy_basic_auth_token[128]; #if LWS_MAX_SMP > 1 pthread_mutex_t lock; @@ -898,6 +896,9 @@ struct lws_vhost { #if defined(LWS_ROLE_H2) struct lws_vhost_role_h2 h2; #endif +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + struct lws_vhost_role_http http; +#endif #if defined(LWS_ROLE_WS) && !defined(LWS_WITHOUT_EXTENSIONS) struct lws_vhost_role_ws ws; #endif @@ -913,7 +914,7 @@ struct lws_vhost { struct lws_conn_stats conn_stats; struct lws_context *context; struct lws_vhost *vhost_next; - const struct lws_http_mount *mount_list; + struct lws *lserv_wsi; const char *name; const char *iface; @@ -931,7 +932,7 @@ struct lws_vhost { #if !defined(LWS_NO_CLIENT) struct lws_dll_lws dll_active_client_conns; #endif - const char *error_document_404; + const char *alpn; #if defined(LWS_WITH_TLS) lws_tls_ctx *ssl_ctx; @@ -948,7 +949,7 @@ struct lws_vhost { void *user; int listen_port; - unsigned int http_proxy_port; + #if defined(LWS_WITH_SOCKS5) unsigned int socks_proxy_port; #endif @@ -1005,10 +1006,11 @@ struct lws_peer { uint8_t addr[32]; uint32_t hash; uint32_t count_wsi; - uint32_t count_ah; - uint32_t total_wsi; - uint32_t total_ah; + +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + struct lws_peer_role_http http; +#endif uint8_t af; }; @@ -1420,8 +1422,7 @@ struct lws { #if defined(LWS_WITH_PEER_LIMITS) struct lws_peer *peer; #endif - struct allocated_headers *ah; - struct lws *ah_wait_list; + struct lws_udp *udp; #ifndef LWS_NO_CLIENT struct client_info_stash *stash; diff --git a/lib/roles/cgi/cgi-server.c b/lib/roles/cgi/cgi-server.c index 8863f0ec9..b5c1d19bf 100644 --- a/lib/roles/cgi/cgi-server.c +++ b/lib/roles/cgi/cgi-server.c @@ -188,8 +188,8 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len /* add us to the pt list of active cgis */ lwsl_debug("%s: adding cgi %p to list\n", __func__, wsi->cgi); - cgi->cgi_list = pt->cgi_list; - pt->cgi_list = cgi; + cgi->cgi_list = pt->http.cgi_list; + pt->http.cgi_list = cgi; sum += lws_snprintf(sum, sumend - sum, "%s ", exec_array[0]); @@ -199,7 +199,7 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len if (lws_is_ssl(wsi)) env_array[n++] = "HTTPS=ON"; - if (wsi->ah) { + if (wsi->http.ah) { static const unsigned char meths[] = { WSI_TOKEN_GET_URI, WSI_TOKEN_POST_URI, @@ -442,7 +442,7 @@ lws_cgi(struct lws *wsi, const char * const *exec_array, int script_uri_path_len bail3: /* drop us from the pt cgi list */ - pt->cgi_list = cgi->cgi_list; + pt->http.cgi_list = cgi->cgi_list; while (--n >= 0) __remove_wsi_socket_from_fds(wsi->cgi->stdwsi[n]); @@ -961,7 +961,7 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt) continue; lwsl_debug("%s: observed PID %d terminated\n", __func__, n); - pcgi = &pt->cgi_list; + pcgi = &pt->http.cgi_list; /* check all the subprocesses on the cgi list */ while (*pcgi) { @@ -1023,7 +1023,7 @@ lws_cgi_kill_terminated(struct lws_context_per_thread *pt) } } - pcgi = &pt->cgi_list; + pcgi = &pt->http.cgi_list; /* check all the subprocesses on the cgi list */ while (*pcgi) { @@ -1095,7 +1095,7 @@ void lws_cgi_remove_and_kill(struct lws *wsi) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws_cgi **pcgi = &pt->cgi_list; + struct lws_cgi **pcgi = &pt->http.cgi_list; /* remove us from the cgi list */ lwsl_debug("%s: remove cgi %p from list\n", __func__, wsi->cgi); diff --git a/lib/roles/h1/ops-h1.c b/lib/roles/h1/ops-h1.c index 9a4694f33..5fa929ab0 100644 --- a/lib/roles/h1/ops-h1.c +++ b/lib/roles/h1/ops-h1.c @@ -62,7 +62,7 @@ lws_read_h1(struct lws *wsi, unsigned char *buf, lws_filepos_t len) /* fallthru */ case LRS_HEADERS: - if (!wsi->ah) { + if (!wsi->http.ah) { lwsl_err("%s: LRS_HEADERS: NULL ah\n", __func__); assert(0); } @@ -308,7 +308,7 @@ lws_h1_server_socket_service(struct lws *wsi, struct lws_pollfd *pollfd) lwsi_state(wsi) == LRS_ISSUING_FILE || lwsi_state(wsi) == LRS_HEADERS || lwsi_state(wsi) == LRS_BODY)) { - if (!wsi->ah && + if (!wsi->http.ah && lws_header_table_attach(wsi, 0)) { lwsl_info("wsi %p: ah get fail\n", wsi); goto try_pollout; @@ -367,7 +367,7 @@ lws_h1_server_socket_service(struct lws *wsi, struct lws_pollfd *pollfd) * so the ah has no further meaning */ - if (wsi->ah && + if (wsi->http.ah && !lwsi_role_h1(wsi) && !lwsi_role_h2(wsi) && !lwsi_role_cgi(wsi)) diff --git a/lib/roles/h2/hpack.c b/lib/roles/h2/hpack.c index 2147c6533..6e802764a 100644 --- a/lib/roles/h2/hpack.c +++ b/lib/roles/h2/hpack.c @@ -202,7 +202,7 @@ static int huftable_decode(int pos, char c) static int lws_frag_start(struct lws *wsi, int hdr_token_idx) { - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; if (!ah) { lwsl_notice("%s: no ah\n", __func__); @@ -275,7 +275,7 @@ static int lws_frag_start(struct lws *wsi, int hdr_token_idx) static int lws_frag_append(struct lws *wsi, unsigned char c) { - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; ah->data[ah->pos++] = c; ah->frags[ah->nfrag].len++; @@ -290,16 +290,16 @@ static int lws_frag_end(struct lws *wsi) return 1; /* don't account for the terminating NUL in the logical length */ - wsi->ah->frags[wsi->ah->nfrag].len--; + wsi->http.ah->frags[wsi->http.ah->nfrag].len--; - wsi->ah->nfrag++; + wsi->http.ah->nfrag++; return 0; } int lws_hdr_extant(struct lws *wsi, enum lws_token_indexes h) { - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; int n; if (!ah) @@ -781,7 +781,7 @@ int lws_hpack_interpret(struct lws *wsi, unsigned char c) { struct lws *nwsi = lws_get_network_wsi(wsi); struct lws_h2_netconn *h2n = nwsi->h2.h2n; - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; unsigned int prev; unsigned char c1; int n, m, plen; diff --git a/lib/roles/h2/http2.c b/lib/roles/h2/http2.c index b0a45578f..c61eb8413 100644 --- a/lib/roles/h2/http2.c +++ b/lib/roles/h2/http2.c @@ -672,11 +672,11 @@ int lws_h2_do_pps_send(struct lws *wsi) goto bail; /* pass on the initial headers to SID 1 */ - h2n->swsi->ah = wsi->ah; - wsi->ah = NULL; + h2n->swsi->http.ah = wsi->http.ah; + wsi->http.ah = NULL; lwsl_info("%s: inherited headers %p\n", __func__, - h2n->swsi->ah); + h2n->swsi->http.ah); h2n->swsi->h2.tx_cr = h2n->set.s[H2SET_INITIAL_WINDOW_SIZE]; lwsl_info("initial tx credit on conn %p: %d\n", @@ -1090,7 +1090,7 @@ lws_h2_parse_frame_header(struct lws *wsi) * ah needs attaching to child wsi, even though * we only fill it from network wsi */ - if (!h2n->swsi->ah) + if (!h2n->swsi->http.ah) if (lws_header_table_attach(h2n->swsi, 0)) { lwsl_err("%s: Failed to get ah\n", __func__); return 1; @@ -1230,7 +1230,7 @@ lws_h2_parse_end_of_frame(struct lws *wsi) &role_ops_h2); /* pass on the initial headers to SID 1 */ - h2n->swsi->ah = wsi->ah; + h2n->swsi->http.ah = wsi->http.ah; h2n->swsi->client_h2_substream = 1; h2n->swsi->protocol = wsi->protocol; @@ -1240,9 +1240,9 @@ lws_h2_parse_end_of_frame(struct lws *wsi) wsi->user_space = NULL; - if (h2n->swsi->ah) - h2n->swsi->ah->wsi = h2n->swsi; - wsi->ah = NULL; + if (h2n->swsi->http.ah) + h2n->swsi->http.ah->wsi = h2n->swsi; + wsi->http.ah = NULL; lwsl_info("%s: MIGRATING nwsi %p: swsi %p\n", __func__, wsi, h2n->swsi); @@ -1422,8 +1422,8 @@ lws_h2_parse_end_of_frame(struct lws *wsi) wsi->vhost->conn_stats.h2_trans++; p = lws_hdr_simple_ptr(h2n->swsi, WSI_TOKEN_HTTP_COLON_METHOD); if (!strcmp(p, "POST")) - h2n->swsi->ah->frag_index[WSI_TOKEN_POST_URI] = - h2n->swsi->ah->frag_index[WSI_TOKEN_HTTP_COLON_PATH]; + h2n->swsi->http.ah->frag_index[WSI_TOKEN_POST_URI] = + h2n->swsi->http.ah->frag_index[WSI_TOKEN_HTTP_COLON_PATH]; lwsl_debug("%s: setting DEF_ACT from 0x%x\n", __func__, h2n->swsi->wsistate); lwsi_set_state(h2n->swsi, LRS_DEFERRING_ACTION); diff --git a/lib/roles/h2/ops-h2.c b/lib/roles/h2/ops-h2.c index f11b461a0..8aeb16735 100644 --- a/lib/roles/h2/ops-h2.c +++ b/lib/roles/h2/ops-h2.c @@ -288,7 +288,7 @@ drain: // lws_buflist_describe(&wsi->buflist, wsi); - if (wsi->ah + if (wsi->http.ah #if !defined(LWS_NO_CLIENT) && !wsi->client_h2_alpn #endif @@ -1000,13 +1000,13 @@ rops_alpn_negotiated_h2(struct lws *wsi, const char *alpn) /* adopt the header info */ - ah = wsi->ah; + ah = wsi->http.ah; lws_role_transition(wsi, LWSIFR_SERVER, LRS_H2_AWAIT_PREFACE, &role_ops_h2); /* http2 union member has http union struct at start */ - wsi->ah = ah; + wsi->http.ah = ah; if (!wsi->h2.h2n) wsi->h2.h2n = lws_zalloc(sizeof(*wsi->h2.h2n), "h2n"); diff --git a/lib/roles/http/client/client-handshake.c b/lib/roles/http/client/client-handshake.c index c5043bd42..b2137dfd3 100644 --- a/lib/roles/http/client/client-handshake.c +++ b/lib/roles/http/client/client-handshake.c @@ -50,7 +50,7 @@ lws_client_connect_2(struct lws *wsi) lwsl_client("%s: %p\n", __func__, wsi); - if (!wsi->ah) { + if (!wsi->http.ah) { cce = "ah was NULL at cc2"; lwsl_err("%s\n", cce); goto oom4; @@ -180,7 +180,7 @@ create_new_conn: * * Priority 1: connect to http proxy */ - if (wsi->vhost->http_proxy_port) { + if (wsi->vhost->http.http_proxy_port) { plen = sprintf((char *)pt->serv_buf, "CONNECT %s:%u HTTP/1.0\x0d\x0a" "User-agent: libwebsockets\x0d\x0a", @@ -193,8 +193,8 @@ create_new_conn: wsi->vhost->proxy_basic_auth_token); plen += sprintf((char *)pt->serv_buf + plen, "\x0d\x0a"); - ads = wsi->vhost->http_proxy_address; - port = wsi->vhost->http_proxy_port; + ads = wsi->vhost->http.http_proxy_address; + port = wsi->vhost->http.http_proxy_port; #if defined(LWS_WITH_SOCKS5) @@ -447,7 +447,7 @@ create_new_conn: /* we are connected to server, or proxy */ /* http proxy */ - if (wsi->vhost->http_proxy_port) { + if (wsi->vhost->http.http_proxy_port) { /* * OK from now on we talk via the proxy, so connect to that @@ -456,9 +456,9 @@ create_new_conn: * leaving old string/frag there but unreferenced) */ if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, - wsi->vhost->http_proxy_address)) + wsi->vhost->http.http_proxy_address)) goto failed; - wsi->c_port = wsi->vhost->http_proxy_port; + wsi->c_port = wsi->vhost->http.http_proxy_port; n = send(wsi->desc.sockfd, (char *)pt->serv_buf, (int)plen, MSG_NOSIGNAL); @@ -665,7 +665,7 @@ lws_client_reset(struct lws **pwsi, int ssl, const char *address, int port, wsi->pending_timeout = NO_PENDING_TIMEOUT; wsi->c_port = port; wsi->hdr_parsing_completed = 0; - _lws_header_table_reset(wsi->ah); + _lws_header_table_reset(wsi->http.ah); if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address)) return NULL; @@ -887,8 +887,12 @@ lws_client_connect_via_info(struct lws_client_connect_info *i) goto bail; wsi->context = i->context; +#if defined(LWS_ROLE_H1) /* assert the mode and union status (hdr) clearly */ lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, &role_ops_h1); +#else + lws_role_transition(wsi, LWSIFR_CLIENT, LRS_UNCONNECTED, &role_ops_raw); +#endif wsi->desc.sockfd = LWS_SOCK_INVALID; /* 1) fill up the wsi with stuff from the connect_info as far as it diff --git a/lib/roles/http/client/client.c b/lib/roles/http/client/client.c index a1841f552..130766a1c 100644 --- a/lib/roles/http/client/client.c +++ b/lib/roles/http/client/client.c @@ -405,10 +405,10 @@ start_ws_handshake: lwsi_set_state(w, LRS_WAITING_SERVER_REPLY); w->hdr_parsing_completed = 0; - w->ah->parser_state = WSI_TOKEN_NAME_PART; - w->ah->lextable_pos = 0; + w->http.ah->parser_state = WSI_TOKEN_NAME_PART; + w->http.ah->lextable_pos = 0; /* If we're (re)starting on headers, need other implied init */ - wsi->ah->ues = URIES_IDLE; + wsi->http.ah->ues = URIES_IDLE; } lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, @@ -428,8 +428,8 @@ start_ws_handshake: } client_http_body_sent: /* prepare ourselves to do the parsing */ - wsi->ah->parser_state = WSI_TOKEN_NAME_PART; - wsi->ah->lextable_pos = 0; + wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART; + wsi->http.ah->lextable_pos = 0; lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY); lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, context->timeout_secs); @@ -469,7 +469,7 @@ client_http_body_sent: * definitively ready from browser pov. */ len = 1; - while (wsi->ah->parser_state != WSI_PARSING_COMPLETE && + while (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE && len > 0) { int plen = 1; @@ -496,7 +496,7 @@ client_http_body_sent: * libwebsocket timeout still active here too, so if parsing did * not complete just wait for next packet coming in this state */ - if (wsi->ah->parser_state != WSI_PARSING_COMPLETE) + if (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE) break; @@ -599,14 +599,14 @@ lws_http_transaction_completed_client(struct lws *wsi) /* otherwise set ourselves up ready to go again */ lwsi_set_state(wsi, LRS_WAITING_SERVER_REPLY); - wsi->ah->parser_state = WSI_TOKEN_NAME_PART; - wsi->ah->lextable_pos = 0; + wsi->http.ah->parser_state = WSI_TOKEN_NAME_PART; + wsi->http.ah->lextable_pos = 0; lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE, wsi->context->timeout_secs); /* If we're (re)starting on headers, need other implied init */ - wsi->ah->ues = URIES_IDLE; + wsi->http.ah->ues = URIES_IDLE; lwsl_info("%s: %p: new queued transaction as %p\n", __func__, wsi, wsi_eff); lws_callback_on_writable(wsi); @@ -617,10 +617,10 @@ lws_http_transaction_completed_client(struct lws *wsi) LWS_VISIBLE LWS_EXTERN unsigned int lws_http_client_http_response(struct lws *wsi) { - if (!wsi->ah) + if (!wsi->http.ah) return 0; - return wsi->ah->http_response; + return wsi->http.ah->http_response; } #if defined(LWS_PLAT_OPTEE) char * @@ -651,7 +651,7 @@ lws_client_interpret_server_handshake(struct lws *wsi) lws_client_stash_destroy(wsi); - ah = wsi->ah; + ah = wsi->http.ah; if (!wsi->do_ws) { /* we are being an http client... */ @@ -668,7 +668,7 @@ lws_client_interpret_server_handshake(struct lws *wsi) LRS_ESTABLISHED, &role_ops_h1); } - wsi->ah = ah; + wsi->http.ah = ah; ah->http_response = 0; } diff --git a/lib/roles/http/header.c b/lib/roles/http/header.c index 48beb7456..a201c97eb 100644 --- a/lib/roles/http/header.c +++ b/lib/roles/http/header.c @@ -277,15 +277,17 @@ lws_return_http_status(struct lws *wsi, unsigned int code, return 1; } +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) if (!wsi->handling_404 && - wsi->vhost->error_document_404 && + wsi->vhost->http.error_document_404 && code == HTTP_STATUS_NOT_FOUND) /* we should do a redirect, and do the 404 there */ if (lws_http_redirect(wsi, HTTP_STATUS_FOUND, - (uint8_t *)wsi->vhost->error_document_404, - (int)strlen(wsi->vhost->error_document_404), + (uint8_t *)wsi->vhost->http.error_document_404, + (int)strlen(wsi->vhost->http.error_document_404), &p, end) > 0) return 0; +#endif /* if the redirect failed, just do a simple status */ p = start; diff --git a/lib/roles/http/private.h b/lib/roles/http/private.h index 07c6b62b8..e8519bd7e 100644 --- a/lib/roles/http/private.h +++ b/lib/roles/http/private.h @@ -158,12 +158,38 @@ LWS_EXTERN int lws_rewrite_parse(struct lws_rewrite *r, const unsigned char *in, int in_len); #endif +struct lws_pt_role_http { + struct allocated_headers *ah_list; + struct lws *ah_wait_list; +#ifdef LWS_WITH_CGI + struct lws_cgi *cgi_list; +#endif + int ah_wait_list_length; + uint32_t ah_pool_length; + + int ah_count_in_use; +}; + +struct lws_peer_role_http { + uint32_t count_ah; + uint32_t total_ah; +}; + +struct lws_vhost_role_http { + char http_proxy_address[128]; + const struct lws_http_mount *mount_list; + const char *error_document_404; + unsigned int http_proxy_port; +}; + struct _lws_http_mode_related { struct lws *new_wsi_list; #if defined(LWS_WITH_HTTP_PROXY) struct lws_rewrite *rw; #endif + struct allocated_headers *ah; + struct lws *ah_wait_list; lws_filepos_t filepos; lws_filepos_t filelen; diff --git a/lib/roles/http/server/parsers.c b/lib/roles/http/server/parsers.c index 67c8dd605..c9ee3234d 100644 --- a/lib/roles/http/server/parsers.c +++ b/lib/roles/http/server/parsers.c @@ -41,13 +41,13 @@ _lws_create_ah(struct lws_context_per_thread *pt, ah_data_idx_t data_size) return NULL; } - ah->next = pt->ah_list; - pt->ah_list = ah; + ah->next = pt->http.ah_list; + pt->http.ah_list = ah; ah->data_length = data_size; - pt->ah_pool_length++; + pt->http.ah_pool_length++; lwsl_info("%s: created ah %p (size %d): pool length %d\n", __func__, - ah, (int)data_size, pt->ah_pool_length); + ah, (int)data_size, pt->http.ah_pool_length); return ah; } @@ -55,12 +55,12 @@ _lws_create_ah(struct lws_context_per_thread *pt, ah_data_idx_t data_size) int _lws_destroy_ah(struct lws_context_per_thread *pt, struct allocated_headers *ah) { - lws_start_foreach_llp(struct allocated_headers **, a, pt->ah_list) { + lws_start_foreach_llp(struct allocated_headers **, a, pt->http.ah_list) { if ((*a) == ah) { *a = ah->next; - pt->ah_pool_length--; + pt->http.ah_pool_length--; lwsl_info("%s: freed ah %p : pool length %d\n", - __func__, ah, pt->ah_pool_length); + __func__, ah, pt->http.ah_pool_length); if (ah->data) lws_free(ah->data); lws_free(ah); @@ -88,7 +88,7 @@ _lws_header_table_reset(struct allocated_headers *ah) void __lws_header_table_reset(struct lws *wsi, int autoservice) { - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; struct lws_context_per_thread *pt; struct lws_pollfd *pfd; @@ -144,18 +144,18 @@ _lws_header_ensure_we_are_on_waiting_list(struct lws *wsi) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; struct lws_pollargs pa; - struct lws **pwsi = &pt->ah_wait_list; + struct lws **pwsi = &pt->http.ah_wait_list; while (*pwsi) { if (*pwsi == wsi) return; - pwsi = &(*pwsi)->ah_wait_list; + pwsi = &(*pwsi)->http.ah_wait_list; } lwsl_info("%s: wsi: %p\n", __func__, wsi); - wsi->ah_wait_list = pt->ah_wait_list; - pt->ah_wait_list = wsi; - pt->ah_wait_list_length++; + wsi->http.ah_wait_list = pt->http.ah_wait_list; + pt->http.ah_wait_list = wsi; + pt->http.ah_wait_list_length++; /* we cannot accept input then */ @@ -166,20 +166,20 @@ static int __lws_remove_from_ah_waiting_list(struct lws *wsi) { struct lws_context_per_thread *pt = &wsi->context->pt[(int)wsi->tsi]; - struct lws **pwsi =&pt->ah_wait_list; + struct lws **pwsi =&pt->http.ah_wait_list; while (*pwsi) { if (*pwsi == wsi) { lwsl_info("%s: wsi %p\n", __func__, wsi); /* point prev guy to our next */ - *pwsi = wsi->ah_wait_list; + *pwsi = wsi->http.ah_wait_list; /* we shouldn't point anywhere now */ - wsi->ah_wait_list = NULL; - pt->ah_wait_list_length--; + wsi->http.ah_wait_list = NULL; + pt->http.ah_wait_list_length--; return 1; } - pwsi = &(*pwsi)->ah_wait_list; + pwsi = &(*pwsi)->http.ah_wait_list; } return 0; @@ -194,18 +194,18 @@ lws_header_table_attach(struct lws *wsi, int autoservice) int n; lwsl_info("%s: wsi %p: ah %p (tsi %d, count = %d) in\n", __func__, - (void *)wsi, (void *)wsi->ah, wsi->tsi, - pt->ah_count_in_use); + (void *)wsi, (void *)wsi->http.ah, wsi->tsi, + pt->http.ah_count_in_use); lws_pt_lock(pt, __func__); /* if we are already bound to one, just clear it down */ - if (wsi->ah) { + if (wsi->http.ah) { lwsl_info("%s: cleardown\n", __func__); goto reset; } - n = pt->ah_count_in_use == context->max_http_header_pool; + n = pt->http.ah_count_in_use == context->max_http_header_pool; #if defined(LWS_WITH_PEER_LIMITS) if (!n) { n = lws_peer_confirm_ah_attach_ok(context, wsi->peer); @@ -229,26 +229,28 @@ lws_header_table_attach(struct lws *wsi, int autoservice) __lws_remove_from_ah_waiting_list(wsi); - wsi->ah = _lws_create_ah(pt, context->max_http_header_data); - if (!wsi->ah) { /* we could not create an ah */ + wsi->http.ah = _lws_create_ah(pt, context->max_http_header_data); + if (!wsi->http.ah) { /* we could not create an ah */ _lws_header_ensure_we_are_on_waiting_list(wsi); goto bail; } - wsi->ah->in_use = 1; - wsi->ah->wsi = wsi; /* mark our owner */ - pt->ah_count_in_use++; + wsi->http.ah->in_use = 1; + wsi->http.ah->wsi = wsi; /* mark our owner */ + pt->http.ah_count_in_use++; -#if defined(LWS_WITH_PEER_LIMITS) +#if defined(LWS_WITH_PEER_LIMITS) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) + lws_context_lock(context); /* <====================================== */ if (wsi->peer) - wsi->peer->count_ah++; + wsi->peer->http.count_ah++; + lws_context_unlock(context); /* ====================================> */ #endif _lws_change_pollfd(wsi, 0, LWS_POLLIN, &pa); lwsl_info("%s: did attach wsi %p: ah %p: count %d (on exit)\n", __func__, - (void *)wsi, (void *)wsi->ah, pt->ah_count_in_use); + (void *)wsi, (void *)wsi->http.ah, pt->http.ah_count_in_use); reset: __lws_header_table_reset(wsi, autoservice); @@ -275,7 +277,7 @@ bail: int __lws_header_table_detach(struct lws *wsi, int autoservice) { struct lws_context *context = wsi->context; - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi]; struct lws_pollargs pa; struct lws **pwsi, **pwsi_eligible; @@ -288,7 +290,7 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__, (void *)wsi, (void *)ah, wsi->tsi, - pt->ah_count_in_use); + pt->http.ah_count_in_use); /* we did have an ah attached */ time(&now); @@ -305,10 +307,10 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) ah->assigned = 0; /* if we think we're detaching one, there should be one in use */ - assert(pt->ah_count_in_use > 0); + assert(pt->http.ah_count_in_use > 0); /* and this specific one should have been in use */ assert(ah->in_use); - memset(&wsi->ah, 0, sizeof(wsi->ah)); + memset(&wsi->http.ah, 0, sizeof(wsi->http.ah)); #if defined(LWS_WITH_PEER_LIMITS) if (ah->wsi) @@ -316,7 +318,7 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) #endif ah->wsi = NULL; /* no owner */ - pwsi = &pt->ah_wait_list; + pwsi = &pt->http.ah_wait_list; /* oh there is nobody on the waiting list... leave the ah unattached */ if (!*pwsi) @@ -341,11 +343,11 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) } #if defined(LWS_WITH_PEER_LIMITS) else - if (!(*pwsi)->ah_wait_list) + if (!(*pwsi)->http.ah_wait_list) lws_stats_atomic_bump(context, pt, LWSSTATS_C_PEER_LIMIT_AH_DENIED, 1); #endif - pwsi = &(*pwsi)->ah_wait_list; + pwsi = &(*pwsi)->http.ah_wait_list; } if (!wsi) /* everybody waiting already has too many ah... */ @@ -353,14 +355,14 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) lwsl_info("%s: last eligible wsi in wait list %p\n", __func__, wsi); - wsi->ah = ah; + wsi->http.ah = ah; ah->wsi = wsi; /* new owner */ __lws_header_table_reset(wsi, autoservice); -#if defined(LWS_WITH_PEER_LIMITS) +#if defined(LWS_WITH_PEER_LIMITS) && (defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)) lws_context_lock(context); /* <====================================== */ if (wsi->peer) - wsi->peer->count_ah++; + wsi->peer->http.count_ah++; lws_context_unlock(context); /* ====================================> */ #endif @@ -375,10 +377,10 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) } /* point prev guy to next guy in list instead */ - *pwsi_eligible = wsi->ah_wait_list; + *pwsi_eligible = wsi->http.ah_wait_list; /* the guy who got one is out of the list */ - wsi->ah_wait_list = NULL; - pt->ah_wait_list_length--; + wsi->http.ah_wait_list = NULL; + pt->http.ah_wait_list_length--; #ifndef LWS_NO_CLIENT if (lwsi_role_client(wsi) && lwsi_state(wsi) == LRS_UNCONNECTED) { @@ -395,17 +397,17 @@ int __lws_header_table_detach(struct lws *wsi, int autoservice) } #endif - assert(!!pt->ah_wait_list_length == !!(lws_intptr_t)pt->ah_wait_list); + assert(!!pt->http.ah_wait_list_length == !!(lws_intptr_t)pt->http.ah_wait_list); bail: lwsl_info("%s: wsi %p: ah %p (tsi=%d, count = %d)\n", __func__, - (void *)wsi, (void *)ah, pt->tid, pt->ah_count_in_use); + (void *)wsi, (void *)ah, pt->tid, pt->http.ah_count_in_use); return 0; nobody_usable_waiting: lwsl_info("%s: nobody usable waiting\n", __func__); _lws_destroy_ah(pt, ah); - pt->ah_count_in_use--; + pt->http.ah_count_in_use--; goto bail; } @@ -428,16 +430,16 @@ lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx) { int n; - if (!wsi->ah) + if (!wsi->http.ah) return 0; - n = wsi->ah->frag_index[h]; + n = wsi->http.ah->frag_index[h]; if (!n) return 0; do { if (!frag_idx) - return wsi->ah->frags[n].len; - n = wsi->ah->frags[n].nfrag; + return wsi->http.ah->frags[n].len; + n = wsi->http.ah->frags[n].nfrag; } while (frag_idx-- && n); return 0; @@ -448,15 +450,15 @@ LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h) int n; int len = 0; - if (!wsi->ah) + if (!wsi->http.ah) return 0; - n = wsi->ah->frag_index[h]; + n = wsi->http.ah->frag_index[h]; if (!n) return 0; do { - len += wsi->ah->frags[n].len; - n = wsi->ah->frags[n].nfrag; + len += wsi->http.ah->frags[n].len; + n = wsi->http.ah->frags[n].nfrag; } while (n); return len; @@ -468,29 +470,29 @@ LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len, int n = 0; int f; - if (!wsi->ah) + if (!wsi->http.ah) return -1; - f = wsi->ah->frag_index[h]; + f = wsi->http.ah->frag_index[h]; if (!f) return -1; while (n < frag_idx) { - f = wsi->ah->frags[f].nfrag; + f = wsi->http.ah->frags[f].nfrag; if (!f) return -1; n++; } - if (wsi->ah->frags[f].len >= len) + if (wsi->http.ah->frags[f].len >= len) return -1; - memcpy(dst, wsi->ah->data + wsi->ah->frags[f].offset, - wsi->ah->frags[f].len); - dst[wsi->ah->frags[f].len] = '\0'; + memcpy(dst, wsi->http.ah->data + wsi->http.ah->frags[f].offset, + wsi->http.ah->frags[f].len); + dst[wsi->http.ah->frags[f].len] = '\0'; - return wsi->ah->frags[f].len; + return wsi->http.ah->frags[f].len; } LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len, @@ -502,21 +504,21 @@ LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len, if (toklen >= len) return -1; - if (!wsi->ah) + if (!wsi->http.ah) return -1; - n = wsi->ah->frag_index[h]; + n = wsi->http.ah->frag_index[h]; if (!n) return 0; do { - if (wsi->ah->frags[n].len >= len) + if (wsi->http.ah->frags[n].len >= len) return -1; - strncpy(dst, &wsi->ah->data[wsi->ah->frags[n].offset], - wsi->ah->frags[n].len); - dst += wsi->ah->frags[n].len; - len -= wsi->ah->frags[n].len; - n = wsi->ah->frags[n].nfrag; + strncpy(dst, &wsi->http.ah->data[wsi->http.ah->frags[n].offset], + wsi->http.ah->frags[n].len); + dst += wsi->http.ah->frags[n].len; + len -= wsi->http.ah->frags[n].len; + n = wsi->http.ah->frags[n].nfrag; } while (n); *dst = '\0'; @@ -527,21 +529,21 @@ char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h) { int n; - n = wsi->ah->frag_index[h]; + n = wsi->http.ah->frag_index[h]; if (!n) return NULL; - return wsi->ah->data + wsi->ah->frags[n].offset; + return wsi->http.ah->data + wsi->http.ah->frags[n].offset; } static int LWS_WARN_UNUSED_RESULT lws_pos_in_bounds(struct lws *wsi) { - if (wsi->ah->pos < + if (wsi->http.ah->pos < (unsigned int)wsi->context->max_http_header_data) return 0; - if ((int)wsi->ah->pos == wsi->context->max_http_header_data) { + if ((int)wsi->http.ah->pos == wsi->context->max_http_header_data) { lwsl_err("Ran out of header data space\n"); return 1; } @@ -550,7 +552,7 @@ lws_pos_in_bounds(struct lws *wsi) * with these tests everywhere, it should never be able to exceed * the limit, only meet it */ - lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->ah->pos, + lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->http.ah->pos, wsi->context->max_http_header_data); assert(0); @@ -560,25 +562,25 @@ lws_pos_in_bounds(struct lws *wsi) int LWS_WARN_UNUSED_RESULT lws_hdr_simple_create(struct lws *wsi, enum lws_token_indexes h, const char *s) { - wsi->ah->nfrag++; - if (wsi->ah->nfrag == ARRAY_SIZE(wsi->ah->frags)) { + wsi->http.ah->nfrag++; + if (wsi->http.ah->nfrag == ARRAY_SIZE(wsi->http.ah->frags)) { lwsl_warn("More hdr frags than we can deal with, dropping\n"); return -1; } - wsi->ah->frag_index[h] = wsi->ah->nfrag; + wsi->http.ah->frag_index[h] = wsi->http.ah->nfrag; - wsi->ah->frags[wsi->ah->nfrag].offset = wsi->ah->pos; - wsi->ah->frags[wsi->ah->nfrag].len = 0; - wsi->ah->frags[wsi->ah->nfrag].nfrag = 0; + wsi->http.ah->frags[wsi->http.ah->nfrag].offset = wsi->http.ah->pos; + wsi->http.ah->frags[wsi->http.ah->nfrag].len = 0; + wsi->http.ah->frags[wsi->http.ah->nfrag].nfrag = 0; do { if (lws_pos_in_bounds(wsi)) return -1; - wsi->ah->data[wsi->ah->pos++] = *s; + wsi->http.ah->data[wsi->http.ah->pos++] = *s; if (*s) - wsi->ah->frags[wsi->ah->nfrag].len++; + wsi->http.ah->frags[wsi->http.ah->nfrag].len++; } while (*s++); return 0; @@ -606,27 +608,27 @@ issue_char(struct lws *wsi, unsigned char c) if (lws_pos_in_bounds(wsi)) return -1; - frag_len = wsi->ah->frags[wsi->ah->nfrag].len; + frag_len = wsi->http.ah->frags[wsi->http.ah->nfrag].len; /* * If we haven't hit the token limit, just copy the character into * the header */ - if (frag_len < wsi->ah->current_token_limit) { - wsi->ah->data[wsi->ah->pos++] = c; + if (frag_len < wsi->http.ah->current_token_limit) { + wsi->http.ah->data[wsi->http.ah->pos++] = c; if (c) - wsi->ah->frags[wsi->ah->nfrag].len++; + wsi->http.ah->frags[wsi->http.ah->nfrag].len++; return 0; } /* Insert a null character when we *hit* the limit: */ - if (frag_len == wsi->ah->current_token_limit) { + if (frag_len == wsi->http.ah->current_token_limit) { if (lws_pos_in_bounds(wsi)) return -1; - wsi->ah->data[wsi->ah->pos++] = '\0'; + wsi->http.ah->data[wsi->http.ah->pos++] = '\0'; lwsl_warn("header %i exceeds limit %d\n", - wsi->ah->parser_state, - wsi->ah->current_token_limit); + wsi->http.ah->parser_state, + wsi->http.ah->current_token_limit); } return 1; @@ -635,7 +637,7 @@ issue_char(struct lws *wsi, unsigned char c) int lws_parse_urldecode(struct lws *wsi, uint8_t *_c) { - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; unsigned int enc = 0; uint8_t c = *_c; @@ -841,13 +843,13 @@ static const unsigned char methods[] = { int LWS_WARN_UNUSED_RESULT lws_parse(struct lws *wsi, unsigned char *buf, int *len) { - struct allocated_headers *ah = wsi->ah; + struct allocated_headers *ah = wsi->http.ah; struct lws_context *context = wsi->context; unsigned int n, m; unsigned char c; int r, pos; - assert(wsi->ah); + assert(wsi->http.ah); do { (*len)--; diff --git a/lib/roles/http/server/server.c b/lib/roles/http/server/server.c index fac864e78..5c819cd66 100644 --- a/lib/roles/http/server/server.c +++ b/lib/roles/http/server/server.c @@ -460,9 +460,11 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, if (!wsi->vhost) return -1; - if (wsi->vhost->error_document_404 && - !strcmp(uri, wsi->vhost->error_document_404)) +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) + if (wsi->vhost->http.error_document_404 && + !strcmp(uri, wsi->vhost->http.error_document_404)) wsi->handling_404 = 1; +#endif lws_snprintf(path, sizeof(path) - 1, "%s/%s", origin, uri); @@ -546,7 +548,7 @@ lws_http_serve(struct lws *wsi, char *uri, const char *origin, if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_RANGE)) if (strcmp(sym, lws_hdr_simple_ptr(wsi, WSI_TOKEN_HTTP_IF_RANGE))) /* differs - defeat Range: */ - wsi->ah->frag_index[WSI_TOKEN_HTTP_RANGE] = 0; + wsi->http.ah->frag_index[WSI_TOKEN_HTTP_RANGE] = 0; if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH)) { /* @@ -653,13 +655,14 @@ bail: return -1; } +#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) const struct lws_http_mount * lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len) { const struct lws_http_mount *hm, *hit = NULL; int best = 0; - hm = wsi->vhost->mount_list; + hm = wsi->vhost->http.mount_list; while (hm) { if (uri_len >= hm->mountpoint_len && !strncmp(uri_ptr, hm->mountpoint, hm->mountpoint_len) && @@ -684,6 +687,7 @@ lws_find_mount(struct lws *wsi, const char *uri_ptr, int uri_len) return hit; } +#endif #if !defined(LWS_WITH_ESP32) static int @@ -1383,7 +1387,7 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len) assert(0); } - if (!wsi->ah) { + if (!wsi->http.ah) { lwsl_err("%s: assert: NULL ah\n", __func__); assert(0); } @@ -1435,7 +1439,7 @@ raw_transition: goto bail_nuke_ah; } - if (wsi->ah->parser_state != WSI_PARSING_COMPLETE) + if (wsi->http.ah->parser_state != WSI_PARSING_COMPLETE) continue; lwsl_parser("%s: lws_parse sees parsing complete\n", __func__); @@ -1550,7 +1554,7 @@ raw_transition: wsi->http.fop_fd = NULL; lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi, - (void *)wsi->ah); + (void *)wsi->http.ah); n = lws_http_action(wsi); @@ -1764,7 +1768,7 @@ lws_http_transaction_completed(struct lws *wsi) * that is already at least the start of another header set, simply * reset the existing header table and keep it. */ - if (wsi->ah) { + if (wsi->http.ah) { // lws_buflist_describe(&wsi->buflist, wsi); if (!lws_buflist_next_segment_len(&wsi->buflist, NULL)) { lwsl_debug("%s: nothing in buflist so detaching ah\n", __func__); @@ -1798,8 +1802,8 @@ lws_http_transaction_completed(struct lws *wsi) wsi->vhost->keepalive_timeout); } /* If we're (re)starting on headers, need other implied init */ - if (wsi->ah) - wsi->ah->ues = URIES_IDLE; + if (wsi->http.ah) + wsi->http.ah->ues = URIES_IDLE; lwsi_set_state(wsi, LRS_ESTABLISHED); } else @@ -2074,7 +2078,7 @@ adopt_socket_readbuf(struct lws *wsi, const char *readbuf, size_t len) * readbuf data to wsi or ah yet, and we will do it next if we get * the ah. */ - if (wsi->ah || !lws_header_table_attach(wsi, 0)) { + if (wsi->http.ah || !lws_header_table_attach(wsi, 0)) { lwsl_notice("%s: calling service on readbuf ah\n", __func__); pt = &wsi->context->pt[(int)wsi->tsi]; diff --git a/lib/roles/ws/client-ws.c b/lib/roles/ws/client-ws.c index 2fe5b4f9d..10b69f019 100644 --- a/lib/roles/ws/client-ws.c +++ b/lib/roles/ws/client-ws.c @@ -194,8 +194,8 @@ lws_generate_client_ws_handshake(struct lws *wsi, char *p) lws_SHA1((unsigned char *)buf, n, (unsigned char *)hash); lws_b64_encode_string(hash, 20, - wsi->ah->initial_handshake_hash_base64, - sizeof(wsi->ah->initial_handshake_hash_base64)); + wsi->http.ah->initial_handshake_hash_base64, + sizeof(wsi->http.ah->initial_handshake_hash_base64)); return p; } @@ -225,18 +225,18 @@ lws_client_ws_upgrade(struct lws *wsi, const char **cce) goto bail3; } - if (wsi->ah->http_response == 401) { + if (wsi->http.ah->http_response == 401) { lwsl_warn( "lws_client_handshake: got bad HTTP response '%d'\n", - wsi->ah->http_response); + wsi->http.ah->http_response); *cce = "HS: ws upgrade unauthorized"; goto bail3; } - if (wsi->ah->http_response != 101) { + if (wsi->http.ah->http_response != 101) { lwsl_warn( "lws_client_handshake: got bad HTTP response '%d'\n", - wsi->ah->http_response); + wsi->http.ah->http_response); *cce = "HS: ws upgrade response not 101"; goto bail3; } @@ -544,9 +544,9 @@ check_accept: */ p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT); - if (strcmp(p, wsi->ah->initial_handshake_hash_base64)) { + if (strcmp(p, wsi->http.ah->initial_handshake_hash_base64)) { lwsl_warn("lws_client_int_s_hs: accept '%s' wrong vs '%s'\n", p, - wsi->ah->initial_handshake_hash_base64); + wsi->http.ah->initial_handshake_hash_base64); *cce = "HS: Accept hash wrong"; goto bail2; } diff --git a/lib/roles/ws/ops-ws.c b/lib/roles/ws/ops-ws.c index f94b0ed67..13402b46e 100644 --- a/lib/roles/ws/ops-ws.c +++ b/lib/roles/ws/ops-ws.c @@ -1023,7 +1023,7 @@ read: goto drain; } - if (!(pollfd->revents & pollfd->events & LWS_POLLIN) && !wsi->ah) + if (!(pollfd->revents & pollfd->events & LWS_POLLIN) && !wsi->http.ah) return LWS_HPI_RET_HANDLED; if (lws_is_flowcontrolled(wsi)) { @@ -1129,7 +1129,7 @@ drain: ebuf.len = 0; } while (m); - if (wsi->ah + if (wsi->http.ah #if !defined(LWS_NO_CLIENT) && !wsi->client_h2_alpn #endif diff --git a/lib/service.c b/lib/service.c index 226bf96b6..cf2f2b445 100644 --- a/lib/service.c +++ b/lib/service.c @@ -240,8 +240,8 @@ __lws_service_timeout_check(struct lws *wsi, time_t sec) "(did hdr %d, ah %p, wl %d, pfd " "events %d) %llu vs %llu\n", (void *)wsi, wsi->pending_timeout, - wsi->hdr_parsing_completed, wsi->ah, - pt->ah_wait_list_length, n, + wsi->hdr_parsing_completed, wsi->http.ah, + pt->http.ah_wait_list_length, n, (unsigned long long)sec, (unsigned long long)wsi->pending_timeout_limit); #if defined(LWS_WITH_CGI) @@ -613,7 +613,7 @@ lws_service_periodic_checks(struct lws_context *context, * timeout status */ - ah = pt->ah_list; + ah = pt->http.ah_list; while (ah) { int len; char buf[256]; @@ -686,7 +686,7 @@ lws_service_periodic_checks(struct lws_context *context, __lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS, "excessive ah"); - ah = pt->ah_list; + ah = pt->http.ah_list; } lws_pt_unlock(pt);