1
0
Fork 0
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:
Andy Green 2017-11-25 10:10:33 +08:00
parent 2a30cd8ba7
commit 6c484b2b31
3 changed files with 52 additions and 26 deletions

View file

@ -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);

View file

@ -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;
}

View file

@ -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,