Re: [PATCH] HTTP/2: added support for setting custom push request headers

2018-02-14 Thread Ruslan Ermilov
On Tue, Feb 13, 2018 at 11:58:40AM +, Alessandro Ghedini wrote:
> If it's of any help, I merged your patch and mine into one, which copies the
> headers (excluding Accept) into PUSH_PROMISE and r->headers_in like my 
> original
> patch did, as well as HPACK encode them into PUSH_PROMISE instead of writing
> them as literal strings, as your patch did. This fixes the problems I 
> mentioned
> in my previous email.

To keep you updated, we're cultivating these patches:

# HG changeset patch
# User Ruslan Ermilov 
# Date 1518609549 -10800
#  Wed Feb 14 14:59:09 2018 +0300
# Node ID 9cd08f096c366771ffbebd2872883be04903d425
# Parent  8b0553239592f5d0fd419e5116b9d343838685cf
Expose more headers with NGX_HTTP_HEADERS.

diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -140,7 +140,7 @@ ngx_http_header_t  ngx_http_headers_in[]
  offsetof(ngx_http_headers_in_t, upgrade),
  ngx_http_process_header_line },
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_HTTP_HEADERS)
 { ngx_string("Accept-Encoding"),
  offsetof(ngx_http_headers_in_t, accept_encoding),
  ngx_http_process_header_line },
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -200,7 +200,7 @@ typedef struct {
 ngx_table_elt_t  *expect;
 ngx_table_elt_t  *upgrade;
 
-#if (NGX_HTTP_GZIP)
+#if (NGX_HTTP_GZIP || NGX_HTTP_HEADERS)
 ngx_table_elt_t  *accept_encoding;
 ngx_table_elt_t  *via;
 #endif
# HG changeset patch
# User Ruslan Ermilov 
# Date 1518634812 -10800
#  Wed Feb 14 22:00:12 2018 +0300
# Node ID cd54884b375b70ecd358358e5e78f43e70b6163a
# Parent  9cd08f096c366771ffbebd2872883be04903d425
HTTP/2: push additional request headers (closes #1478).

The Accept-Encoding, Accept-Language, and User-Agent header fields
are now copied from the original request to pushed requests.

diff --git a/auto/modules b/auto/modules
--- a/auto/modules
+++ b/auto/modules
@@ -420,6 +420,7 @@ if [ $HTTP = YES ]; then
 
 if [ $HTTP_V2 = YES ]; then
 have=NGX_HTTP_V2 . auto/have
+have=NGX_HTTP_HEADERS . auto/have
 
 ngx_module_name=ngx_http_v2_module
 ngx_module_incs=src/http/v2
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -11,6 +11,14 @@
 #include 
 
 
+typedef struct {
+ngx_str_t   name;
+ngx_uint_t  offset;
+ngx_uint_t  hash;
+ngx_http_header_t  *hh;
+} ngx_http_v2_parse_header_t;
+
+
 /* errors */
 #define NGX_HTTP_V2_NO_ERROR 0x0
 #define NGX_HTTP_V2_PROTOCOL_ERROR   0x1
@@ -156,6 +164,8 @@ static ngx_int_t ngx_http_v2_parse_schem
 ngx_str_t *value);
 static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r,
 ngx_str_t *value);
+static ngx_int_t ngx_http_v2_parse_header(ngx_http_request_t *r,
+ngx_http_v2_parse_header_t *header, ngx_str_t *value);
 static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r);
 static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
 ngx_http_v2_header_t *header);
@@ -201,6 +211,23 @@ static ngx_http_v2_handler_pt ngx_http_v
 (sizeof(ngx_http_v2_frame_states) / sizeof(ngx_http_v2_handler_pt))
 
 
+static ngx_http_v2_parse_header_t  ngx_http_v2_parse_headers[] = {
+{ ngx_string("host"),
+  offsetof(ngx_http_headers_in_t, host), 0, NULL },
+
+{ ngx_string("accept-encoding"),
+  offsetof(ngx_http_headers_in_t, accept_encoding), 0, NULL },
+
+{ ngx_string("accept-language"),
+  offsetof(ngx_http_headers_in_t, accept_language), 0, NULL },
+
+{ ngx_string("user-agent"),
+  offsetof(ngx_http_headers_in_t, user_agent), 0, NULL },
+
+{ ngx_null_string, 0, 0, NULL }
+};
+
+
 void
 ngx_http_v2_init(ngx_event_t *rev)
 {
@@ -2514,21 +2541,25 @@ ngx_http_v2_parse_int(ngx_http_v2_connec
 }
 
 
-ngx_int_t
-ngx_http_v2_push_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t depend,
-size_t request_length, ngx_str_t *path, ngx_str_t *authority)
+ngx_http_v2_stream_t *
+ngx_http_v2_push_stream(ngx_http_v2_stream_t *parent, ngx_str_t *path)
 {
-ngx_int_t  rc;
-ngx_str_t  value;
-ngx_connection_t  *fc;
-ngx_http_request_t*r;
-ngx_http_v2_node_t*node;
-ngx_http_v2_stream_t  *stream;
+ngx_int_t rc;
+ngx_str_t value;
+ngx_table_elt_t **h;
+ngx_connection_t *fc;
+ngx_http_request_t   *r;
+ngx_http_v2_node_t   *node;
+ngx_http_v2_stream_t *stream;
+ngx_http_v2_connection_t *h2c;
+ngx_http_v2_parse_header_t   *header;
+
+h2c = parent->connection;
 
 node = ngx_htt

Re: [PATCH] HTTP/2: added support for setting custom push request headers

2018-02-13 Thread Alessandro Ghedini
On Mon, Feb 12, 2018 at 03:30:21PM +, Alessandro Ghedini wrote:
> On Mon, Feb 12, 2018 at 05:11:55PM +0300, Ruslan Ermilov wrote:
> > On Mon, Feb 12, 2018 at 12:35:13PM +, Alessandro Ghedini wrote:
> > > # HG changeset patch
> > > # User Alessandro Ghedini 
> > > # Date 1518438578 0
> > > #  Mon Feb 12 12:29:38 2018 +
> > > # Branch http2-push-header
> > > # Node ID 4eb0c9e8da0bc52065578e4ee78df1833617ac35
> > > # Parent  a49af443656f2b65ca5de9d8cad5594f44e18ff7
> > > HTTP/2: added support for setting custom push request headers.
> > > 
> > > This implementa the http2_push_header configuration directive that makes
> > > it possible to set custom request headers for pushed requests.
> > > 
> > > Complex values are evaluated in the context of the original request,
> > > so it's possible to copy its headers into pushed requests.
> > > 
> > > Example usage:
> > > 
> > > http2_push_header User-Agent $http_user_agent;
> > 
> > If I'm not mistaken, both the original patch and this one
> > do not send the copied headers in the PUSH_PROMISE frame.
> > 
> > Given the https://trac.nginx.org/nginx/ticket/1478, and some
> > research of how different implementations behave, I prepared
> > the following patch:
> 
> Also, your patch doesn't seem to work completely. You don't to copy the 
> request
> headers in the request's headers_in, which means they don't get processed by
> NGINX, if the pushed resource is handled by NGINX itself.

If it's of any help, I merged your patch and mine into one, which copies the
headers (excluding Accept) into PUSH_PROMISE and r->headers_in like my original
patch did, as well as HPACK encode them into PUSH_PROMISE instead of writing
them as literal strings, as your patch did. This fixes the problems I mentioned
in my previous email.

# HG changeset patch
# User Alessandro Ghedini 
# Date 1518522249 0
#  Tue Feb 13 11:44:09 2018 +
# Branch push-headers
# Node ID bfd3019a0f63cf00364d44bab74b7864808abbd7
# Parent  8b0553239592f5d0fd419e5116b9d343838685cf
HTTP/2: push additional headers (ticket #1478).

When pushing requests, copy and push Accept-Encoding, Accept-Language,
and User-Agent header fields from the original request.

Includes changes made by Ruslan Ermilov.

diff -r 8b0553239592 -r bfd3019a0f63 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c Fri Feb 09 23:20:08 2018 +0300
+++ b/src/http/v2/ngx_http_v2.c Tue Feb 13 11:44:09 2018 +
@@ -156,6 +156,8 @@
 ngx_str_t *value);
 static ngx_int_t ngx_http_v2_parse_authority(ngx_http_request_t *r,
 ngx_str_t *value);
+static ngx_int_t ngx_http_v2_copy_header(ngx_http_request_t *r,
+ngx_table_elt_t *hdr);
 static ngx_int_t ngx_http_v2_construct_request_line(ngx_http_request_t *r);
 static ngx_int_t ngx_http_v2_cookie(ngx_http_request_t *r,
 ngx_http_v2_header_t *header);
@@ -2516,7 +2518,8 @@
 
 ngx_int_t
 ngx_http_v2_push_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t depend,
-size_t request_length, ngx_str_t *path, ngx_str_t *authority)
+size_t request_length, ngx_str_t *path, ngx_str_t *authority,
+ngx_http_headers_in_t *headers_in)
 {
 ngx_int_t  rc;
 ngx_str_t  value;
@@ -2605,6 +2608,28 @@
 goto error;
 }
 
+rc = ngx_http_v2_copy_header(r, headers_in->user_agent);
+
+if (rc != NGX_OK) {
+goto error;
+}
+
+#if (NGX_HTTP_GZIP)
+rc = ngx_http_v2_copy_header(r, headers_in->accept_encoding);
+
+if (rc != NGX_OK) {
+goto error;
+}
+#endif
+
+#if (NGX_HTTP_HEADERS)
+rc = ngx_http_v2_copy_header(r, headers_in->accept_language);
+
+if (rc != NGX_OK) {
+goto error;
+}
+#endif
+
 fc->write->handler = ngx_http_v2_run_request_handler;
 ngx_post_event(fc->write, &ngx_posted_events);
 
@@ -3479,6 +3504,63 @@
 
 
 static ngx_int_t
+ngx_http_v2_copy_header(ngx_http_request_t *r, ngx_table_elt_t *hdr)
+{
+ngx_table_elt_t*h;
+ngx_http_header_t  *hh;
+ngx_http_core_main_conf_t  *cmcf;
+
+if (hdr == NULL) {
+return NGX_OK;
+}
+
+h = ngx_list_push(&r->headers_in.headers);
+if (h == NULL) {
+return NGX_ERROR;
+}
+
+h->hash = hdr->hash;
+
+h->key.len = hdr->key.len;
+
+h->key.data = ngx_pnalloc(r->stream->pool, h->key.len + 1);
+if (h->key.data == NULL) {
+h->hash = 0;
+return NGX_ERROR;
+}
+
+(void) ngx_cpystrn(h->key.data, hdr->key.data, h->key.len + 1);
+
+h->value.len = hdr->value.len;
+
+h->value.data = ngx_pnalloc(r->stream->pool, h->value.len + 1);
+if (h->key.data == NULL) {
+h->hash = 0;
+return NGX_ERROR;
+}
+
+(void) ngx_cpystrn(h->value.data, hdr->value.data, h->value.len + 1);
+
+h->lowcase_key = h->key.data;
+
+cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
+
+hh = ngx_hash_find(&cmcf->headers_in_hash, h->hash,
+   h->lowcase_key, h->key.len);
+
+if (hh == NULL) {
+re

Re: [PATCH] HTTP/2: added support for setting custom push request headers

2018-02-12 Thread Alessandro Ghedini
On Mon, Feb 12, 2018 at 05:11:55PM +0300, Ruslan Ermilov wrote:
> On Mon, Feb 12, 2018 at 12:35:13PM +, Alessandro Ghedini wrote:
> > # HG changeset patch
> > # User Alessandro Ghedini 
> > # Date 1518438578 0
> > #  Mon Feb 12 12:29:38 2018 +
> > # Branch http2-push-header
> > # Node ID 4eb0c9e8da0bc52065578e4ee78df1833617ac35
> > # Parent  a49af443656f2b65ca5de9d8cad5594f44e18ff7
> > HTTP/2: added support for setting custom push request headers.
> > 
> > This implementa the http2_push_header configuration directive that makes
> > it possible to set custom request headers for pushed requests.
> > 
> > Complex values are evaluated in the context of the original request,
> > so it's possible to copy its headers into pushed requests.
> > 
> > Example usage:
> > 
> > http2_push_header User-Agent $http_user_agent;
> 
> If I'm not mistaken, both the original patch and this one
> do not send the copied headers in the PUSH_PROMISE frame.
> 
> Given the https://trac.nginx.org/nginx/ticket/1478, and some
> research of how different implementations behave, I prepared
> the following patch:

Also, your patch doesn't seem to work completely. You don't to copy the request
headers in the request's headers_in, which means they don't get processed by
NGINX, if the pushed resource is handled by NGINX itself.

E.g.

  daemon off;
  worker_processes  1;
  master_process off;

  events {
worker_connections  1024;
  }

  http {
access_log /dev/stdout;
error_log  logs/error.log debug;

server {
listen   4433 ssl http2;

server_name  localhost;

ssl_certificate  cert.crt;
ssl_certificate_key  cert.key;

http2_max_concurrent_pushes   200;
http2_push_preloadon;


gzip on;
gzip_types text/plain;
gzip_min_length 1;

location /hello {
http2_push /a;

root   html;
}

location /a {
return 200 "a";
}
}
  }

 % nghttp https://127.0.0.1:4433/hello -vn  
[  0.001] Connected
[WARNING] Certificate verification failed: Hostname mismatch
The negotiated protocol: h2
[  0.003] send SETTINGS frame 
  (niv=2)
  [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
  [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[  0.003] send PRIORITY frame 
  (dep_stream_id=0, weight=201, exclusive=0)
[  0.003] send PRIORITY frame 
  (dep_stream_id=0, weight=101, exclusive=0)
[  0.003] send PRIORITY frame 
  (dep_stream_id=0, weight=1, exclusive=0)
[  0.003] send PRIORITY frame 
  (dep_stream_id=7, weight=1, exclusive=0)
[  0.003] send PRIORITY frame 
  (dep_stream_id=3, weight=1, exclusive=0)
[  0.003] send HEADERS frame 
  ; END_STREAM | END_HEADERS | PRIORITY
  (padlen=0, dep_stream_id=11, weight=16, exclusive=0)
  ; Open new stream
  :method: GET
  :path: /hello
  :scheme: https
  :authority: 127.0.0.1:4433
  accept: */*
  accept-encoding: gzip, deflate
  user-agent: nghttp2/1.29.0
[  0.004] recv SETTINGS frame 
  (niv=3)
  [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
  [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
  [SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
[  0.004] recv WINDOW_UPDATE frame 
  (window_size_increment=2147418112)
[  0.004] send SETTINGS frame 
  ; ACK
  (niv=0)
[  0.004] recv SETTINGS frame 
  ; ACK
  (niv=0)
[  0.004] recv (stream_id=13) :method: GET
[  0.004] recv (stream_id=13) :path: /a
[  0.004] recv (stream_id=13) :authority: 127.0.0.1:4433
[  0.004] recv (stream_id=13) :scheme: https
[  0.004] recv (stream_id=13) accept-encoding: gzip, deflate
[  0.004] recv (stream_id=13) user-agent: nghttp2/1.29.0
[  0.004] recv PUSH_PROMISE frame 
  ; END_HEADERS
  (padlen=0, promised_stream_id=2)
[  0.004] recv (stream_id=13) :status: 200
[  0.004] recv (stream_id=13) server: nginx/1.13.9
[  0.004] recv (stream_id=13) date: Mon, 12 Feb 2018 15:18:39 GMT
[  0.004] recv (stream_id=13) content-type: text/plain
[  0.004] recv (stream_id=13) last-modified: Thu, 08 Feb 2018 15:43:05 GMT
[  0.004] recv (stream_id=13) etag: W/"5a7c7009-1f5"
[  0.004] recv (stream_id=13) content-encoding: gzip
[  0.004] recv HEADERS frame 
  ; END_HEADERS
  (padlen=0)
  ; First response header
[  0.004] recv DATA frame 
  ; END_STREAM
[  0.004] recv (stream_id=2) :status: 200
[  0.004] recv (stream_id=2) server: nginx/1.13.9
[  0.004] recv (stream_id=2) date: Mon, 12 Feb 2018 15:18:39 GMT
[  0.004] recv (stream_id=2) content-type: text/plain
[  0.004] recv (stream_id=2) content-length: 1
[  0.004] recv HEADERS frame 
  ; END_HEADERS
  (padlen=0)
  ; First push response header
[  0.004] recv DATA frame 
  ; END_STREAM
[  0.004] send GOAWAY frame 
  (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_d

Re: [PATCH] HTTP/2: added support for setting custom push request headers

2018-02-12 Thread Alessandro Ghedini
On Mon, Feb 12, 2018 at 05:11:55PM +0300, Ruslan Ermilov wrote:
> On Mon, Feb 12, 2018 at 12:35:13PM +, Alessandro Ghedini wrote:
> > # HG changeset patch
> > # User Alessandro Ghedini 
> > # Date 1518438578 0
> > #  Mon Feb 12 12:29:38 2018 +
> > # Branch http2-push-header
> > # Node ID 4eb0c9e8da0bc52065578e4ee78df1833617ac35
> > # Parent  a49af443656f2b65ca5de9d8cad5594f44e18ff7
> > HTTP/2: added support for setting custom push request headers.
> > 
> > This implementa the http2_push_header configuration directive that makes
> > it possible to set custom request headers for pushed requests.
> > 
> > Complex values are evaluated in the context of the original request,
> > so it's possible to copy its headers into pushed requests.
> > 
> > Example usage:
> > 
> > http2_push_header User-Agent $http_user_agent;
> 
> If I'm not mistaken, both the original patch and this one
> do not send the copied headers in the PUSH_PROMISE frame.

They both do actually AFAICT, see the changes in ngx_http_v2_push_resource.
Though they don't use HPACK.

Cheers
___
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel


Re: [PATCH] HTTP/2: added support for setting custom push request headers

2018-02-12 Thread Ruslan Ermilov
On Mon, Feb 12, 2018 at 12:35:13PM +, Alessandro Ghedini wrote:
> # HG changeset patch
> # User Alessandro Ghedini 
> # Date 1518438578 0
> #  Mon Feb 12 12:29:38 2018 +
> # Branch http2-push-header
> # Node ID 4eb0c9e8da0bc52065578e4ee78df1833617ac35
> # Parent  a49af443656f2b65ca5de9d8cad5594f44e18ff7
> HTTP/2: added support for setting custom push request headers.
> 
> This implementa the http2_push_header configuration directive that makes
> it possible to set custom request headers for pushed requests.
> 
> Complex values are evaluated in the context of the original request,
> so it's possible to copy its headers into pushed requests.
> 
> Example usage:
> 
> http2_push_header User-Agent $http_user_agent;

If I'm not mistaken, both the original patch and this one
do not send the copied headers in the PUSH_PROMISE frame.

Given the https://trac.nginx.org/nginx/ticket/1478, and some
research of how different implementations behave, I prepared
the following patch:

# HG changeset patch
# User Ruslan Ermilov 
# Date 151803 -10800
#  Mon Feb 12 17:06:43 2018 +0300
# Node ID 4e72b3bfdeaa9917bbdc89a7fa75580c6bec41a7
# Parent  8b0553239592f5d0fd419e5116b9d343838685cf
HTTP/2: push additional headers (ticket #1478).

When pushing requests, copy and push Accept-Encoding, Accept-Language,
and User-Agent header fields from the original request.

diff --git a/src/http/v2/ngx_http_v2_filter_module.c 
b/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
@@ -50,20 +50,37 @@
 #define NGX_HTTP_V2_STATUS_404_INDEX  13
 #define NGX_HTTP_V2_STATUS_500_INDEX  14
 
+#define NGX_HTTP_V2_ACCEPT_ENCODING_INDEX 16
+#define NGX_HTTP_V2_ACCEPT_LANGUAGE_INDEX 17
 #define NGX_HTTP_V2_CONTENT_LENGTH_INDEX  28
 #define NGX_HTTP_V2_CONTENT_TYPE_INDEX31
 #define NGX_HTTP_V2_DATE_INDEX33
 #define NGX_HTTP_V2_LAST_MODIFIED_INDEX   44
 #define NGX_HTTP_V2_LOCATION_INDEX46
 #define NGX_HTTP_V2_SERVER_INDEX  54
+#define NGX_HTTP_V2_USER_AGENT_INDEX  58
 #define NGX_HTTP_V2_VARY_INDEX59
 
 #define NGX_HTTP_V2_NO_TRAILERS   (ngx_http_v2_out_frame_t *) -1
 
 
+typedef struct {
+ngx_str_t authority;
+#if (NGX_HTTP_GZIP)
+ngx_str_t accept_encoding;
+#endif
+#if (NGX_HTTP_HEADERS)
+ngx_str_t accept_language;
+#endif
+ngx_str_t user_agent;
+} ngx_http_v2_push_ctx_t;
+
+
 static ngx_int_t ngx_http_v2_push_resources(ngx_http_request_t *r);
 static ngx_int_t ngx_http_v2_push_resource(ngx_http_request_t *r,
-ngx_str_t *path, ngx_str_t *authority);
+ngx_str_t *path, ngx_http_v2_push_ctx_t *ctx);
+static ngx_int_t ngx_http_v2_indexed_header_encode(ngx_http_request_t *r,
+u_char index, ngx_str_t *value, ngx_str_t *header);
 
 static u_char *ngx_http_v2_string_encode(u_char *dst, u_char *src, size_t len,
 u_char *tmp, ngx_uint_t lower);
@@ -685,16 +702,17 @@ ngx_http_v2_push_resources(ngx_http_requ
 {
 u_char *start, *end, *last;
 ngx_int_t   rc;
-ngx_str_t   path, authority;
+ngx_str_t   path;
 ngx_uint_t  i, push;
 ngx_table_elt_t   **h;
 ngx_http_v2_loc_conf_t *h2lcf;
+ngx_http_v2_push_ctx_t  ctx;
 ngx_http_complex_value_t   *pushes;
 
 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http2 push resources");
 
-ngx_str_null(&authority);
+ngx_memzero(&ctx, sizeof(ngx_http_v2_push_ctx_t));
 
 h2lcf = ngx_http_get_module_loc_conf(r, ngx_http_v2_module);
 
@@ -715,7 +733,7 @@ ngx_http_v2_push_resources(ngx_http_requ
 continue;
 }
 
-rc = ngx_http_v2_push_resource(r, &path, &authority);
+rc = ngx_http_v2_push_resource(r, &path, &ctx);
 
 if (rc == NGX_ERROR) {
 return NGX_ERROR;
@@ -880,7 +898,7 @@ ngx_http_v2_push_resources(ngx_http_requ
 if (push && path.len
 && !(path.len > 1 && path.data[0] == '/' && path.data[1] == '/'))
 {
-rc = ngx_http_v2_push_resource(r, &path, &authority);
+rc = ngx_http_v2_push_resource(r, &path, &ctx);
 
 if (rc == NGX_ERROR) {
 return NGX_ERROR;
@@ -905,11 +923,17 @@ ngx_http_v2_push_resources(ngx_http_requ
 
 static ngx_int_t
 ngx_http_v2_push_resource(ngx_http_request_t *r, ngx_str_t *path,
-ngx_str_t *authority)
+ngx_http_v2_push_ctx_t *ctx)
 {
 u_char*start, *pos, *tmp;
 size_t len;
-ngx_table_elt_t   *host;
+ngx_table_elt_t   *host, *user_agent;
+#if (NGX_HTTP_GZIP)
+ngx_table_elt_t   *accept_encoding;
+#endif
+#if (NGX_HTTP_HEADERS)
+ngx_table_elt_t   *accept_language;
+#endif