Welcome! Log In Create A New Profile

Advanced

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

Alessandro Ghedini
February 12, 2018 10:32AM
On Mon, Feb 12, 2018 at 05:11:55PM +0300, Ruslan Ermilov wrote:
> On Mon, Feb 12, 2018 at 12:35:13PM +0000, Alessandro Ghedini wrote:
> > # HG changeset patch
> > # User Alessandro Ghedini <alessandro@ghedini.me>
> > # Date 1518438578 0
> > # Mon Feb 12 12:29:38 2018 +0000
> > # 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_preload on;


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 <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
(dep_stream_id=0, weight=201, exclusive=0)
[ 0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
(dep_stream_id=0, weight=101, exclusive=0)
[ 0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
(dep_stream_id=0, weight=1, exclusive=0)
[ 0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
(dep_stream_id=7, weight=1, exclusive=0)
[ 0.003] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
(dep_stream_id=3, weight=1, exclusive=0)
[ 0.003] send HEADERS frame <length=44, flags=0x25, stream_id=13>
; 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 <length=18, flags=0x00, stream_id=0>
(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 <length=4, flags=0x00, stream_id=0>
(window_size_increment=2147418112)
[ 0.004] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.004] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
; 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 <length=47, flags=0x04, stream_id=13>
; 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 <length=105, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0)
; First response header
[ 0.004] recv DATA frame <length=32, flags=0x01, stream_id=13>
; 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 <length=48, flags=0x04, stream_id=2>
; END_HEADERS
(padlen=0)
; First push response header
[ 0.004] recv DATA frame <length=1, flags=0x01, stream_id=2>
; END_STREAM
[ 0.004] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])

Notice how the response of the pushed request doesn't actually get compressed.
Additionally from the access logs I see:

127.0.0.1 - - [12/Feb/2018:15:18:39 +0000] "GET /hello HTTP/2.0" 200 32 "-" "nghttp2/1.29.0"
127.0.0.1 - - [12/Feb/2018:15:18:39 +0000] "GET /a HTTP/2.0" 200 1 "-" "-"

The second one is the pushed request, notice how it doesn't have a user agent
unlike the first request (which is the one coming from the client directly).

With my patch (the one with the custom config directive, but this mostly applies
to the other one as well) however I get this:

% nghttp https://127.0.0.1:4433/hello -vn
[ 0.002] Connected
[WARNING] Certificate verification failed: Hostname mismatch
The negotiated protocol: h2
[ 0.004] send SETTINGS frame <length=12, flags=0x00, stream_id=0>
(niv=2)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):100]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65535]
[ 0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=3>
(dep_stream_id=0, weight=201, exclusive=0)
[ 0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=5>
(dep_stream_id=0, weight=101, exclusive=0)
[ 0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=7>
(dep_stream_id=0, weight=1, exclusive=0)
[ 0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=9>
(dep_stream_id=7, weight=1, exclusive=0)
[ 0.004] send PRIORITY frame <length=5, flags=0x00, stream_id=11>
(dep_stream_id=3, weight=1, exclusive=0)
[ 0.004] send HEADERS frame <length=44, flags=0x25, stream_id=13>
; 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 <length=18, flags=0x00, stream_id=0>
(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 <length=4, flags=0x00, stream_id=0>
(window_size_increment=2147418112)
[ 0.004] send SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.005] recv SETTINGS frame <length=0, flags=0x01, stream_id=0>
; ACK
(niv=0)
[ 0.005] recv (stream_id=13) :method: GET
[ 0.005] recv (stream_id=13) :path: /a
[ 0.005] recv (stream_id=13) :authority: 127.0.0.1:4433
[ 0.005] recv (stream_id=13) :scheme: https
[ 0.005] recv (stream_id=13) accept-encoding: gzip, deflate
[ 0.005] recv (stream_id=13) user-agent: nghttp2/1.29.0
[ 0.005] recv PUSH_PROMISE frame <length=67, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0, promised_stream_id=2)
[ 0.005] recv (stream_id=13) :status: 200
[ 0.005] recv (stream_id=13) server: nginx/1.13.9
[ 0.005] recv (stream_id=13) date: Mon, 12 Feb 2018 15:27:14 GMT
[ 0.005] recv (stream_id=13) content-type: text/plain
[ 0.005] recv (stream_id=13) last-modified: Thu, 08 Feb 2018 15:43:05 GMT
[ 0.005] recv (stream_id=13) etag: W/"5a7c7009-1f5"
[ 0.005] recv (stream_id=13) content-encoding: gzip
[ 0.005] recv HEADERS frame <length=105, flags=0x04, stream_id=13>
; END_HEADERS
(padlen=0)
; First response header
[ 0.005] recv DATA frame <length=32, flags=0x01, stream_id=13>
; END_STREAM
[ 0.006] recv (stream_id=2) :status: 200
[ 0.006] recv (stream_id=2) server: nginx/1.13.9
[ 0.006] recv (stream_id=2) date: Mon, 12 Feb 2018 15:27:14 GMT
[ 0.006] recv (stream_id=2) content-type: text/plain
[ 0.006] recv (stream_id=2) content-encoding: gzip
[ 0.006] recv HEADERS frame <length=62, flags=0x04, stream_id=2>
; END_HEADERS
(padlen=0)
; First push response header
[ 0.006] recv DATA frame <length=21, flags=0x01, stream_id=2>
; END_STREAM
[ 0.006] send GOAWAY frame <length=8, flags=0x00, stream_id=0>
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])

The second response is compressed and the logs look like this:

127.0.0.1 - - [12/Feb/2018:15:27:14 +0000] "GET /hello HTTP/2.0" 200 32 "-" "nghttp2/1.29.0"
127.0.0.1 - - [12/Feb/2018:15:27:14 +0000] "GET /a HTTP/2.0" 200 21 "-" "nghttp2/1.29.0"

Cheers
_______________________________________________
nginx-devel mailing list
nginx-devel@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx-devel
Subject Author Views Posted

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

Alessandro Ghedini 617 February 12, 2018 07:38AM

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

ru@nginx.com 674 February 12, 2018 09:14AM

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

Alessandro Ghedini 373 February 12, 2018 10:20AM

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

Alessandro Ghedini 496 February 12, 2018 10:32AM

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

Alessandro Ghedini 412 February 13, 2018 07:00AM

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

ru@nginx.com 535 February 14, 2018 02:50PM



Sorry, you do not have permission to post/reply in this forum.

Online Users

Guests: 318
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 421 on December 02, 2018
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready