mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
refactor-struct-lws-hdr
Migrate what used to be in lws_hdr_related into either the ah or the wsi, and eliminate it along with the three different ways used to access things inside it. Eg wsi->u.hdr.ah and wsi->u.http.ah become wsi->ah These changes are internal-only, in private-libwebsockets.h and lib.
This commit is contained in:
parent
93846135f2
commit
df46d8827c
13 changed files with 287 additions and 329 deletions
|
@ -50,7 +50,7 @@ lws_client_connect_2(struct lws *wsi)
|
|||
|
||||
lwsl_client("%s\n", __func__);
|
||||
|
||||
if (!wsi->u.hdr.ah) {
|
||||
if (!wsi->ah) {
|
||||
cce = "ah was NULL at cc2";
|
||||
lwsl_err("%s\n", cce);
|
||||
goto oom4;
|
||||
|
@ -519,7 +519,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->u.hdr.ah);
|
||||
_lws_header_table_reset(wsi->ah);
|
||||
|
||||
if (lws_hdr_simple_create(wsi, _WSI_TOKEN_CLIENT_PEER_ADDRESS, address))
|
||||
return NULL;
|
||||
|
@ -760,43 +760,43 @@ lws_client_connect_via_info(struct lws_client_connect_info *i)
|
|||
* things pointed to have gone out of scope.
|
||||
*/
|
||||
|
||||
wsi->u.hdr.stash = lws_malloc(sizeof(*wsi->u.hdr.stash), "client stash");
|
||||
if (!wsi->u.hdr.stash) {
|
||||
wsi->stash = lws_malloc(sizeof(*wsi->stash), "client stash");
|
||||
if (!wsi->stash) {
|
||||
lwsl_err("%s: OOM\n", __func__);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
wsi->u.hdr.stash->origin[0] = '\0';
|
||||
wsi->u.hdr.stash->protocol[0] = '\0';
|
||||
wsi->u.hdr.stash->method[0] = '\0';
|
||||
wsi->u.hdr.stash->iface[0] = '\0';
|
||||
wsi->stash->origin[0] = '\0';
|
||||
wsi->stash->protocol[0] = '\0';
|
||||
wsi->stash->method[0] = '\0';
|
||||
wsi->stash->iface[0] = '\0';
|
||||
|
||||
strncpy(wsi->u.hdr.stash->address, i->address,
|
||||
sizeof(wsi->u.hdr.stash->address) - 1);
|
||||
strncpy(wsi->u.hdr.stash->path, i->path,
|
||||
sizeof(wsi->u.hdr.stash->path) - 1);
|
||||
strncpy(wsi->u.hdr.stash->host, i->host,
|
||||
sizeof(wsi->u.hdr.stash->host) - 1);
|
||||
strncpy(wsi->stash->address, i->address,
|
||||
sizeof(wsi->stash->address) - 1);
|
||||
strncpy(wsi->stash->path, i->path,
|
||||
sizeof(wsi->stash->path) - 1);
|
||||
strncpy(wsi->stash->host, i->host,
|
||||
sizeof(wsi->stash->host) - 1);
|
||||
if (i->origin)
|
||||
strncpy(wsi->u.hdr.stash->origin, i->origin,
|
||||
sizeof(wsi->u.hdr.stash->origin) - 1);
|
||||
strncpy(wsi->stash->origin, i->origin,
|
||||
sizeof(wsi->stash->origin) - 1);
|
||||
if (i->protocol)
|
||||
strncpy(wsi->u.hdr.stash->protocol, i->protocol,
|
||||
sizeof(wsi->u.hdr.stash->protocol) - 1);
|
||||
strncpy(wsi->stash->protocol, i->protocol,
|
||||
sizeof(wsi->stash->protocol) - 1);
|
||||
if (i->method)
|
||||
strncpy(wsi->u.hdr.stash->method, i->method,
|
||||
sizeof(wsi->u.hdr.stash->method) - 1);
|
||||
strncpy(wsi->stash->method, i->method,
|
||||
sizeof(wsi->stash->method) - 1);
|
||||
if (i->iface)
|
||||
strncpy(wsi->u.hdr.stash->iface, i->iface,
|
||||
sizeof(wsi->u.hdr.stash->iface) - 1);
|
||||
strncpy(wsi->stash->iface, i->iface,
|
||||
sizeof(wsi->stash->iface) - 1);
|
||||
|
||||
wsi->u.hdr.stash->address[sizeof(wsi->u.hdr.stash->address) - 1] = '\0';
|
||||
wsi->u.hdr.stash->path[sizeof(wsi->u.hdr.stash->path) - 1] = '\0';
|
||||
wsi->u.hdr.stash->host[sizeof(wsi->u.hdr.stash->host) - 1] = '\0';
|
||||
wsi->u.hdr.stash->origin[sizeof(wsi->u.hdr.stash->origin) - 1] = '\0';
|
||||
wsi->u.hdr.stash->protocol[sizeof(wsi->u.hdr.stash->protocol) - 1] = '\0';
|
||||
wsi->u.hdr.stash->method[sizeof(wsi->u.hdr.stash->method) - 1] = '\0';
|
||||
wsi->u.hdr.stash->iface[sizeof(wsi->u.hdr.stash->iface) - 1] = '\0';
|
||||
wsi->stash->address[sizeof(wsi->stash->address) - 1] = '\0';
|
||||
wsi->stash->path[sizeof(wsi->stash->path) - 1] = '\0';
|
||||
wsi->stash->host[sizeof(wsi->stash->host) - 1] = '\0';
|
||||
wsi->stash->origin[sizeof(wsi->stash->origin) - 1] = '\0';
|
||||
wsi->stash->protocol[sizeof(wsi->stash->protocol) - 1] = '\0';
|
||||
wsi->stash->method[sizeof(wsi->stash->method) - 1] = '\0';
|
||||
wsi->stash->iface[sizeof(wsi->stash->iface) - 1] = '\0';
|
||||
|
||||
if (i->pwsi)
|
||||
*i->pwsi = wsi;
|
||||
|
@ -842,7 +842,7 @@ bail1:
|
|||
struct lws *
|
||||
lws_client_connect_via_info2(struct lws *wsi)
|
||||
{
|
||||
struct client_info_stash *stash = wsi->u.hdr.stash;
|
||||
struct client_info_stash *stash = wsi->stash;
|
||||
|
||||
if (!stash)
|
||||
return wsi;
|
||||
|
@ -886,7 +886,7 @@ lws_client_connect_via_info2(struct lws *wsi)
|
|||
|
||||
#if defined(LWS_WITH_SOCKS5)
|
||||
if (!wsi->vhost->socks_proxy_port)
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -917,7 +917,7 @@ lws_client_connect_via_info2(struct lws *wsi)
|
|||
bail1:
|
||||
#if defined(LWS_WITH_SOCKS5)
|
||||
if (!wsi->vhost->socks_proxy_port)
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
|
@ -1029,9 +1029,9 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
|
|||
n = len++;
|
||||
|
||||
/* the address we tell SOCKS proxy to connect to */
|
||||
strncpy((char *)&(pt->serv_buf[len]), wsi->u.hdr.stash->address,
|
||||
strncpy((char *)&(pt->serv_buf[len]), wsi->stash->address,
|
||||
context->pt_serv_buf_size - len);
|
||||
len += strlen(wsi->u.hdr.stash->address);
|
||||
len += strlen(wsi->stash->address);
|
||||
net_num = htons(wsi->c_port);
|
||||
|
||||
/* the port we tell SOCKS proxy to connect to */
|
||||
|
@ -1039,7 +1039,7 @@ void socks_generate_msg(struct lws *wsi, enum socks_msg_type type,
|
|||
pt->serv_buf[len++] = p[1];
|
||||
|
||||
/* the length of the address, excluding port */
|
||||
pt->serv_buf[n] = strlen(wsi->u.hdr.stash->address);
|
||||
pt->serv_buf[n] = strlen(wsi->stash->address);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -196,7 +196,7 @@ socks_reply_fail:
|
|||
lwsl_client("socks connect OK\n");
|
||||
|
||||
/* free stash since we are done with it */
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
if (lws_hdr_simple_create(wsi,
|
||||
_WSI_TOKEN_CLIENT_PEER_ADDRESS,
|
||||
wsi->vhost->socks_proxy_address))
|
||||
|
@ -350,8 +350,8 @@ start_ws_handshake:
|
|||
break;
|
||||
}
|
||||
client_http_body_sent:
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
|
||||
wsi->u.hdr.lextable_pos = 0;
|
||||
wsi->ah->parser_state = WSI_TOKEN_NAME_PART;
|
||||
wsi->ah->lextable_pos = 0;
|
||||
wsi->mode = LWSCM_WSCL_WAITING_SERVER_REPLY;
|
||||
lws_set_timeout(wsi, PENDING_TIMEOUT_AWAITING_SERVER_RESPONSE,
|
||||
context->timeout_secs);
|
||||
|
@ -391,7 +391,7 @@ client_http_body_sent:
|
|||
* definitively ready from browser pov.
|
||||
*/
|
||||
len = 1;
|
||||
while (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE &&
|
||||
while (wsi->ah->parser_state != WSI_PARSING_COMPLETE &&
|
||||
len > 0) {
|
||||
n = lws_ssl_capable_read(wsi, &c, 1);
|
||||
lws_latency(context, wsi, "send lws_issue_raw", n,
|
||||
|
@ -416,7 +416,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->u.hdr.parser_state != WSI_PARSING_COMPLETE)
|
||||
if (wsi->ah->parser_state != WSI_PARSING_COMPLETE)
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@ -495,13 +495,13 @@ lws_http_transaction_completed_client(struct lws *wsi)
|
|||
* As client, nothing new is going to come until we ask for it
|
||||
* we can drop the ah, if any
|
||||
*/
|
||||
if (wsi->u.hdr.ah) {
|
||||
if (wsi->ah) {
|
||||
lws_header_table_force_to_detachable_state(wsi);
|
||||
lws_header_table_detach(wsi, 0);
|
||||
}
|
||||
|
||||
/* If we're (re)starting on headers, need other implied init */
|
||||
wsi->u.hdr.ues = URIES_IDLE;
|
||||
wsi->ues = URIES_IDLE;
|
||||
|
||||
lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi);
|
||||
|
||||
|
@ -512,10 +512,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->u.http.ah)
|
||||
if (!wsi->ah)
|
||||
return 0;
|
||||
|
||||
return wsi->u.http.ah->http_response;
|
||||
return wsi->ah->http_response;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -539,16 +539,16 @@ lws_client_interpret_server_handshake(struct lws *wsi)
|
|||
int more = 1;
|
||||
void *v;
|
||||
#endif
|
||||
if (wsi->u.hdr.stash)
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
if (wsi->stash)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
|
||||
ah = wsi->u.hdr.ah;
|
||||
ah = wsi->ah;
|
||||
if (!wsi->do_ws) {
|
||||
/* we are being an http client...
|
||||
*/
|
||||
lws_union_transition(wsi, LWSCM_HTTP_CLIENT_ACCEPTED);
|
||||
wsi->state = LWSS_CLIENT_HTTP_ESTABLISHED;
|
||||
wsi->u.http.ah = ah;
|
||||
wsi->ah = ah;
|
||||
ah->http_response = 0;
|
||||
}
|
||||
|
||||
|
@ -1017,9 +1017,9 @@ check_accept:
|
|||
*/
|
||||
|
||||
p = lws_hdr_simple_ptr(wsi, WSI_TOKEN_ACCEPT);
|
||||
if (strcmp(p, wsi->u.hdr.ah->initial_handshake_hash_base64)) {
|
||||
if (strcmp(p, wsi->ah->initial_handshake_hash_base64)) {
|
||||
lwsl_warn("lws_client_int_s_hs: accept '%s' wrong vs '%s'\n", p,
|
||||
wsi->u.hdr.ah->initial_handshake_hash_base64);
|
||||
wsi->ah->initial_handshake_hash_base64);
|
||||
cce = "HS: Accept hash wrong";
|
||||
goto bail2;
|
||||
}
|
||||
|
@ -1300,8 +1300,8 @@ lws_generate_client_handshake(struct lws *wsi, char *pkt)
|
|||
lws_SHA1((unsigned char *)buf, n, (unsigned char *)hash);
|
||||
|
||||
lws_b64_encode_string(hash, 20,
|
||||
wsi->u.hdr.ah->initial_handshake_hash_base64,
|
||||
sizeof(wsi->u.hdr.ah->initial_handshake_hash_base64));
|
||||
wsi->ah->initial_handshake_hash_base64,
|
||||
sizeof(wsi->ah->initial_handshake_hash_base64));
|
||||
}
|
||||
|
||||
/* give userland a chance to append, eg, cookies */
|
||||
|
|
|
@ -114,7 +114,7 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
|||
/* fallthru */
|
||||
|
||||
case LWSS_HTTP_HEADERS:
|
||||
if (!wsi->u.hdr.ah) {
|
||||
if (!wsi->ah) {
|
||||
lwsl_err("%s: LWSS_HTTP_HEADERS: NULL ah\n", __func__);
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -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->u.h2.http.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
|
||||
if (!ah) {
|
||||
lwsl_notice("%s: no ah\n", __func__);
|
||||
|
@ -274,7 +274,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->u.h2.http.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
|
||||
ah->data[ah->pos++] = c;
|
||||
ah->frags[ah->nfrag].len++;
|
||||
|
@ -289,16 +289,16 @@ static int lws_frag_end(struct lws *wsi)
|
|||
return 1;
|
||||
|
||||
/* don't account for the terminating NUL in the logical length */
|
||||
wsi->u.h2.http.ah->frags[wsi->u.h2.http.ah->nfrag].len--;
|
||||
wsi->ah->frags[wsi->ah->nfrag].len--;
|
||||
|
||||
wsi->u.h2.http.ah->nfrag++;
|
||||
wsi->ah->nfrag++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
lws_hdr_extant(struct lws *wsi, enum lws_token_indexes h)
|
||||
{
|
||||
struct allocated_headers *ah = wsi->u.h2.http.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
int n;
|
||||
|
||||
if (!ah)
|
||||
|
@ -768,7 +768,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->u.h2.h2n;
|
||||
struct allocated_headers *ah = wsi->u.h2.http.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
unsigned int prev;
|
||||
unsigned char c1;
|
||||
int n, m;
|
||||
|
@ -795,7 +795,7 @@ int lws_hpack_interpret(struct lws *wsi, unsigned char c)
|
|||
h2n->ext_count = 0;
|
||||
h2n->hpack_hdr_len = 0;
|
||||
h2n->unknown_header = 0;
|
||||
wsi->u.hdr.parser_state = 255;
|
||||
ah->parser_state = 255;
|
||||
|
||||
if (c & 0x80) { /* 1.... indexed header field only */
|
||||
/* just a possibly-extended integer */
|
||||
|
@ -983,8 +983,8 @@ int lws_hpack_interpret(struct lws *wsi, unsigned char c)
|
|||
pre_data:
|
||||
h2n->hpack = HPKS_DATA;
|
||||
if (!h2n->value || !h2n->hdr_idx) {
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
|
||||
wsi->u.hdr.lextable_pos = 0;
|
||||
ah->parser_state = WSI_TOKEN_NAME_PART;
|
||||
ah->lextable_pos = 0;
|
||||
h2n->unknown_header = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -992,7 +992,7 @@ pre_data:
|
|||
if (h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER) {
|
||||
n = wsi->u.hdr.parser_state;
|
||||
n = ah->parser_state;
|
||||
if (n == 255) {
|
||||
n = -1;
|
||||
h2n->hdr_idx = -1;
|
||||
|
@ -1111,7 +1111,7 @@ pre_data:
|
|||
/*
|
||||
* Convert name using existing parser,
|
||||
* If h2n->unknown_header == 0, result is
|
||||
* in wsi->u.hdr.parser_state
|
||||
* in wsi->parser_state
|
||||
* using WSI_TOKEN_GET_URI.
|
||||
*
|
||||
* If unknown header h2n->unknown_header
|
||||
|
@ -1159,19 +1159,19 @@ swallow:
|
|||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER)) {
|
||||
h2n->hdr_idx = LWS_HPACK_IGNORE_ENTRY;
|
||||
lwsl_header("wsi->u.hdr.parser_state: %d\n",
|
||||
wsi->u.hdr.parser_state);
|
||||
lwsl_header("wsi->parser_state: %d\n",
|
||||
ah->parser_state);
|
||||
|
||||
if (wsi->u.hdr.parser_state == WSI_TOKEN_NAME_PART) {
|
||||
if (ah->parser_state == WSI_TOKEN_NAME_PART) {
|
||||
/* h2 headers come without the colon */
|
||||
n = lws_parse(wsi, ':');
|
||||
(void)n;
|
||||
}
|
||||
|
||||
if (wsi->u.hdr.parser_state == WSI_TOKEN_NAME_PART ||
|
||||
wsi->u.hdr.parser_state == WSI_TOKEN_SKIPPING) {
|
||||
if (ah->parser_state == WSI_TOKEN_NAME_PART ||
|
||||
ah->parser_state == WSI_TOKEN_SKIPPING) {
|
||||
h2n->unknown_header = 1;
|
||||
wsi->u.hdr.parser_state = -1;
|
||||
ah->parser_state = -1;
|
||||
wsi->seen_nonpseudoheader = 1;
|
||||
}
|
||||
}
|
||||
|
@ -1209,14 +1209,14 @@ swallow:
|
|||
* hdr is a new literal, so length is already in
|
||||
* h2n->hpack_hdr_len
|
||||
*/
|
||||
m = wsi->u.hdr.parser_state;
|
||||
m = ah->parser_state;
|
||||
if (h2n->unknown_header ||
|
||||
wsi->u.hdr.parser_state == WSI_TOKEN_NAME_PART ||
|
||||
wsi->u.hdr.parser_state == WSI_TOKEN_SKIPPING) {
|
||||
ah->parser_state == WSI_TOKEN_NAME_PART ||
|
||||
ah->parser_state == WSI_TOKEN_SKIPPING) {
|
||||
if (h2n->first_hdr_char == ':') {
|
||||
lwsl_info("HPKT_LITERAL_HDR_VALUE_INCR:"
|
||||
" end state %d unk hdr %d\n",
|
||||
wsi->u.hdr.parser_state,
|
||||
ah->parser_state,
|
||||
h2n->unknown_header);
|
||||
/* unknown pseudoheaders are illegal */
|
||||
lws_h2_goaway(nwsi,
|
||||
|
@ -1253,14 +1253,12 @@ add_it:
|
|||
if (h2n->hpack_type == HPKT_LITERAL_HDR_VALUE ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_INCR ||
|
||||
h2n->hpack_type == HPKT_LITERAL_HDR_VALUE_NEVER) {
|
||||
m = wsi->u.hdr.parser_state;
|
||||
m = ah->parser_state;
|
||||
if (m == 255)
|
||||
m = -1;
|
||||
} else {
|
||||
m = lws_token_from_index(wsi, h2n->hdr_idx, NULL, NULL,
|
||||
NULL);
|
||||
//lwsl_notice("token from index(%d) says %d\n", h2n->hdr_idx, m);
|
||||
}
|
||||
} else
|
||||
m = lws_token_from_index(wsi, h2n->hdr_idx,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
if (m != -1 && m != LWS_HPACK_IGNORE_ENTRY)
|
||||
|
|
|
@ -581,11 +581,11 @@ int lws_h2_do_pps_send(struct lws *wsi)
|
|||
goto bail;
|
||||
|
||||
/* pass on the initial headers to SID 1 */
|
||||
h2n->swsi->u.http.ah = wsi->u.http.ah;
|
||||
wsi->u.http.ah = NULL;
|
||||
h2n->swsi->ah = wsi->ah;
|
||||
wsi->ah = NULL;
|
||||
|
||||
lwsl_info("%s: inherited headers %p\n", __func__,
|
||||
h2n->swsi->u.http.ah);
|
||||
h2n->swsi->ah);
|
||||
h2n->swsi->u.h2.tx_cr =
|
||||
h2n->set.s[H2SET_INITIAL_WINDOW_SIZE];
|
||||
lwsl_info("initial tx credit on conn %p: %d\n",
|
||||
|
@ -973,7 +973,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->u.hdr.ah)
|
||||
if (!h2n->swsi->ah)
|
||||
if (lws_header_table_attach(h2n->swsi, 0)) {
|
||||
lwsl_err("%s: Failed to get ah\n", __func__);
|
||||
return 1;
|
||||
|
@ -1191,8 +1191,8 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
|
|||
|
||||
p = lws_hdr_simple_ptr(h2n->swsi, WSI_TOKEN_HTTP_COLON_METHOD);
|
||||
if (!strcmp(p, "POST"))
|
||||
h2n->swsi->u.hdr.ah->frag_index[WSI_TOKEN_POST_URI] =
|
||||
h2n->swsi->u.hdr.ah->frag_index[WSI_TOKEN_HTTP_COLON_PATH];
|
||||
h2n->swsi->ah->frag_index[WSI_TOKEN_POST_URI] =
|
||||
h2n->swsi->ah->frag_index[WSI_TOKEN_HTTP_COLON_PATH];
|
||||
|
||||
wsi->vhost->conn_stats.h2_trans++;
|
||||
|
||||
|
|
|
@ -127,13 +127,13 @@ int lws_h2_configure_if_upgraded(struct lws *wsi)
|
|||
|
||||
/* adopt the header info */
|
||||
|
||||
ah = wsi->u.hdr.ah;
|
||||
ah = wsi->ah;
|
||||
|
||||
lws_union_transition(wsi, LWSCM_HTTP2_SERVING);
|
||||
wsi->state = LWSS_HTTP2_AWAIT_CLIENT_PREFACE;
|
||||
|
||||
/* http2 union member has http union struct at start */
|
||||
wsi->u.http.ah = ah;
|
||||
wsi->ah = ah;
|
||||
|
||||
wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n), "h2n");
|
||||
if (!wsi->u.h2.h2n)
|
||||
|
|
|
@ -433,8 +433,8 @@ lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason)
|
|||
wsi->mode == LWSCM_WSCL_WAITING_SOCKS_GREETING_REPLY ||
|
||||
wsi->mode == LWSCM_WSCL_WAITING_SOCKS_CONNECT_REPLY ||
|
||||
wsi->mode == LWSCM_WSCL_WAITING_SOCKS_AUTH_REPLY)
|
||||
if (wsi->u.hdr.stash)
|
||||
lws_free_set_NULL(wsi->u.hdr.stash);
|
||||
if (wsi->stash)
|
||||
lws_free_set_NULL(wsi->stash);
|
||||
#endif
|
||||
|
||||
if (wsi->mode == LWSCM_RAW) {
|
||||
|
@ -3076,7 +3076,7 @@ lws_stats_log_dump(struct lws_context *context)
|
|||
wl = pt->ah_wait_list;
|
||||
while (wl) {
|
||||
m++;
|
||||
wl = wl->u.hdr.ah_wait_list;
|
||||
wl = wl->ah_wait_list;
|
||||
}
|
||||
|
||||
lwsl_notice(" AH wait list count / actual: %d / %d\n",
|
||||
|
|
|
@ -326,7 +326,7 @@ esp8266_cb_rx(void *arg, char *data, unsigned short len)
|
|||
* if we're doing HTTP headers, and we have no ah, check if there is
|
||||
* a free ah, if not, have to buffer it
|
||||
*/
|
||||
if (!wsi->hdr_parsing_completed && !wsi->u.hdr.ah) {
|
||||
if (!wsi->hdr_parsing_completed && !wsi->ah) {
|
||||
for (n = 0; n < wsi->context->max_http_header_pool; n++)
|
||||
if (!pt->ah_pool[n].in_use)
|
||||
break;
|
||||
|
|
|
@ -843,19 +843,27 @@ struct allocated_headers {
|
|||
#else
|
||||
uint8_t rx[2048];
|
||||
#endif
|
||||
|
||||
int16_t rxpos;
|
||||
int16_t rxlen;
|
||||
uint32_t pos;
|
||||
uint32_t http_response;
|
||||
int hdr_token_idx;
|
||||
|
||||
#ifndef LWS_NO_CLIENT
|
||||
char initial_handshake_hash_base64[30];
|
||||
#endif
|
||||
|
||||
uint32_t pos;
|
||||
uint32_t http_response;
|
||||
uint32_t current_token_limit;
|
||||
int hdr_token_idx;
|
||||
|
||||
int16_t rxpos;
|
||||
int16_t rxlen;
|
||||
int16_t lextable_pos;
|
||||
|
||||
uint8_t in_use;
|
||||
uint8_t nfrag;
|
||||
char /*enum uri_path_states */ ups;
|
||||
char /*enum uri_esc_states */ ues;
|
||||
|
||||
char esc_stash;
|
||||
char post_literal_equal;
|
||||
uint8_t /* enum lws_token_indexes */ parser_state;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -1384,18 +1392,6 @@ enum uri_esc_states {
|
|||
URIES_SEEN_PERCENT_H1,
|
||||
};
|
||||
|
||||
/* notice that these union members:
|
||||
*
|
||||
* hdr
|
||||
* http
|
||||
* http2
|
||||
*
|
||||
* all have a pointer to allocated_headers struct as their first member.
|
||||
*
|
||||
* It means for allocated_headers access, the three union paths can all be
|
||||
* used interchangeably to access the same data
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LWS_NO_CLIENT
|
||||
struct client_info_stash {
|
||||
|
@ -1409,25 +1405,6 @@ struct client_info_stash {
|
|||
};
|
||||
#endif
|
||||
|
||||
struct _lws_header_related {
|
||||
/* MUST be first in struct */
|
||||
struct allocated_headers *ah;
|
||||
struct lws *ah_wait_list;
|
||||
unsigned char *preamble_rx;
|
||||
#ifndef LWS_NO_CLIENT
|
||||
struct client_info_stash *stash;
|
||||
#endif
|
||||
unsigned int preamble_rx_len;
|
||||
enum uri_path_states ups;
|
||||
enum uri_esc_states ues;
|
||||
short lextable_pos;
|
||||
unsigned int current_token_limit;
|
||||
|
||||
char esc_stash;
|
||||
char post_literal_equal;
|
||||
unsigned char parser_state; /* enum lws_token_indexes */
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_RANGES)
|
||||
enum range_states {
|
||||
LWSRS_NO_ACTIVE_RANGE,
|
||||
|
@ -1456,14 +1433,6 @@ lws_ranges_reset(struct lws_range_parsing *rp);
|
|||
#endif
|
||||
|
||||
struct _lws_http_mode_related {
|
||||
/* MUST be first in struct */
|
||||
struct allocated_headers *ah; /* mirroring _lws_header_related */
|
||||
struct lws *ah_wait_list;
|
||||
unsigned char *preamble_rx;
|
||||
#ifndef LWS_NO_CLIENT
|
||||
struct client_info_stash *stash;
|
||||
#endif
|
||||
unsigned int preamble_rx_len;
|
||||
struct lws *new_wsi_list;
|
||||
lws_filepos_t filepos;
|
||||
lws_filepos_t filelen;
|
||||
|
@ -1796,8 +1765,6 @@ struct _lws_h2_related {
|
|||
#endif
|
||||
|
||||
struct _lws_websocket_related {
|
||||
/* cheapest way to deal with ah overlap with ws union transition */
|
||||
struct _lws_header_related hdr;
|
||||
char *rx_ubuf;
|
||||
unsigned int rx_ubuf_alloc;
|
||||
struct lws *rx_draining_ext_list;
|
||||
|
@ -1912,8 +1879,8 @@ struct lws_access_log {
|
|||
#endif
|
||||
|
||||
struct lws {
|
||||
|
||||
/* structs */
|
||||
|
||||
/* members with mutually exclusive lifetimes are unionized */
|
||||
|
||||
union u {
|
||||
|
@ -1921,7 +1888,6 @@ struct lws {
|
|||
#ifdef LWS_WITH_HTTP2
|
||||
struct _lws_h2_related h2;
|
||||
#endif
|
||||
struct _lws_header_related hdr;
|
||||
struct _lws_websocket_related ws;
|
||||
} u;
|
||||
|
||||
|
@ -1955,7 +1921,12 @@ struct lws {
|
|||
#if defined(LWS_WITH_PEER_LIMITS)
|
||||
struct lws_peer *peer;
|
||||
#endif
|
||||
|
||||
struct allocated_headers *ah;
|
||||
struct lws *ah_wait_list;
|
||||
unsigned char *preamble_rx;
|
||||
#ifndef LWS_NO_CLIENT
|
||||
struct client_info_stash *stash;
|
||||
#endif
|
||||
void *user_space;
|
||||
void *opaque_parent_data;
|
||||
/* rxflow handling */
|
||||
|
@ -1996,6 +1967,7 @@ struct lws {
|
|||
int position_in_fds_table;
|
||||
uint32_t rxflow_len;
|
||||
uint32_t rxflow_pos;
|
||||
uint32_t preamble_rx_len;
|
||||
unsigned int trunc_alloc_len; /* size of malloc */
|
||||
unsigned int trunc_offset; /* where we are in terms of spilling */
|
||||
unsigned int trunc_len; /* how much is buffered */
|
||||
|
|
|
@ -196,7 +196,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->u.hdr.ah) {
|
||||
if (wsi->ah) {
|
||||
static const unsigned char meths[] = {
|
||||
WSI_TOKEN_GET_URI,
|
||||
WSI_TOKEN_POST_URI,
|
||||
|
|
|
@ -121,7 +121,7 @@ _lws_header_table_reset(struct allocated_headers *ah)
|
|||
void
|
||||
lws_header_table_reset(struct lws *wsi, int autoservice)
|
||||
{
|
||||
struct allocated_headers *ah = wsi->u.hdr.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pollfd *pfd;
|
||||
|
||||
|
@ -132,8 +132,8 @@ lws_header_table_reset(struct lws *wsi, int autoservice)
|
|||
|
||||
_lws_header_table_reset(ah);
|
||||
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
|
||||
wsi->u.hdr.lextable_pos = 0;
|
||||
ah->parser_state = WSI_TOKEN_NAME_PART;
|
||||
ah->lextable_pos = 0;
|
||||
|
||||
/* since we will restart the ah, our new headers are not completed */
|
||||
wsi->hdr_parsing_completed = 0;
|
||||
|
@ -148,11 +148,10 @@ lws_header_table_reset(struct lws *wsi, int autoservice)
|
|||
* if we inherited pending rx (from socket adoption deferred
|
||||
* processing), apply and free it.
|
||||
*/
|
||||
if (wsi->u.hdr.preamble_rx) {
|
||||
memcpy(ah->rx, wsi->u.hdr.preamble_rx,
|
||||
wsi->u.hdr.preamble_rx_len);
|
||||
ah->rxlen = wsi->u.hdr.preamble_rx_len;
|
||||
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
|
||||
if (wsi->preamble_rx) {
|
||||
memcpy(ah->rx, wsi->preamble_rx, wsi->preamble_rx_len);
|
||||
ah->rxlen = wsi->preamble_rx_len;
|
||||
lws_free_set_NULL(wsi->preamble_rx);
|
||||
|
||||
if (autoservice) {
|
||||
lwsl_debug("%s: service on readbuf ah\n", __func__);
|
||||
|
@ -180,11 +179,11 @@ _lws_header_ensure_we_are_on_waiting_list(struct lws *wsi)
|
|||
while (*pwsi) {
|
||||
if (*pwsi == wsi)
|
||||
return;
|
||||
pwsi = &(*pwsi)->u.hdr.ah_wait_list;
|
||||
pwsi = &(*pwsi)->ah_wait_list;
|
||||
}
|
||||
|
||||
lwsl_info("%s: wsi: %p\n", __func__, wsi);
|
||||
wsi->u.hdr.ah_wait_list = pt->ah_wait_list;
|
||||
wsi->ah_wait_list = pt->ah_wait_list;
|
||||
pt->ah_wait_list = wsi;
|
||||
pt->ah_wait_list_length++;
|
||||
|
||||
|
@ -203,14 +202,14 @@ __lws_remove_from_ah_waiting_list(struct lws *wsi)
|
|||
if (*pwsi == wsi) {
|
||||
lwsl_info("%s: wsi %p\n", __func__, wsi);
|
||||
/* point prev guy to our next */
|
||||
*pwsi = wsi->u.hdr.ah_wait_list;
|
||||
*pwsi = wsi->ah_wait_list;
|
||||
/* we shouldn't point anywhere now */
|
||||
wsi->u.hdr.ah_wait_list = NULL;
|
||||
wsi->ah_wait_list = NULL;
|
||||
pt->ah_wait_list_length--;
|
||||
|
||||
return 1;
|
||||
}
|
||||
pwsi = &(*pwsi)->u.hdr.ah_wait_list;
|
||||
pwsi = &(*pwsi)->ah_wait_list;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -225,11 +224,11 @@ 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->u.hdr.ah, wsi->tsi,
|
||||
(void *)wsi, (void *)wsi->ah, wsi->tsi,
|
||||
pt->ah_count_in_use);
|
||||
|
||||
/* if we are already bound to one, just clear it down */
|
||||
if (wsi->u.hdr.ah) {
|
||||
if (wsi->ah) {
|
||||
lwsl_info("%s: cleardown\n", __func__);
|
||||
goto reset;
|
||||
}
|
||||
|
@ -260,15 +259,15 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
|
|||
|
||||
__lws_remove_from_ah_waiting_list(wsi);
|
||||
|
||||
wsi->u.hdr.ah = _lws_create_ah(pt, context->max_http_header_data);
|
||||
if (!wsi->u.hdr.ah) { /* we could not create an ah */
|
||||
wsi->ah = _lws_create_ah(pt, context->max_http_header_data);
|
||||
if (!wsi->ah) { /* we could not create an ah */
|
||||
_lws_header_ensure_we_are_on_waiting_list(wsi);
|
||||
|
||||
goto bail;
|
||||
}
|
||||
|
||||
wsi->u.hdr.ah->in_use = 1;
|
||||
wsi->u.hdr.ah->wsi = wsi; /* mark our owner */
|
||||
wsi->ah->in_use = 1;
|
||||
wsi->ah->wsi = wsi; /* mark our owner */
|
||||
pt->ah_count_in_use++;
|
||||
|
||||
#if defined(LWS_WITH_PEER_LIMITS)
|
||||
|
@ -279,15 +278,15 @@ lws_header_table_attach(struct lws *wsi, int autoservice)
|
|||
_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->u.hdr.ah, pt->ah_count_in_use);
|
||||
(void *)wsi, (void *)wsi->ah, pt->ah_count_in_use);
|
||||
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
reset:
|
||||
|
||||
/* and reset the rx state */
|
||||
wsi->u.hdr.ah->rxpos = 0;
|
||||
wsi->u.hdr.ah->rxlen = 0;
|
||||
wsi->ah->rxpos = 0;
|
||||
wsi->ah->rxlen = 0;
|
||||
|
||||
lws_header_table_reset(wsi, autoservice);
|
||||
|
||||
|
@ -311,9 +310,9 @@ bail:
|
|||
void
|
||||
lws_header_table_force_to_detachable_state(struct lws *wsi)
|
||||
{
|
||||
if (wsi->u.hdr.ah) {
|
||||
wsi->u.hdr.ah->rxpos = -1;
|
||||
wsi->u.hdr.ah->rxlen = -1;
|
||||
if (wsi->ah) {
|
||||
wsi->ah->rxpos = -1;
|
||||
wsi->ah->rxlen = -1;
|
||||
wsi->hdr_parsing_completed = 1;
|
||||
}
|
||||
}
|
||||
|
@ -321,7 +320,7 @@ lws_header_table_force_to_detachable_state(struct lws *wsi)
|
|||
int
|
||||
lws_header_table_is_in_detachable_state(struct lws *wsi)
|
||||
{
|
||||
struct allocated_headers *ah = wsi->u.hdr.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
|
||||
return ah && ah->rxpos == ah->rxlen && wsi->hdr_parsing_completed;
|
||||
}
|
||||
|
@ -329,7 +328,7 @@ lws_header_table_is_in_detachable_state(struct lws *wsi)
|
|||
int lws_header_table_detach(struct lws *wsi, int autoservice)
|
||||
{
|
||||
struct lws_context *context = wsi->context;
|
||||
struct allocated_headers *ah = wsi->u.hdr.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
|
||||
struct lws_pollargs pa;
|
||||
struct lws **pwsi, **pwsi_eligible;
|
||||
|
@ -346,8 +345,8 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
|
|||
(void *)wsi, (void *)ah, wsi->tsi,
|
||||
pt->ah_count_in_use);
|
||||
|
||||
if (wsi->u.hdr.preamble_rx)
|
||||
lws_free_set_NULL(wsi->u.hdr.preamble_rx);
|
||||
if (wsi->preamble_rx)
|
||||
lws_free_set_NULL(wsi->preamble_rx);
|
||||
|
||||
/* may not be detached while he still has unprocessed rx */
|
||||
if (!lws_header_table_is_in_detachable_state(wsi)) {
|
||||
|
@ -380,7 +379,7 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
|
|||
assert(pt->ah_count_in_use > 0);
|
||||
/* and this specific one should have been in use */
|
||||
assert(ah->in_use);
|
||||
wsi->u.hdr.ah = NULL;
|
||||
memset(&wsi->ah, 0, sizeof(wsi->ah));
|
||||
ah->wsi = NULL; /* no owner */
|
||||
#if defined(LWS_WITH_PEER_LIMITS)
|
||||
lws_peer_track_ah_detach(context, wsi->peer);
|
||||
|
@ -411,11 +410,11 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
|
|||
}
|
||||
#if defined(LWS_WITH_PEER_LIMITS)
|
||||
else
|
||||
if (!(*pwsi)->u.hdr.ah_wait_list)
|
||||
if (!(*pwsi)->ah_wait_list)
|
||||
lws_stats_atomic_bump(context, pt,
|
||||
LWSSTATS_C_PEER_LIMIT_AH_DENIED, 1);
|
||||
#endif
|
||||
pwsi = &(*pwsi)->u.hdr.ah_wait_list;
|
||||
pwsi = &(*pwsi)->ah_wait_list;
|
||||
}
|
||||
|
||||
if (!wsi) /* everybody waiting already has too many ah... */
|
||||
|
@ -423,7 +422,7 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
|
|||
|
||||
lwsl_info("%s: last eligible wsi in wait list %p\n", __func__, wsi);
|
||||
|
||||
wsi->u.hdr.ah = ah;
|
||||
wsi->ah = ah;
|
||||
ah->wsi = wsi; /* new owner */
|
||||
|
||||
/* and reset the rx state */
|
||||
|
@ -446,9 +445,9 @@ int lws_header_table_detach(struct lws *wsi, int autoservice)
|
|||
}
|
||||
|
||||
/* point prev guy to next guy in list instead */
|
||||
*pwsi_eligible = wsi->u.hdr.ah_wait_list;
|
||||
*pwsi_eligible = wsi->ah_wait_list;
|
||||
/* the guy who got one is out of the list */
|
||||
wsi->u.hdr.ah_wait_list = NULL;
|
||||
wsi->ah_wait_list = NULL;
|
||||
pt->ah_wait_list_length--;
|
||||
|
||||
#ifndef LWS_NO_CLIENT
|
||||
|
@ -488,16 +487,16 @@ lws_hdr_fragment_length(struct lws *wsi, enum lws_token_indexes h, int frag_idx)
|
|||
{
|
||||
int n;
|
||||
|
||||
if (!wsi->u.hdr.ah)
|
||||
if (!wsi->ah)
|
||||
return 0;
|
||||
|
||||
n = wsi->u.hdr.ah->frag_index[h];
|
||||
n = wsi->ah->frag_index[h];
|
||||
if (!n)
|
||||
return 0;
|
||||
do {
|
||||
if (!frag_idx)
|
||||
return wsi->u.hdr.ah->frags[n].len;
|
||||
n = wsi->u.hdr.ah->frags[n].nfrag;
|
||||
return wsi->ah->frags[n].len;
|
||||
n = wsi->ah->frags[n].nfrag;
|
||||
} while (frag_idx-- && n);
|
||||
|
||||
return 0;
|
||||
|
@ -508,15 +507,15 @@ LWS_VISIBLE int lws_hdr_total_length(struct lws *wsi, enum lws_token_indexes h)
|
|||
int n;
|
||||
int len = 0;
|
||||
|
||||
if (!wsi->u.hdr.ah)
|
||||
if (!wsi->ah)
|
||||
return 0;
|
||||
|
||||
n = wsi->u.hdr.ah->frag_index[h];
|
||||
n = wsi->ah->frag_index[h];
|
||||
if (!n)
|
||||
return 0;
|
||||
do {
|
||||
len += wsi->u.hdr.ah->frags[n].len;
|
||||
n = wsi->u.hdr.ah->frags[n].nfrag;
|
||||
len += wsi->ah->frags[n].len;
|
||||
n = wsi->ah->frags[n].nfrag;
|
||||
} while (n);
|
||||
|
||||
return len;
|
||||
|
@ -528,29 +527,29 @@ LWS_VISIBLE int lws_hdr_copy_fragment(struct lws *wsi, char *dst, int len,
|
|||
int n = 0;
|
||||
int f;
|
||||
|
||||
if (!wsi->u.hdr.ah)
|
||||
if (!wsi->ah)
|
||||
return -1;
|
||||
|
||||
f = wsi->u.hdr.ah->frag_index[h];
|
||||
f = wsi->ah->frag_index[h];
|
||||
|
||||
if (!f)
|
||||
return -1;
|
||||
|
||||
while (n < frag_idx) {
|
||||
f = wsi->u.hdr.ah->frags[f].nfrag;
|
||||
f = wsi->ah->frags[f].nfrag;
|
||||
if (!f)
|
||||
return -1;
|
||||
n++;
|
||||
}
|
||||
|
||||
if (wsi->u.hdr.ah->frags[f].len >= len)
|
||||
if (wsi->ah->frags[f].len >= len)
|
||||
return -1;
|
||||
|
||||
memcpy(dst, wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[f].offset,
|
||||
wsi->u.hdr.ah->frags[f].len);
|
||||
dst[wsi->u.hdr.ah->frags[f].len] = '\0';
|
||||
memcpy(dst, wsi->ah->data + wsi->ah->frags[f].offset,
|
||||
wsi->ah->frags[f].len);
|
||||
dst[wsi->ah->frags[f].len] = '\0';
|
||||
|
||||
return wsi->u.hdr.ah->frags[f].len;
|
||||
return wsi->ah->frags[f].len;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len,
|
||||
|
@ -562,21 +561,21 @@ LWS_VISIBLE int lws_hdr_copy(struct lws *wsi, char *dst, int len,
|
|||
if (toklen >= len)
|
||||
return -1;
|
||||
|
||||
if (!wsi->u.hdr.ah)
|
||||
if (!wsi->ah)
|
||||
return -1;
|
||||
|
||||
n = wsi->u.hdr.ah->frag_index[h];
|
||||
n = wsi->ah->frag_index[h];
|
||||
if (!n)
|
||||
return 0;
|
||||
|
||||
do {
|
||||
if (wsi->u.hdr.ah->frags[n].len >= len)
|
||||
if (wsi->ah->frags[n].len >= len)
|
||||
return -1;
|
||||
strncpy(dst, &wsi->u.hdr.ah->data[wsi->u.hdr.ah->frags[n].offset],
|
||||
wsi->u.hdr.ah->frags[n].len);
|
||||
dst += wsi->u.hdr.ah->frags[n].len;
|
||||
len -= wsi->u.hdr.ah->frags[n].len;
|
||||
n = wsi->u.hdr.ah->frags[n].nfrag;
|
||||
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;
|
||||
} while (n);
|
||||
*dst = '\0';
|
||||
|
||||
|
@ -587,21 +586,21 @@ char *lws_hdr_simple_ptr(struct lws *wsi, enum lws_token_indexes h)
|
|||
{
|
||||
int n;
|
||||
|
||||
n = wsi->u.hdr.ah->frag_index[h];
|
||||
n = wsi->ah->frag_index[h];
|
||||
if (!n)
|
||||
return NULL;
|
||||
|
||||
return wsi->u.hdr.ah->data + wsi->u.hdr.ah->frags[n].offset;
|
||||
return wsi->ah->data + wsi->ah->frags[n].offset;
|
||||
}
|
||||
|
||||
int LWS_WARN_UNUSED_RESULT
|
||||
lws_pos_in_bounds(struct lws *wsi)
|
||||
{
|
||||
if (wsi->u.hdr.ah->pos <
|
||||
if (wsi->ah->pos <
|
||||
(unsigned int)wsi->context->max_http_header_data)
|
||||
return 0;
|
||||
|
||||
if ((int)wsi->u.hdr.ah->pos == wsi->context->max_http_header_data) {
|
||||
if ((int)wsi->ah->pos == wsi->context->max_http_header_data) {
|
||||
lwsl_err("Ran out of header data space\n");
|
||||
return 1;
|
||||
}
|
||||
|
@ -610,7 +609,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->u.hdr.ah->pos,
|
||||
lwsl_err("%s: pos %d, limit %d\n", __func__, wsi->ah->pos,
|
||||
wsi->context->max_http_header_data);
|
||||
assert(0);
|
||||
|
||||
|
@ -620,25 +619,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->u.hdr.ah->nfrag++;
|
||||
if (wsi->u.hdr.ah->nfrag == ARRAY_SIZE(wsi->u.hdr.ah->frags)) {
|
||||
wsi->ah->nfrag++;
|
||||
if (wsi->ah->nfrag == ARRAY_SIZE(wsi->ah->frags)) {
|
||||
lwsl_warn("More hdr frags than we can deal with, dropping\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
wsi->u.hdr.ah->frag_index[h] = wsi->u.hdr.ah->nfrag;
|
||||
wsi->ah->frag_index[h] = wsi->ah->nfrag;
|
||||
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].offset = wsi->u.hdr.ah->pos;
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len = 0;
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].nfrag = 0;
|
||||
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;
|
||||
|
||||
do {
|
||||
if (lws_pos_in_bounds(wsi))
|
||||
return -1;
|
||||
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = *s;
|
||||
wsi->ah->data[wsi->ah->pos++] = *s;
|
||||
if (*s)
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
|
||||
wsi->ah->frags[wsi->ah->nfrag].len++;
|
||||
} while (*s++);
|
||||
|
||||
return 0;
|
||||
|
@ -666,27 +665,27 @@ issue_char(struct lws *wsi, unsigned char c)
|
|||
if (lws_pos_in_bounds(wsi))
|
||||
return -1;
|
||||
|
||||
frag_len = wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len;
|
||||
frag_len = wsi->ah->frags[wsi->ah->nfrag].len;
|
||||
/*
|
||||
* If we haven't hit the token limit, just copy the character into
|
||||
* the header
|
||||
*/
|
||||
if (frag_len < wsi->u.hdr.current_token_limit) {
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = c;
|
||||
if (frag_len < wsi->ah->current_token_limit) {
|
||||
wsi->ah->data[wsi->ah->pos++] = c;
|
||||
if (c)
|
||||
wsi->u.hdr.ah->frags[wsi->u.hdr.ah->nfrag].len++;
|
||||
wsi->ah->frags[wsi->ah->nfrag].len++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Insert a null character when we *hit* the limit: */
|
||||
if (frag_len == wsi->u.hdr.current_token_limit) {
|
||||
if (frag_len == wsi->ah->current_token_limit) {
|
||||
if (lws_pos_in_bounds(wsi))
|
||||
return -1;
|
||||
|
||||
wsi->u.hdr.ah->data[wsi->u.hdr.ah->pos++] = '\0';
|
||||
wsi->ah->data[wsi->ah->pos++] = '\0';
|
||||
lwsl_warn("header %i exceeds limit %d\n",
|
||||
wsi->u.hdr.parser_state,
|
||||
wsi->u.hdr.current_token_limit);
|
||||
wsi->ah->parser_state,
|
||||
wsi->ah->current_token_limit);
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -695,18 +694,20 @@ issue_char(struct lws *wsi, unsigned char c)
|
|||
int
|
||||
lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
||||
{
|
||||
struct allocated_headers *ah = wsi->u.hdr.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
unsigned int enc = 0;
|
||||
uint8_t c = *_c;
|
||||
|
||||
// lwsl_notice("ah->ups %d\n", ah->ups);
|
||||
|
||||
/*
|
||||
* PRIORITY 1
|
||||
* special URI processing... convert %xx
|
||||
*/
|
||||
switch (wsi->u.hdr.ues) {
|
||||
switch (ah->ues) {
|
||||
case URIES_IDLE:
|
||||
if (c == '%') {
|
||||
wsi->u.hdr.ues = URIES_SEEN_PERCENT;
|
||||
ah->ues = URIES_SEEN_PERCENT;
|
||||
goto swallow;
|
||||
}
|
||||
break;
|
||||
|
@ -715,8 +716,8 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
/* illegal post-% char */
|
||||
goto forbid;
|
||||
|
||||
wsi->u.hdr.esc_stash = c;
|
||||
wsi->u.hdr.ues = URIES_SEEN_PERCENT_H1;
|
||||
ah->esc_stash = c;
|
||||
ah->ues = URIES_SEEN_PERCENT_H1;
|
||||
goto swallow;
|
||||
|
||||
case URIES_SEEN_PERCENT_H1:
|
||||
|
@ -724,11 +725,11 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
/* illegal post-% char */
|
||||
goto forbid;
|
||||
|
||||
*_c = (char_to_hex(wsi->u.hdr.esc_stash) << 4) |
|
||||
*_c = (char_to_hex(ah->esc_stash) << 4) |
|
||||
char_to_hex(c);
|
||||
c = *_c;
|
||||
enc = 1;
|
||||
wsi->u.hdr.ues = URIES_IDLE;
|
||||
ah->ues = URIES_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -741,7 +742,7 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
* leave /.dir or whatever alone
|
||||
*/
|
||||
|
||||
switch (wsi->u.hdr.ups) {
|
||||
switch (ah->ups) {
|
||||
case URIPS_IDLE:
|
||||
if (!c)
|
||||
return -1;
|
||||
|
@ -757,7 +758,7 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
if (ah->nfrag >= ARRAY_SIZE(ah->frags))
|
||||
goto excessive;
|
||||
/* start next fragment after the & */
|
||||
wsi->u.hdr.post_literal_equal = 0;
|
||||
ah->post_literal_equal = 0;
|
||||
ah->frags[ah->nfrag].offset = ah->pos;
|
||||
ah->frags[ah->nfrag].len = 0;
|
||||
ah->frags[ah->nfrag].nfrag = 0;
|
||||
|
@ -766,14 +767,14 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
/* uriencoded = in the name part, disallow */
|
||||
if (c == '=' && enc &&
|
||||
ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] &&
|
||||
!wsi->u.hdr.post_literal_equal) {
|
||||
!ah->post_literal_equal) {
|
||||
c = '_';
|
||||
*_c =c;
|
||||
}
|
||||
|
||||
/* after the real =, we don't care how many = */
|
||||
if (c == '=' && !enc)
|
||||
wsi->u.hdr.post_literal_equal = 1;
|
||||
ah->post_literal_equal = 1;
|
||||
|
||||
/* + to space */
|
||||
if (c == '+' && !enc) {
|
||||
|
@ -782,7 +783,7 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
}
|
||||
/* issue the first / always */
|
||||
if (c == '/' && !ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS])
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
||||
ah->ups = URIPS_SEEN_SLASH;
|
||||
break;
|
||||
case URIPS_SEEN_SLASH:
|
||||
/* swallow subsequent slashes */
|
||||
|
@ -790,24 +791,24 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
goto swallow;
|
||||
/* track and swallow the first . after / */
|
||||
if (c == '.') {
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT;
|
||||
ah->ups = URIPS_SEEN_SLASH_DOT;
|
||||
goto swallow;
|
||||
}
|
||||
wsi->u.hdr.ups = URIPS_IDLE;
|
||||
ah->ups = URIPS_IDLE;
|
||||
break;
|
||||
case URIPS_SEEN_SLASH_DOT:
|
||||
/* swallow second . */
|
||||
if (c == '.') {
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH_DOT_DOT;
|
||||
ah->ups = URIPS_SEEN_SLASH_DOT_DOT;
|
||||
goto swallow;
|
||||
}
|
||||
/* change /./ to / */
|
||||
if (c == '/') {
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
||||
ah->ups = URIPS_SEEN_SLASH;
|
||||
goto swallow;
|
||||
}
|
||||
/* it was like /.dir ... regurgitate the . */
|
||||
wsi->u.hdr.ups = URIPS_IDLE;
|
||||
ah->ups = URIPS_IDLE;
|
||||
if (issue_char(wsi, '.') < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
@ -830,7 +831,7 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
} while (ah->frags[ah->nfrag].len > 1 &&
|
||||
ah->data[ah->pos] != '/');
|
||||
}
|
||||
wsi->u.hdr.ups = URIPS_SEEN_SLASH;
|
||||
ah->ups = URIPS_SEEN_SLASH;
|
||||
if (ah->frags[ah->nfrag].len > 1)
|
||||
break;
|
||||
goto swallow;
|
||||
|
@ -842,13 +843,13 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
return -1;
|
||||
if (issue_char(wsi, '.') < 0)
|
||||
return -1;
|
||||
wsi->u.hdr.ups = URIPS_IDLE;
|
||||
ah->ups = URIPS_IDLE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (c == '?' && !enc &&
|
||||
!ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS]) { /* start of URI arguments */
|
||||
if (wsi->u.hdr.ues != URIES_IDLE)
|
||||
if (ah->ues != URIES_IDLE)
|
||||
goto forbid;
|
||||
|
||||
/* seal off uri header */
|
||||
|
@ -863,9 +864,9 @@ lws_parse_urldecode(struct lws *wsi, uint8_t *_c)
|
|||
ah->frags[ah->nfrag].len = 0;
|
||||
ah->frags[ah->nfrag].nfrag = 0;
|
||||
|
||||
wsi->u.hdr.post_literal_equal = 0;
|
||||
ah->post_literal_equal = 0;
|
||||
ah->frag_index[WSI_TOKEN_HTTP_URI_ARGS] = ah->nfrag;
|
||||
wsi->u.hdr.ups = URIPS_IDLE;
|
||||
ah->ups = URIPS_IDLE;
|
||||
goto swallow;
|
||||
}
|
||||
|
||||
|
@ -895,26 +896,26 @@ static const unsigned char methods[] = {
|
|||
int LWS_WARN_UNUSED_RESULT
|
||||
lws_parse(struct lws *wsi, unsigned char c)
|
||||
{
|
||||
struct allocated_headers *ah = wsi->u.hdr.ah;
|
||||
struct allocated_headers *ah = wsi->ah;
|
||||
struct lws_context *context = wsi->context;
|
||||
unsigned int n, m;
|
||||
int r;
|
||||
|
||||
assert(wsi->u.hdr.ah);
|
||||
assert(wsi->ah);
|
||||
|
||||
switch (wsi->u.hdr.parser_state) {
|
||||
switch (ah->parser_state) {
|
||||
default:
|
||||
|
||||
lwsl_parser("WSI_TOK_(%d) '%c'\n", wsi->u.hdr.parser_state, c);
|
||||
lwsl_parser("WSI_TOK_(%d) '%c'\n", ah->parser_state, c);
|
||||
|
||||
/* collect into malloc'd buffers */
|
||||
/* optional initial space swallow */
|
||||
if (!ah->frags[ah->frag_index[wsi->u.hdr.parser_state]].len &&
|
||||
if (!ah->frags[ah->frag_index[ah->parser_state]].len &&
|
||||
c == ' ')
|
||||
break;
|
||||
|
||||
for (m = 0; m < ARRAY_SIZE(methods); m++)
|
||||
if (wsi->u.hdr.parser_state == methods[m])
|
||||
if (ah->parser_state == methods[m])
|
||||
break;
|
||||
if (m == ARRAY_SIZE(methods))
|
||||
/* it was not any of the methods */
|
||||
|
@ -928,7 +929,7 @@ lws_parse(struct lws *wsi, unsigned char c)
|
|||
if (issue_char(wsi, '/') < 0)
|
||||
return -1;
|
||||
|
||||
if (wsi->u.hdr.ups == URIPS_SEEN_SLASH_DOT_DOT) {
|
||||
if (ah->ups == URIPS_SEEN_SLASH_DOT_DOT) {
|
||||
/*
|
||||
* back up one dir level if possible
|
||||
* safe against header fragmentation because
|
||||
|
@ -948,7 +949,7 @@ lws_parse(struct lws *wsi, unsigned char c)
|
|||
/* begin parsing HTTP version: */
|
||||
if (issue_char(wsi, '\0') < 0)
|
||||
return -1;
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_HTTP;
|
||||
ah->parser_state = WSI_TOKEN_HTTP;
|
||||
goto start_fragment;
|
||||
}
|
||||
|
||||
|
@ -967,13 +968,13 @@ lws_parse(struct lws *wsi, unsigned char c)
|
|||
}
|
||||
check_eol:
|
||||
/* bail at EOL */
|
||||
if (wsi->u.hdr.parser_state != WSI_TOKEN_CHALLENGE &&
|
||||
if (ah->parser_state != WSI_TOKEN_CHALLENGE &&
|
||||
c == '\x0d') {
|
||||
if (wsi->u.hdr.ues != URIES_IDLE)
|
||||
if (ah->ues != URIES_IDLE)
|
||||
goto forbid;
|
||||
|
||||
c = '\0';
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
|
||||
ah->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
|
||||
lwsl_parser("*\n");
|
||||
}
|
||||
|
||||
|
@ -981,25 +982,26 @@ check_eol:
|
|||
if ((int)n < 0)
|
||||
return -1;
|
||||
if (n > 0)
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||
ah->parser_state = WSI_TOKEN_SKIPPING;
|
||||
|
||||
swallow:
|
||||
/* per-protocol end of headers management */
|
||||
|
||||
if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
|
||||
if (ah->parser_state == WSI_TOKEN_CHALLENGE)
|
||||
goto set_parsing_complete;
|
||||
break;
|
||||
|
||||
/* collecting and checking a name part */
|
||||
case WSI_TOKEN_NAME_PART:
|
||||
lwsl_parser("WSI_TOKEN_NAME_PART '%c' 0x%02X (mode=%d) wsi->u.hdr.lextable_pos=%d\n", c, c, wsi->mode, wsi->u.hdr.lextable_pos);
|
||||
lwsl_parser("WSI_TOKEN_NAME_PART '%c' 0x%02X (mode=%d) "
|
||||
"wsi->lextable_pos=%d\n", c, c, wsi->mode,
|
||||
ah->lextable_pos);
|
||||
|
||||
wsi->u.hdr.lextable_pos =
|
||||
lextable_decode(wsi->u.hdr.lextable_pos, c);
|
||||
ah->lextable_pos = lextable_decode(ah->lextable_pos, c);
|
||||
/*
|
||||
* Server needs to look out for unknown methods...
|
||||
*/
|
||||
if (wsi->u.hdr.lextable_pos < 0 &&
|
||||
if (ah->lextable_pos < 0 &&
|
||||
(wsi->mode == LWSCM_HTTP_SERVING)) {
|
||||
/* this is not a header we know about */
|
||||
for (m = 0; m < ARRAY_SIZE(methods); m++)
|
||||
|
@ -1008,7 +1010,7 @@ swallow:
|
|||
* already had the method, no idea what
|
||||
* this crap from the client is, ignore
|
||||
*/
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||
ah->parser_state = WSI_TOKEN_SKIPPING;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
@ -1032,16 +1034,16 @@ swallow:
|
|||
* ...otherwise for a client, let him ignore unknown headers
|
||||
* coming from the server
|
||||
*/
|
||||
if (wsi->u.hdr.lextable_pos < 0) {
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||
if (ah->lextable_pos < 0) {
|
||||
ah->parser_state = WSI_TOKEN_SKIPPING;
|
||||
break;
|
||||
}
|
||||
|
||||
if (lextable[wsi->u.hdr.lextable_pos] < FAIL_CHAR) {
|
||||
if (lextable[ah->lextable_pos] < FAIL_CHAR) {
|
||||
/* terminal state */
|
||||
|
||||
n = ((unsigned int)lextable[wsi->u.hdr.lextable_pos] << 8) |
|
||||
lextable[wsi->u.hdr.lextable_pos + 1];
|
||||
n = ((unsigned int)lextable[ah->lextable_pos] << 8) |
|
||||
lextable[ah->lextable_pos + 1];
|
||||
|
||||
lwsl_parser("known hdr %d\n", n);
|
||||
for (m = 0; m < ARRAY_SIZE(methods); m++)
|
||||
|
@ -1058,18 +1060,19 @@ swallow:
|
|||
if (n == WSI_TOKEN_SWORIGIN)
|
||||
n = WSI_TOKEN_ORIGIN;
|
||||
|
||||
wsi->u.hdr.parser_state = (enum lws_token_indexes)
|
||||
ah->parser_state = (enum lws_token_indexes)
|
||||
(WSI_TOKEN_GET_URI + n);
|
||||
ah->ups = URIPS_IDLE;
|
||||
|
||||
if (context->token_limits)
|
||||
wsi->u.hdr.current_token_limit =
|
||||
ah->current_token_limit =
|
||||
context->token_limits->token_limit[
|
||||
wsi->u.hdr.parser_state];
|
||||
ah->parser_state];
|
||||
else
|
||||
wsi->u.hdr.current_token_limit =
|
||||
ah->current_token_limit =
|
||||
wsi->context->max_http_header_data;
|
||||
|
||||
if (wsi->u.hdr.parser_state == WSI_TOKEN_CHALLENGE)
|
||||
if (ah->parser_state == WSI_TOKEN_CHALLENGE)
|
||||
goto set_parsing_complete;
|
||||
|
||||
goto start_fragment;
|
||||
|
@ -1089,10 +1092,10 @@ excessive:
|
|||
ah->frags[ah->nfrag].nfrag = 0;
|
||||
ah->frags[ah->nfrag].flags = 2;
|
||||
|
||||
n = ah->frag_index[wsi->u.hdr.parser_state];
|
||||
n = ah->frag_index[ah->parser_state];
|
||||
if (!n) { /* first fragment */
|
||||
ah->frag_index[wsi->u.hdr.parser_state] = ah->nfrag;
|
||||
ah->hdr_token_idx = wsi->u.hdr.parser_state;
|
||||
ah->frag_index[ah->parser_state] = ah->nfrag;
|
||||
ah->hdr_token_idx = ah->parser_state;
|
||||
break;
|
||||
}
|
||||
/* continuation */
|
||||
|
@ -1109,18 +1112,18 @@ excessive:
|
|||
lwsl_parser("WSI_TOKEN_SKIPPING '%c'\n", c);
|
||||
|
||||
if (c == '\x0d')
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
|
||||
ah->parser_state = WSI_TOKEN_SKIPPING_SAW_CR;
|
||||
break;
|
||||
|
||||
case WSI_TOKEN_SKIPPING_SAW_CR:
|
||||
lwsl_parser("WSI_TOKEN_SKIPPING_SAW_CR '%c'\n", c);
|
||||
if (wsi->u.hdr.ues != URIES_IDLE)
|
||||
if (ah->ues != URIES_IDLE)
|
||||
goto forbid;
|
||||
if (c == '\x0a') {
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_NAME_PART;
|
||||
wsi->u.hdr.lextable_pos = 0;
|
||||
ah->parser_state = WSI_TOKEN_NAME_PART;
|
||||
ah->lextable_pos = 0;
|
||||
} else
|
||||
wsi->u.hdr.parser_state = WSI_TOKEN_SKIPPING;
|
||||
ah->parser_state = WSI_TOKEN_SKIPPING;
|
||||
break;
|
||||
/* we're done, ignore anything else */
|
||||
|
||||
|
@ -1132,7 +1135,7 @@ excessive:
|
|||
return 0;
|
||||
|
||||
set_parsing_complete:
|
||||
if (wsi->u.hdr.ues != URIES_IDLE)
|
||||
if (ah->ues != URIES_IDLE)
|
||||
goto forbid;
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_UPGRADE)) {
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_VERSION))
|
||||
|
@ -1141,7 +1144,7 @@ set_parsing_complete:
|
|||
|
||||
lwsl_parser("v%02d hdrs completed\n", wsi->ietf_spec_revision);
|
||||
}
|
||||
wsi->u.hdr.parser_state = WSI_PARSING_COMPLETE;
|
||||
ah->parser_state = WSI_PARSING_COMPLETE;
|
||||
wsi->hdr_parsing_completed = 1;
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -488,7 +488,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->u.http.ah->frag_index[WSI_TOKEN_HTTP_RANGE] = 0;
|
||||
wsi->ah->frag_index[WSI_TOKEN_HTTP_RANGE] = 0;
|
||||
|
||||
if (lws_hdr_total_length(wsi, WSI_TOKEN_HTTP_IF_NONE_MATCH)) {
|
||||
/*
|
||||
|
@ -1334,11 +1334,9 @@ lws_server_init_wsi_for_ws(struct lws *wsi)
|
|||
int
|
||||
lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
||||
{
|
||||
int protocol_len, n = 0, hit, non_space_char_found = 0, m;
|
||||
struct lws_context *context = lws_get_context(wsi);
|
||||
struct lws_context_per_thread *pt = &context->pt[(int)wsi->tsi];
|
||||
struct _lws_header_related hdr;
|
||||
struct allocated_headers *ah;
|
||||
int protocol_len, n = 0, hit, non_space_char_found = 0, m;
|
||||
unsigned char *obuf = *buf;
|
||||
char protocol_list[128];
|
||||
char protocol_name[64];
|
||||
|
@ -1350,7 +1348,7 @@ lws_handshake_server(struct lws *wsi, unsigned char **buf, size_t len)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
if (!wsi->u.hdr.ah) {
|
||||
if (!wsi->ah) {
|
||||
lwsl_err("%s: assert: NULL ah\n", __func__);
|
||||
assert(0);
|
||||
}
|
||||
|
@ -1401,7 +1399,7 @@ raw_transition:
|
|||
goto bail_nuke_ah;
|
||||
}
|
||||
|
||||
if (wsi->u.hdr.parser_state != WSI_PARSING_COMPLETE)
|
||||
if (wsi->ah->parser_state != WSI_PARSING_COMPLETE)
|
||||
continue;
|
||||
|
||||
lwsl_parser("%s: lws_parse sees parsing complete\n", __func__);
|
||||
|
@ -1511,16 +1509,13 @@ raw_transition:
|
|||
/* no upgrade ack... he remained as HTTP */
|
||||
|
||||
lwsl_info("No upgrade\n");
|
||||
ah = wsi->u.hdr.ah;
|
||||
|
||||
lws_union_transition(wsi, LWSCM_HTTP_SERVING_ACCEPTED);
|
||||
wsi->state = LWSS_HTTP;
|
||||
wsi->u.http.fop_fd = NULL;
|
||||
|
||||
/* expose it at the same offset as u.hdr */
|
||||
wsi->u.http.ah = ah;
|
||||
lwsl_debug("%s: wsi %p: ah %p\n", __func__, (void *)wsi,
|
||||
(void *)wsi->u.hdr.ah);
|
||||
(void *)wsi->ah);
|
||||
|
||||
n = lws_http_action(wsi);
|
||||
|
||||
|
@ -1546,13 +1541,8 @@ upgrade_h2c:
|
|||
|
||||
/* adopt the header info */
|
||||
|
||||
ah = wsi->u.hdr.ah;
|
||||
|
||||
lws_union_transition(wsi, LWSCM_HTTP2_SERVING);
|
||||
|
||||
/* http2 union member has http union struct at start */
|
||||
wsi->u.http.ah = ah;
|
||||
|
||||
if (!wsi->u.h2.h2n) {
|
||||
wsi->u.h2.h2n = lws_zalloc(sizeof(*wsi->u.h2.h2n),
|
||||
"h2n");
|
||||
|
@ -1712,10 +1702,9 @@ upgrade_ws:
|
|||
*/
|
||||
|
||||
lwsl_info("%s: %p: inheriting ws ah (rxpos:%d, rxlen:%d)\n",
|
||||
__func__, wsi, wsi->u.hdr.ah->rxpos,
|
||||
wsi->u.hdr.ah->rxlen);
|
||||
__func__, wsi, wsi->ah->rxpos,
|
||||
wsi->ah->rxlen);
|
||||
lws_pt_lock(pt);
|
||||
hdr = wsi->u.hdr;
|
||||
|
||||
lws_union_transition(wsi, LWSCM_WS_SERVING);
|
||||
/*
|
||||
|
@ -1726,12 +1715,8 @@ upgrade_ws:
|
|||
*
|
||||
* Because rxpos/rxlen shows something in the ah, we will get
|
||||
* service guaranteed next time around the event loop
|
||||
*
|
||||
* All union members begin with hdr, so we can use it even
|
||||
* though we transitioned to ws union mode (the ah detach
|
||||
* code uses it anyway).
|
||||
*/
|
||||
wsi->u.hdr = hdr;
|
||||
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
lws_server_init_wsi_for_ws(wsi);
|
||||
|
@ -1893,7 +1878,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->u.hdr.ah) {
|
||||
if (wsi->ah) {
|
||||
lwsl_debug("%s: wsi->more_rx_waiting=%d\n", __func__,
|
||||
wsi->more_rx_waiting);
|
||||
|
||||
|
@ -1930,7 +1915,7 @@ lws_http_transaction_completed(struct lws *wsi)
|
|||
}
|
||||
|
||||
/* If we're (re)starting on headers, need other implied init */
|
||||
wsi->u.hdr.ues = URIES_IDLE;
|
||||
wsi->ah->ues = URIES_IDLE;
|
||||
|
||||
lwsl_info("%s: %p: keep-alive await new transaction\n", __func__, wsi);
|
||||
|
||||
|
@ -2173,8 +2158,8 @@ 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->u.hdr.ah || !lws_header_table_attach(wsi, 0)) {
|
||||
ah = wsi->u.hdr.ah;
|
||||
if (wsi->ah || !lws_header_table_attach(wsi, 0)) {
|
||||
ah = wsi->ah;
|
||||
memcpy(ah->rx, readbuf, len);
|
||||
ah->rxpos = 0;
|
||||
ah->rxlen = (int16_t)len;
|
||||
|
@ -2204,13 +2189,13 @@ adopt_socket_readbuf(struct lws *wsi, const char *readbuf, size_t len)
|
|||
* later successful lws_header_table_attach() will apply the
|
||||
* below to the rx buffer (via lws_header_table_reset()).
|
||||
*/
|
||||
wsi->u.hdr.preamble_rx = lws_malloc(len, "preamble_rx");
|
||||
if (!wsi->u.hdr.preamble_rx) {
|
||||
wsi->preamble_rx = lws_malloc(len, "preamble_rx");
|
||||
if (!wsi->preamble_rx) {
|
||||
lwsl_err("OOM\n");
|
||||
goto bail;
|
||||
}
|
||||
memcpy(wsi->u.hdr.preamble_rx, readbuf, len);
|
||||
wsi->u.hdr.preamble_rx_len = (int)len;
|
||||
memcpy(wsi->preamble_rx, readbuf, len);
|
||||
wsi->preamble_rx_len = (int)len;
|
||||
|
||||
return wsi;
|
||||
|
||||
|
@ -2304,14 +2289,14 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
if (wsi->mode != LWSCM_RAW && (wsi->state == LWSS_HTTP ||
|
||||
wsi->state == LWSS_HTTP_ISSUING_FILE ||
|
||||
wsi->state == LWSS_HTTP_HEADERS)) {
|
||||
if (!wsi->u.hdr.ah) {
|
||||
if (!wsi->ah) {
|
||||
/* no autoservice beacuse we will do it next */
|
||||
if (lws_header_table_attach(wsi, 0)) {
|
||||
lwsl_info("wsi %p: ah get fail\n", wsi);
|
||||
goto try_pollout;
|
||||
}
|
||||
}
|
||||
ah = wsi->u.hdr.ah;
|
||||
ah = wsi->ah;
|
||||
|
||||
/* if nothing in ah rx buffer, get some fresh rx */
|
||||
if (ah->rxpos == ah->rxlen) {
|
||||
|
@ -2363,14 +2348,14 @@ lws_server_socket_service(struct lws_context *context, struct lws *wsi,
|
|||
if (n < 0) /* we closed wsi */
|
||||
return 1;
|
||||
|
||||
if (!wsi->u.hdr.ah)
|
||||
if (!wsi->ah)
|
||||
break;
|
||||
if ( wsi->u.hdr.ah->rxlen)
|
||||
wsi->u.hdr.ah->rxpos += n;
|
||||
if ( wsi->ah->rxlen)
|
||||
wsi->ah->rxpos += n;
|
||||
|
||||
lwsl_debug("%s: wsi %p: ah read rxpos %d, rxlen %d\n",
|
||||
__func__, wsi, wsi->u.hdr.ah->rxpos,
|
||||
wsi->u.hdr.ah->rxlen);
|
||||
__func__, wsi, wsi->ah->rxpos,
|
||||
wsi->ah->rxlen);
|
||||
|
||||
if (lws_header_table_is_in_detachable_state(wsi) &&
|
||||
(wsi->mode != LWSCM_HTTP_SERVING &&
|
||||
|
|
|
@ -601,7 +601,7 @@ lws_service_timeout_check(struct lws *wsi, unsigned int 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->u.hdr.ah,
|
||||
wsi->hdr_parsing_completed, wsi->ah,
|
||||
pt->ah_wait_list_length, n,
|
||||
(unsigned long long)sec,
|
||||
(unsigned long long)wsi->pending_timeout_limit);
|
||||
|
@ -1470,12 +1470,12 @@ read:
|
|||
/* all the union members start with hdr, so even in ws mode
|
||||
* we can deal with the ah via u.hdr
|
||||
*/
|
||||
if (wsi->u.hdr.ah) {
|
||||
if (wsi->ah) {
|
||||
lwsl_info("%s: %p: inherited ah rx\n", __func__, wsi);
|
||||
eff_buf.token_len = wsi->u.hdr.ah->rxlen -
|
||||
wsi->u.hdr.ah->rxpos;
|
||||
eff_buf.token = (char *)wsi->u.hdr.ah->rx +
|
||||
wsi->u.hdr.ah->rxpos;
|
||||
eff_buf.token_len = wsi->ah->rxlen -
|
||||
wsi->ah->rxpos;
|
||||
eff_buf.token = (char *)wsi->ah->rx +
|
||||
wsi->ah->rxpos;
|
||||
} else {
|
||||
if (wsi->mode != LWSCM_HTTP_CLIENT_ACCEPTED) {
|
||||
/*
|
||||
|
@ -1618,7 +1618,7 @@ drain:
|
|||
eff_buf.token_len = 0;
|
||||
} while (more);
|
||||
|
||||
if (wsi->u.hdr.ah) {
|
||||
if (wsi->ah) {
|
||||
lwsl_debug("%s: %p: detaching\n", __func__, wsi);
|
||||
lws_header_table_force_to_detachable_state(wsi);
|
||||
/* we can run the normal ah detach flow despite
|
||||
|
|
Loading…
Add table
Reference in a new issue