[PATCH] HTTP/2: signal 0-byte HPACK's dynamic table size

Maxim Dounin mdounin at mdounin.ru
Tue Sep 12 02:46:15 UTC 2017


Hello!

On Wed, Aug 30, 2017 at 02:55:34PM -0700, Piotr Sikora via nginx-devel wrote:

> # HG changeset patch
> # User Piotr Sikora <piotrsikora at google.com>
> # Date 1504129931 25200
> #      Wed Aug 30 14:52:11 2017 -0700
> # Node ID 7e1e91f9ca063563cb293136e7b1cede36e63dc6
> # Parent  c7d4017c8876af6d8570e400320537d7d39e9578
> HTTP/2: signal 0-byte HPACK's dynamic table size.
> 
> 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 at google.com>
> 
> diff -r c7d4017c8876 -r 7e1e91f9ca06 src/http/v2/ngx_http_v2.c
> --- a/src/http/v2/ngx_http_v2.c
> +++ b/src/http/v2/ngx_http_v2.c
> @@ -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);
> diff -r c7d4017c8876 -r 7e1e91f9ca06 src/http/v2/ngx_http_v2.h
> --- a/src/http/v2/ngx_http_v2.h
> +++ b/src/http/v2/ngx_http_v2.h
> @@ -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;
>  };
> diff -r c7d4017c8876 -r 7e1e91f9ca06 src/http/v2/ngx_http_v2_filter_module.c
> --- a/src/http/v2/ngx_http_v2_filter_module.c
> +++ b/src/http/v2/ngx_http_v2_filter_module.c
> @@ -141,6 +141,7 @@ ngx_http_v2_header_filter(ngx_http_reque
>      ngx_http_v2_out_frame_t   *frame;
>      ngx_http_core_loc_conf_t  *clcf;
>      ngx_http_core_srv_conf_t  *cscf;
> +    ngx_http_v2_connection_t  *h2c;
>      u_char                     addr[NGX_SOCKADDR_STRLEN];
>  
>      static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7";
> @@ -235,7 +236,11 @@ ngx_http_v2_header_filter(ngx_http_reque
>          }
>      }
>  
> -    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_reque
>  
>      start = pos;
>  
> +    if (h2c->table_update) {
> +        ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
> +                       "http2 sending dynamic table size update: 0");
> +        *pos++ = 32;
> +        h2c->table_update = 0;
> +    }
> +
>      ngx_log_debug1(NGX_LOG_DEBUG_HTTP, fc->log, 0,
>                     "http2 output header: \":status: %03ui\"",
>                     r->headers_out.status);

Thank you for the patch.  I've pushed a change which fixes tests 
with this patch (http://hg.nginx.org/nginx-tests/rev/24e175025ad8). 
Unless there are objections, I'll push this patch with the 
following mostly style changes:

--- a/src/http/v2/ngx_http_v2_filter_module.c
+++ b/src/http/v2/ngx_http_v2_filter_module.c
@@ -139,9 +139,9 @@ ngx_http_v2_header_filter(ngx_http_reque
     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;
-    ngx_http_v2_connection_t  *h2c;
     u_char                     addr[NGX_SOCKADDR_STRLEN];
 
     static const u_char nginx[5] = "\x84\xaa\x63\x55\xe7";
@@ -430,8 +430,8 @@ ngx_http_v2_header_filter(ngx_http_reque
 
     if (h2c->table_update) {
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, fc->log, 0,
-                       "http2 sending dynamic table size update: 0");
-        *pos++ = 32;
+                       "http2 table size update: 0");
+        *pos++ = (1 << 5) | 0;
         h2c->table_update = 0;
     }
 

-- 
Maxim Dounin
http://nginx.org/


More information about the nginx-devel mailing list