mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
h2: provide parser buffer at a time
This commit is contained in:
parent
2a30cd8ba7
commit
6c484b2b31
3 changed files with 52 additions and 26 deletions
|
@ -63,7 +63,7 @@ LWS_VISIBLE int
|
|||
lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
||||
{
|
||||
unsigned char *last_char, *oldbuf = buf;
|
||||
lws_filepos_t body_chunk_len;
|
||||
lws_filepos_t body_chunk_len, inlen = len;
|
||||
size_t n;
|
||||
|
||||
switch (wsi->state) {
|
||||
|
@ -71,7 +71,6 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
|||
case LWSS_HTTP2_AWAIT_CLIENT_PREFACE:
|
||||
case LWSS_HTTP2_ESTABLISHED_PRE_SETTINGS:
|
||||
case LWSS_HTTP2_ESTABLISHED:
|
||||
n = 0;
|
||||
/*
|
||||
* wsi here is always the network connection wsi, not a stream
|
||||
* wsi. Once we unpicked the framing we will find the right
|
||||
|
@ -82,28 +81,31 @@ lws_read(struct lws *wsi, unsigned char *buf, lws_filepos_t len)
|
|||
* ESTABLISHED state for the inner payload, handled in a later
|
||||
* case.
|
||||
*/
|
||||
while (n < len) {
|
||||
while (len) {
|
||||
/*
|
||||
* we were accepting input but now we stopped doing so
|
||||
*/
|
||||
if (lws_is_flowcontrolled(wsi)) {
|
||||
lws_rxflow_cache(wsi, buf, (int)n, (int)len);
|
||||
lws_rxflow_cache(wsi, buf, 0, (int)len);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* account for what we're using in rxflow buffer */
|
||||
if (wsi->rxflow_buffer) {
|
||||
wsi->rxflow_pos++;
|
||||
assert(wsi->rxflow_pos <= wsi->rxflow_len);
|
||||
}
|
||||
|
||||
if (lws_h2_parser(wsi, buf[n++])) {
|
||||
if (lws_h2_parser(wsi, buf, len, &body_chunk_len)) {
|
||||
lwsl_debug("%s: http2_parser bailed\n", __func__);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
/* account for what we're using in rxflow buffer */
|
||||
if (wsi->rxflow_buffer) {
|
||||
wsi->rxflow_pos += (int)body_chunk_len;
|
||||
assert(wsi->rxflow_pos <= wsi->rxflow_len);
|
||||
}
|
||||
|
||||
buf += body_chunk_len;
|
||||
len -= body_chunk_len;
|
||||
}
|
||||
lwsl_debug("%s: used up block of %d\n", __func__, (int)len);
|
||||
lwsl_debug("%s: used up block of %d\n", __func__, (int)inlen);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
@ -274,7 +276,7 @@ postbody_completion:
|
|||
|
||||
read_ok:
|
||||
/* Nothing more to do for now */
|
||||
lwsl_info("%s: read_ok, used %ld\n", __func__, (long)(buf - oldbuf));
|
||||
lwsl_info("%s: %p: read_ok, used %ld (len %d, state %d)\n", __func__, wsi, (long)(buf - oldbuf), (int)len, wsi->state);
|
||||
|
||||
return lws_ptr_diff(buf, oldbuf);
|
||||
|
||||
|
|
|
@ -1319,19 +1319,25 @@ lws_h2_parse_end_of_frame(struct lws *wsi)
|
|||
}
|
||||
|
||||
int
|
||||
lws_h2_parser(struct lws *wsi, unsigned char c)
|
||||
lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen,
|
||||
lws_filepos_t *inused)
|
||||
{
|
||||
struct lws_h2_netconn *h2n = wsi->h2.h2n;
|
||||
struct lws_h2_protocol_send *pps;
|
||||
unsigned char c, *oldin = in;
|
||||
int n;
|
||||
|
||||
if (!h2n)
|
||||
return 1;
|
||||
goto fail;
|
||||
|
||||
while (inlen--) {
|
||||
|
||||
c = *in++;
|
||||
|
||||
switch (wsi->state) {
|
||||
case LWSS_HTTP2_AWAIT_CLIENT_PREFACE:
|
||||
if (preface[h2n->count++] != c)
|
||||
return 1;
|
||||
goto fail;
|
||||
|
||||
if (preface[h2n->count])
|
||||
break;
|
||||
|
@ -1348,7 +1354,7 @@ lws_h2_parser(struct lws *wsi, unsigned char c)
|
|||
*/
|
||||
pps = lws_h2_new_pps(LWS_H2_PPS_MY_SETTINGS);
|
||||
if (!pps)
|
||||
return 1;
|
||||
goto fail;
|
||||
lws_pps_schedule(wsi, pps);
|
||||
break;
|
||||
|
||||
|
@ -1421,7 +1427,7 @@ lws_h2_parser(struct lws *wsi, unsigned char c)
|
|||
break;
|
||||
if (lws_hpack_interpret(h2n->swsi, c)) {
|
||||
lwsl_info("%s: hpack failed\n", __func__);
|
||||
return 1;
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1458,8 +1464,11 @@ lws_h2_parser(struct lws *wsi, unsigned char c)
|
|||
if (!h2n->swsi)
|
||||
break;
|
||||
|
||||
h2n->swsi->state = LWSS_HTTP_BODY;
|
||||
h2n->inside++;
|
||||
if (h2n->swsi->state == LWSS_HTTP2_ESTABLISHED) {
|
||||
h2n->swsi->state = LWSS_HTTP_BODY;
|
||||
lwsl_notice("%s: setting swsi %p to LWSS_HTTP_BODY\n", __func__, h2n->swsi);
|
||||
}
|
||||
|
||||
if (lws_hdr_total_length(h2n->swsi,
|
||||
WSI_TOKEN_HTTP_CONTENT_LENGTH) &&
|
||||
h2n->swsi->http.rx_content_length &&
|
||||
|
@ -1470,10 +1479,15 @@ lws_h2_parser(struct lws *wsi, unsigned char c)
|
|||
break;
|
||||
}
|
||||
|
||||
n = lws_read(h2n->swsi, &c, 1);
|
||||
n = lws_read(h2n->swsi, in - 1, inlen + 1);
|
||||
if (n < 0)
|
||||
break;
|
||||
|
||||
inlen -= n - 1;
|
||||
in += n - 1;
|
||||
h2n->inside += n;
|
||||
h2n->count += n - 1;
|
||||
|
||||
break;
|
||||
|
||||
case LWS_H2_FRAME_TYPE_PRIORITY:
|
||||
|
@ -1520,7 +1534,7 @@ lws_h2_parser(struct lws *wsi, unsigned char c)
|
|||
lwsl_notice("%s: unhandled frame type %d\n",
|
||||
__func__, h2n->type);
|
||||
|
||||
return 1;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
frame_end:
|
||||
|
@ -1531,7 +1545,7 @@ frame_end:
|
|||
* end of frame just happened
|
||||
*/
|
||||
if (lws_h2_parse_end_of_frame(wsi))
|
||||
return 1;
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
try_frame_start:
|
||||
|
@ -1569,11 +1583,20 @@ try_frame_start:
|
|||
}
|
||||
if (h2n->frame_state == LWS_H2_FRAME_HEADER_LENGTH)
|
||||
if (lws_h2_parse_frame_header(wsi))
|
||||
return 1;
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
*inused = in - oldin;
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
*inused = in - oldin;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -1597,7 +1620,7 @@ lws_h2_ws_handshake(struct lws *wsi)
|
|||
wsi->protocol->name && wsi->protocol->name[0]) {
|
||||
if (lws_add_http_header_by_token(wsi, WSI_TOKEN_PROTOCOL,
|
||||
(unsigned char *)wsi->protocol->name,
|
||||
strlen(wsi->protocol->name), &p, end))
|
||||
(int)strlen(wsi->protocol->name), &p, end))
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -2246,7 +2246,8 @@ LWS_EXTERN int
|
|||
lws_h2_settings(struct lws *nwsi, struct http2_settings *settings,
|
||||
unsigned char *buf, int len);
|
||||
LWS_EXTERN int
|
||||
lws_h2_parser(struct lws *wsi, unsigned char c);
|
||||
lws_h2_parser(struct lws *wsi, unsigned char *in, lws_filepos_t inlen,
|
||||
lws_filepos_t *inused);
|
||||
LWS_EXTERN int lws_h2_do_pps_send(struct lws *wsi);
|
||||
LWS_EXTERN int lws_h2_frame_write(struct lws *wsi, int type, int flags,
|
||||
unsigned int sid, unsigned int len,
|
||||
|
|
Loading…
Add table
Reference in a new issue