]> git.kaiwu.me - nginx.git/commitdiff
HTTP/2: signal 0-byte HPACK's dynamic table size.
authorPiotr Sikora <piotrsikora@google.com>
Wed, 30 Aug 2017 21:52:11 +0000 (14:52 -0700)
committerPiotr Sikora <piotrsikora@google.com>
Wed, 30 Aug 2017 21:52:11 +0000 (14:52 -0700)
This change lets NGINX talk to clients with SETTINGS_HEADER_TABLE_SIZE
smaller than the default 4KB. Previously, NGINX would ACK the SETTINGS
frame with a small dynamic table size, but it would never send dynamic
table size update, leading to a connection-level COMPRESSION_ERROR.

Also, it allows clients to release 4KB of memory per connection, since
NGINX doesn't use HPACK's dynamic table when encoding headers, however
clients had to maintain it, since NGINX never signaled that it doesn't
use it.

Signed-off-by: Piotr Sikora <piotrsikora@google.com>
src/http/v2/ngx_http_v2.c
src/http/v2/ngx_http_v2.h
src/http/v2/ngx_http_v2_filter_module.c

index 772561640fb898918de145b3558eae5ba884c587..d99dd83421c7371fa0a383f35581ab6789988f0e 100644 (file)
@@ -245,6 +245,8 @@ ngx_http_v2_init(ngx_event_t *rev)
 
     h2c->frame_size = NGX_HTTP_V2_DEFAULT_FRAME_SIZE;
 
+    h2c->table_update = 1;
+
     h2scf = ngx_http_get_module_srv_conf(hc->conf_ctx, ngx_http_v2_module);
 
     h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
index 4804658eb41a25f219c4864b1a0616a4605d6ba9..42e0eb1325158fd01936d025b04c540c7756974b 100644 (file)
@@ -144,6 +144,7 @@ struct ngx_http_v2_connection_s {
 
     unsigned                         closed_nodes:8;
     unsigned                         settings_ack:1;
+    unsigned                         table_update:1;
     unsigned                         blocked:1;
     unsigned                         goaway:1;
 };
index 8621e7a4dae33b6609caf48570fbb56efeeda83f..74aac6ef0f4fb8c1f1069dc4b20de63759174437 100644 (file)
@@ -139,6 +139,7 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
     ngx_connection_t          *fc;
     ngx_http_cleanup_t        *cln;
     ngx_http_v2_out_frame_t   *frame;
+    ngx_http_v2_connection_t  *h2c;
     ngx_http_core_loc_conf_t  *clcf;
     ngx_http_core_srv_conf_t  *cscf;
     u_char                     addr[NGX_SOCKADDR_STRLEN];
@@ -235,7 +236,11 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
         }
     }
 
-    len = status ? 1 : 1 + ngx_http_v2_literal_size("418");
+    h2c = r->stream->connection;
+
+    len = h2c->table_update ? 1 : 0;
+
+    len += status ? 1 : 1 + ngx_http_v2_literal_size("418");
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
 
@@ -423,6 +428,13 @@ ngx_http_v2_header_filter(ngx_http_request_t *r)
 
     start = pos;
 
+    if (h2c->table_update) {
+        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
+                       "http2 table size update: 0");
+        *pos++ = (1 << 5) | 0;
+        h2c->table_update = 0;
+    }
+
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
                    "http2 output header: \":status: %03ui\"",
                    r->headers_out.status);