aboutsummaryrefslogtreecommitdiff
path: root/src/http/v3/ngx_http_v3_parse.c
diff options
context:
space:
mode:
authorRoman Arutyunyan <arut@nginx.com>2020-07-02 15:34:05 +0300
committerRoman Arutyunyan <arut@nginx.com>2020-07-02 15:34:05 +0300
commita687d08062d8cb029ab82249aa55833cf44be3ce (patch)
tree57ab07f1a9e3471ba1b43e6635bcde4094277bc7 /src/http/v3/ngx_http_v3_parse.c
parenta7ef0da3c8b64f2b5f4d8a7e73e724a74611284c (diff)
downloadnginx-a687d08062d8cb029ab82249aa55833cf44be3ce.tar.gz
nginx-a687d08062d8cb029ab82249aa55833cf44be3ce.zip
HTTP/3: refactored dynamic table implementation.
Previously dynamic table was not functional because of zero limit on its size set by default. Now the following changes enable it: - new directives to set SETTINGS_QPACK_MAX_TABLE_CAPACITY and SETTINGS_QPACK_BLOCKED_STREAMS - send settings with SETTINGS_QPACK_MAX_TABLE_CAPACITY and SETTINGS_QPACK_BLOCKED_STREAMS to the client - send Insert Count Increment to the client - send Header Acknowledgement to the client - evict old dynamic table entries on overflow - decode Required Insert Count from client - block stream if Required Insert Count is not reached
Diffstat (limited to 'src/http/v3/ngx_http_v3_parse.c')
-rw-r--r--src/http/v3/ngx_http_v3_parse.c111
1 files changed, 86 insertions, 25 deletions
diff --git a/src/http/v3/ngx_http_v3_parse.c b/src/http/v3/ngx_http_v3_parse.c
index 85491082e..bd91c5b02 100644
--- a/src/http/v3/ngx_http_v3_parse.c
+++ b/src/http/v3/ngx_http_v3_parse.c
@@ -10,6 +10,10 @@
#include <ngx_http.h>
+static ngx_int_t ngx_http_v3_parse_lookup(ngx_connection_t *c,
+ ngx_uint_t dynamic, ngx_uint_t index, ngx_str_t *name, ngx_str_t *value);
+
+
ngx_int_t
ngx_http_v3_parse_varlen_int(ngx_connection_t *c,
ngx_http_v3_parse_varlen_int_t *st, u_char ch)
@@ -144,6 +148,7 @@ ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st,
sw_start = 0,
sw_length,
sw_prefix,
+ sw_verify,
sw_header_rep,
sw_done
};
@@ -195,9 +200,20 @@ ngx_http_v3_parse_headers(ngx_connection_t *c, ngx_http_v3_parse_headers_t *st,
return NGX_ERROR;
}
- st->state = sw_header_rep;
+ st->state = sw_verify;
break;
+ case sw_verify:
+
+ rc = ngx_http_v3_check_insert_count(c, st->prefix.insert_count);
+ if (rc != NGX_OK) {
+ return rc;
+ }
+
+ st->state = sw_header_rep;
+
+ /* fall through */
+
case sw_header_rep:
rc = ngx_http_v3_parse_header_rep(c, &st->header_rep, st->prefix.base,
@@ -228,6 +244,12 @@ done:
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http3 parse headers done");
+ if (st->prefix.insert_count > 0) {
+ if (ngx_http_v3_client_ack_header(c, c->qs->id) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
st->state = sw_start;
return NGX_DONE;
}
@@ -286,6 +308,10 @@ ngx_http_v3_parse_header_block_prefix(ngx_connection_t *c,
done:
+ if (ngx_http_v3_decode_insert_count(c, &st->insert_count) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
if (st->sign) {
st->base = st->insert_count - st->delta_base - 1;
} else {
@@ -294,7 +320,7 @@ done:
ngx_log_debug4(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http3 parse header block prefix done "
- "i:%ui, s:%ui, d:%ui, base:%uL",
+ "insert_count:%ui, sign:%ui, delta_base:%ui, base:%uL",
st->insert_count, st->sign, st->delta_base, st->base);
st->state = sw_start;
@@ -479,7 +505,6 @@ ngx_int_t
ngx_http_v3_parse_header_ri(ngx_connection_t *c, ngx_http_v3_parse_header_t *st,
u_char ch)
{
- ngx_http_v3_header_t *h;
enum {
sw_start = 0,
sw_index
@@ -518,15 +543,14 @@ done:
st->index = st->base - st->index - 1;
}
- h = ngx_http_v3_lookup_table(c, st->dynamic, st->index);
- if (h == NULL) {
+ if (ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name,
+ &st->value)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
- st->name = h->name;
- st->value = h->value;
st->state = sw_start;
-
return NGX_DONE;
}
@@ -535,8 +559,7 @@ ngx_int_t
ngx_http_v3_parse_header_lri(ngx_connection_t *c,
ngx_http_v3_parse_header_t *st, u_char ch)
{
- ngx_int_t rc;
- ngx_http_v3_header_t *h;
+ ngx_int_t rc;
enum {
sw_start = 0,
sw_index,
@@ -616,12 +639,12 @@ done:
st->index = st->base - st->index - 1;
}
- h = ngx_http_v3_lookup_table(c, st->dynamic, st->index);
- if (h == NULL) {
+ if (ngx_http_v3_parse_lookup(c, st->dynamic, st->index, &st->name, NULL)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
- st->name = h->name;
st->state = sw_start;
return NGX_DONE;
}
@@ -735,7 +758,6 @@ ngx_int_t
ngx_http_v3_parse_header_pbi(ngx_connection_t *c,
ngx_http_v3_parse_header_t *st, u_char ch)
{
- ngx_http_v3_header_t *h;
enum {
sw_start = 0,
sw_index
@@ -768,13 +790,13 @@ done:
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http3 parse header pbi done dynamic[+%ui]", st->index);
- h = ngx_http_v3_lookup_table(c, 1, st->base + st->index);
- if (h == NULL) {
+ if (ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name,
+ &st->value)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
- st->name = h->name;
- st->value = h->value;
st->state = sw_start;
return NGX_DONE;
}
@@ -784,8 +806,7 @@ ngx_int_t
ngx_http_v3_parse_header_lpbi(ngx_connection_t *c,
ngx_http_v3_parse_header_t *st, u_char ch)
{
- ngx_int_t rc;
- ngx_http_v3_header_t *h;
+ ngx_int_t rc;
enum {
sw_start = 0,
sw_index,
@@ -860,17 +881,57 @@ done:
"http3 parse header lpbi done dynamic[+%ui] \"%V\"",
st->index, &st->value);
- h = ngx_http_v3_lookup_table(c, 1, st->base + st->index);
- if (h == NULL) {
+ if (ngx_http_v3_parse_lookup(c, 1, st->base + st->index, &st->name, NULL)
+ != NGX_OK)
+ {
return NGX_ERROR;
}
- st->name = h->name;
st->state = sw_start;
return NGX_DONE;
}
+static ngx_int_t
+ngx_http_v3_parse_lookup(ngx_connection_t *c, ngx_uint_t dynamic,
+ ngx_uint_t index, ngx_str_t *name, ngx_str_t *value)
+{
+ u_char *p;
+
+ if (!dynamic) {
+ return ngx_http_v3_lookup_static(c, index, name, value);
+ }
+
+ if (ngx_http_v3_lookup(c, index, name, value) != NGX_OK) {
+ return NGX_ERROR;
+ }
+
+ if (name) {
+ p = ngx_pnalloc(c->pool, name->len + 1);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, name->data, name->len);
+ p[name->len] = '\0';
+ name->data = p;
+ }
+
+ if (value) {
+ p = ngx_pnalloc(c->pool, value->len + 1);
+ if (p == NULL) {
+ return NGX_ERROR;
+ }
+
+ ngx_memcpy(p, value->data, value->len);
+ p[value->len] = '\0';
+ value->data = p;
+ }
+
+ return NGX_OK;
+}
+
+
ngx_int_t
ngx_http_v3_parse_control(ngx_connection_t *c, void *data, u_char ch)
{
@@ -1145,7 +1206,7 @@ done:
"http3 parse encoder instruction done");
st->state = sw_start;
- return NGX_DONE;
+ return NGX_AGAIN;
}
@@ -1429,7 +1490,7 @@ done:
"http3 parse decoder instruction done");
st->state = sw_start;
- return NGX_DONE;
+ return NGX_AGAIN;
}