HTTP/3: bulk parse functions.

Previously HTTP/3 streams were parsed by one character.  Now all parse functions
receive buffers.  This should optimize parsing time and CPU load.
This commit is contained in:
Roman Arutyunyan 2021-07-08 21:52:47 +03:00
parent d4fae36970
commit 7c9cdcd3f9
4 changed files with 1188 additions and 990 deletions

File diff suppressed because it is too large Load diff

View file

@ -136,11 +136,11 @@ typedef struct {
*/
ngx_int_t ngx_http_v3_parse_headers(ngx_connection_t *c,
ngx_http_v3_parse_headers_t *st, u_char ch);
ngx_http_v3_parse_headers_t *st, ngx_buf_t *b);
ngx_int_t ngx_http_v3_parse_data(ngx_connection_t *c,
ngx_http_v3_parse_data_t *st, u_char ch);
ngx_http_v3_parse_data_t *st, ngx_buf_t *b);
ngx_int_t ngx_http_v3_parse_uni(ngx_connection_t *c,
ngx_http_v3_parse_uni_t *st, u_char ch);
ngx_http_v3_parse_uni_t *st, ngx_buf_t *b);
#endif /* _NGX_HTTP_V3_PARSE_H_INCLUDED_ */

View file

@ -207,6 +207,7 @@ ngx_http_v3_cleanup_request(void *data)
static void
ngx_http_v3_process_request(ngx_event_t *rev)
{
u_char *p;
ssize_t n;
ngx_buf_t *b;
ngx_int_t rc;
@ -273,7 +274,9 @@ ngx_http_v3_process_request(ngx_event_t *rev)
b->last = b->start + n;
}
rc = ngx_http_v3_parse_headers(c, st, *b->pos);
p = b->pos;
rc = ngx_http_v3_parse_headers(c, st, b);
if (rc > 0) {
ngx_http_v3_finalize_connection(c, rc,
@ -302,8 +305,7 @@ ngx_http_v3_process_request(ngx_event_t *rev)
break;
}
b->pos++;
r->request_length++;
r->request_length += b->pos - p;
if (rc == NGX_AGAIN) {
continue;
@ -1024,6 +1026,7 @@ ngx_http_v3_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
{
off_t max;
size_t size;
u_char *p;
ngx_int_t rc;
ngx_buf_t *b;
ngx_uint_t last;
@ -1078,9 +1081,11 @@ ngx_http_v3_request_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
while (cl->buf->pos < cl->buf->last) {
if (st->length == 0) {
r->request_length++;
p = cl->buf->pos;
rc = ngx_http_v3_parse_data(r->connection, st, *cl->buf->pos++);
rc = ngx_http_v3_parse_data(r->connection, st, cl->buf);
r->request_length += cl->buf->pos - p;
if (rc == NGX_AGAIN) {
continue;

View file

@ -168,7 +168,8 @@ ngx_http_v3_uni_read_handler(ngx_event_t *rev)
{
u_char buf[128];
ssize_t n;
ngx_int_t rc, i;
ngx_buf_t b;
ngx_int_t rc;
ngx_connection_t *c;
ngx_http_v3_uni_stream_t *us;
@ -177,6 +178,8 @@ ngx_http_v3_uni_read_handler(ngx_event_t *rev)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 read handler");
ngx_memzero(&b, sizeof(ngx_buf_t));
while (rev->ready) {
n = c->recv(c, buf, sizeof(buf));
@ -201,25 +204,25 @@ ngx_http_v3_uni_read_handler(ngx_event_t *rev)
break;
}
for (i = 0; i < n; i++) {
b.pos = buf;
b.last = buf + n;
rc = ngx_http_v3_parse_uni(c, &us->parse, buf[i]);
rc = ngx_http_v3_parse_uni(c, &us->parse, &b);
if (rc == NGX_DONE) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http3 read done");
ngx_http_v3_close_uni_stream(c);
return;
}
if (rc == NGX_DONE) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http3 read done");
ngx_http_v3_close_uni_stream(c);
return;
}
if (rc > 0) {
goto failed;
}
if (rc > 0) {
goto failed;
}
if (rc != NGX_AGAIN) {
rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR;
goto failed;
}
if (rc != NGX_AGAIN) {
rc = NGX_HTTP_V3_ERR_GENERAL_PROTOCOL_ERROR;
goto failed;
}
}