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 3749805864
commit 68d4325de0
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_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_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_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_ */ #endif /* _NGX_HTTP_V3_PARSE_H_INCLUDED_ */

View File

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

View File

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