将 http2_push 与 nginX 结合使用 HAProxy 不起作用
Using http2_push with nginX in conjunction with HAProxy does not work
当 nginX 配置在 HaProxy 后面时,我无法 HTTP/2 推送工作。但是,当网络浏览器直接访问 nginX 时,确实 工作。
已经做了很多研究,但没有找到任何提示。希望有人知道我做错了什么。请参阅下面的配置和进一步观察。
配置
相关的HaProxy(版本1.8.7)配置为:
frontend appname
bind *:443 ssl crt certificate.pem alpn h2,http/1.1
mode tcp
use_backend app-http2 if { ssl_fc_alpn -i h2 }
default_backend app
backend app-http2
mode tcp
server lamp2 127.0.0.1:8002 check send-proxy
以及相关的nginX(1.14.0版本)配置如下:
http {
# This is the one I would like to use
server {
listen 8002 http2 proxy_protocol;
server_name _;
root /usr/share/nginx/html;
location / {
http2_push /image.jpg;
}
}
# This one can be accessed directly; and *does* work
server {
listen 8004 http2 ssl;
ssl_certificate certificate.pem;
ssl_certificate_key private.key;
server_name _;
root /usr/share/nginx/html;
location / {
http2_push /image.jpg;
}
}
}
观察结果
- 在 nginx 日志中,我可以验证两种访问内容的方式都使用 HTTP2。
- 当我用Chrome访问页面时看到push是只在直接访问nginX
时使用
2018 年 5 月 9 日更新
还是没有解决。但人们似乎同意这是一个错误。我在他们的问题跟踪器上打开了一个问题:https://trac.nginx.org/nginx/ticket/1549#ticket
2018 年 4 月 26 日更新
看来问题不仅仅是 http2 推送。如果我记录 $scheme
nginX 变量,它总是设置为 http
。无论是从 http 访问还是从 http2.
所以这显然是问题所在。但是我不确定如何解决这个问题。 Haproxy 工作在 tcp 模式;因此可能不会做错任何事。
一个相关(但可能已过时)的 Stack Overflow 主题是 nginx $scheme variable behind load balancer。但是这个答案对解决这个问题没有帮助!
2018 年 4 月 25 日更新
还是不行。而是更近了一步。 运行 nghttp2,结果如下。
两者似乎都嵌入了 /image.jpg 资源。但是通过 haproxy 的方案将其方案设置为 http;而不是 https。正如在这个差异中看到的那样:
我想是因为这个; Chrome 不会使用这个推送的资源。但是我不确定是什么原因造成的!
有人知道吗?
两条命令的完整输出:
nghttp -nv https://127.0.0.1:8004/
[ 0.001] Connected
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: /
:scheme: https
:authority: 127.0.0.1:8004
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.25.0
[ 0.003] recv SETTINGS frame
(niv=3)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
[SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
[ 0.003] recv WINDOW_UPDATE frame
(window_size_increment=2147418112)
[ 0.003] send SETTINGS frame
; ACK
(niv=0)
[ 0.003] recv SETTINGS frame
; ACK
(niv=0)
[ 0.003] recv (stream_id=13) :method: GET
[ 0.003] recv (stream_id=13) :path: /image.jpg
[ 0.003] recv (stream_id=13) :scheme: https
[ 0.003] recv (stream_id=13) :authority: 127.0.0.1:8004
[ 0.003] recv (stream_id=13) accept-encoding: gzip, deflate
[ 0.003] recv (stream_id=13) user-agent: nghttp2/1.25.0
[ 0.003] recv PUSH_PROMISE frame
; END_HEADERS
(padlen=0, promised_stream_id=2)
[ 0.003] recv (stream_id=13) :status: 200
[ 0.003] recv (stream_id=13) server: nginx/1.14.0
[ 0.003] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:26 GMT
[ 0.003] recv (stream_id=13) content-type: text/html
[ 0.003] recv (stream_id=13) content-length: 638
[ 0.003] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT
[ 0.003] recv (stream_id=13) etag: "5ae069c2-27e"
[ 0.003] recv (stream_id=13) accept-ranges: bytes
[ 0.003] 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.14.0
[ 0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:26 GMT
[ 0.004] recv (stream_id=2) content-type: image/jpeg
[ 0.004] recv (stream_id=2) content-length: 182884
[ 0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT
[ 0.004] recv (stream_id=2) etag: "57656be2-2ca64"
[ 0.004] recv (stream_id=2) accept-ranges: bytes
[ 0.004] recv HEADERS frame
; END_HEADERS
(padlen=0)
; First push response header
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] send WINDOW_UPDATE frame
(window_size_increment=33248)
[ 0.004] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] send WINDOW_UPDATE frame
(window_size_increment=32925)
[ 0.046] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.046] recv DATA frame
[ 0.046] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.046] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.046] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] recv DATA frame
[ 0.090] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.090] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.090] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.090] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.134] recv DATA frame
[ 0.134] recv DATA frame
[ 0.134] recv DATA frame
; END_STREAM
[ 0.134] send GOAWAY frame
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
和
nghttp -nv https://127.0.0.1:8002/
[ 0.001] Connected
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: /
:scheme: https
:authority: 127.0.0.1:8002
accept: */*
accept-encoding: gzip, deflate
user-agent: nghttp2/1.25.0
[ 0.003] recv SETTINGS frame
(niv=3)
[SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128]
[SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536]
[SETTINGS_MAX_FRAME_SIZE(0x05):16777215]
[ 0.003] recv WINDOW_UPDATE frame
(window_size_increment=2147418112)
[ 0.003] 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: /image.jpg
[ 0.004] recv (stream_id=13) :scheme: http
[ 0.004] recv (stream_id=13) :authority: 127.0.0.1:8002
[ 0.004] recv (stream_id=13) accept-encoding: gzip, deflate
[ 0.004] recv (stream_id=13) user-agent: nghttp2/1.25.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.14.0
[ 0.004] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:45 GMT
[ 0.004] recv (stream_id=13) content-type: text/html
[ 0.004] recv (stream_id=13) content-length: 638
[ 0.004] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT
[ 0.004] recv (stream_id=13) etag: "5ae069c2-27e"
[ 0.004] recv (stream_id=13) accept-ranges: bytes
[ 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.14.0
[ 0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:45 GMT
[ 0.004] recv (stream_id=2) content-type: image/jpeg
[ 0.004] recv (stream_id=2) content-length: 182884
[ 0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT
[ 0.004] recv (stream_id=2) etag: "57656be2-2ca64"
[ 0.004] recv (stream_id=2) accept-ranges: bytes
[ 0.004] recv HEADERS frame
; END_HEADERS
(padlen=0)
; First push response header
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] send WINDOW_UPDATE frame
(window_size_increment=33406)
[ 0.004] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.004] recv DATA frame
[ 0.044] recv DATA frame
[ 0.044] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.044] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.044] recv DATA frame
[ 0.044] recv DATA frame
[ 0.045] recv DATA frame
[ 0.045] recv DATA frame
[ 0.045] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.045] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.045] recv DATA frame
[ 0.045] recv DATA frame
[ 0.045] recv DATA frame
[ 0.045] recv DATA frame
[ 0.045] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.045] send WINDOW_UPDATE frame
(window_size_increment=32767)
[ 0.045] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.046] send WINDOW_UPDATE frame
(window_size_increment=32768)
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
[ 0.046] recv DATA frame
; END_STREAM
[ 0.046] send GOAWAY frame
(last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
看来 Chrome 确保如果在与通过 https
方案服务的请求相对应的流上发送推送,则承诺也使用相同的方案:https://chromium.googlesource.com/chromium/src/+/master/net/spdy/chromium/spdy_session.cc#1766
我不确定检查是否正确:RFC 7540 表示发送 PUSH_PROMISE
的服务器应该是权威的。对于 http
这意味着主机名匹配,因此浏览器应该能够处理该文件。
也就是说,即使浏览器接受了推送,它也只会在浏览器发出针对 http://127.0.0.1:8002/image.jpg
的请求时使用它。如果 HTML 是通过 https
获得的并且它请求 /image.jpg
,那么我不确定浏览器是否会接受获取 http://127.0.0.1:8002/image.jpg
.
这让我们将 nginx 设置为 http
。我认为这是由于 haproxy 执行 SSL 终止这一事实,因此 ngnix 看到一个明文连接传入,就它而言,方案 是 http
。我对 ngnix 的了解还不够,无法为此提出修复建议。
我最终在 NginX 跟踪器上开了一张票。它得到修复。该修复程序在最近发布的 1.15.1 版本中可用。
Bugfix: HTTP/2 server push did not work if SSL was terminated by a proxy server in front of nginx.
感谢您的帮助!
当 nginX 配置在 HaProxy 后面时,我无法 HTTP/2 推送工作。但是,当网络浏览器直接访问 nginX 时,确实 工作。
已经做了很多研究,但没有找到任何提示。希望有人知道我做错了什么。请参阅下面的配置和进一步观察。
配置
相关的HaProxy(版本1.8.7)配置为:
frontend appname bind *:443 ssl crt certificate.pem alpn h2,http/1.1 mode tcp use_backend app-http2 if { ssl_fc_alpn -i h2 } default_backend app backend app-http2 mode tcp server lamp2 127.0.0.1:8002 check send-proxy
以及相关的nginX(1.14.0版本)配置如下:
http { # This is the one I would like to use server { listen 8002 http2 proxy_protocol; server_name _; root /usr/share/nginx/html; location / { http2_push /image.jpg; } } # This one can be accessed directly; and *does* work server { listen 8004 http2 ssl; ssl_certificate certificate.pem; ssl_certificate_key private.key; server_name _; root /usr/share/nginx/html; location / { http2_push /image.jpg; } } }
观察结果
- 在 nginx 日志中,我可以验证两种访问内容的方式都使用 HTTP2。
- 当我用Chrome访问页面时看到push是只在直接访问nginX 时使用
2018 年 5 月 9 日更新 还是没有解决。但人们似乎同意这是一个错误。我在他们的问题跟踪器上打开了一个问题:https://trac.nginx.org/nginx/ticket/1549#ticket
2018 年 4 月 26 日更新
看来问题不仅仅是 http2 推送。如果我记录 $scheme
nginX 变量,它总是设置为 http
。无论是从 http 访问还是从 http2.
所以这显然是问题所在。但是我不确定如何解决这个问题。 Haproxy 工作在 tcp 模式;因此可能不会做错任何事。
一个相关(但可能已过时)的 Stack Overflow 主题是 nginx $scheme variable behind load balancer。但是这个答案对解决这个问题没有帮助!
2018 年 4 月 25 日更新
还是不行。而是更近了一步。 运行 nghttp2,结果如下。
两者似乎都嵌入了 /image.jpg 资源。但是通过 haproxy 的方案将其方案设置为 http;而不是 https。正如在这个差异中看到的那样:
我想是因为这个; Chrome 不会使用这个推送的资源。但是我不确定是什么原因造成的!
有人知道吗?
两条命令的完整输出:
nghttp -nv https://127.0.0.1:8004/ [ 0.001] Connected 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: / :scheme: https :authority: 127.0.0.1:8004 accept: */* accept-encoding: gzip, deflate user-agent: nghttp2/1.25.0 [ 0.003] recv SETTINGS frame (niv=3) [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128] [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536] [SETTINGS_MAX_FRAME_SIZE(0x05):16777215] [ 0.003] recv WINDOW_UPDATE frame (window_size_increment=2147418112) [ 0.003] send SETTINGS frame ; ACK (niv=0) [ 0.003] recv SETTINGS frame ; ACK (niv=0) [ 0.003] recv (stream_id=13) :method: GET [ 0.003] recv (stream_id=13) :path: /image.jpg [ 0.003] recv (stream_id=13) :scheme: https [ 0.003] recv (stream_id=13) :authority: 127.0.0.1:8004 [ 0.003] recv (stream_id=13) accept-encoding: gzip, deflate [ 0.003] recv (stream_id=13) user-agent: nghttp2/1.25.0 [ 0.003] recv PUSH_PROMISE frame ; END_HEADERS (padlen=0, promised_stream_id=2) [ 0.003] recv (stream_id=13) :status: 200 [ 0.003] recv (stream_id=13) server: nginx/1.14.0 [ 0.003] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:26 GMT [ 0.003] recv (stream_id=13) content-type: text/html [ 0.003] recv (stream_id=13) content-length: 638 [ 0.003] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT [ 0.003] recv (stream_id=13) etag: "5ae069c2-27e" [ 0.003] recv (stream_id=13) accept-ranges: bytes [ 0.003] 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.14.0 [ 0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:26 GMT [ 0.004] recv (stream_id=2) content-type: image/jpeg [ 0.004] recv (stream_id=2) content-length: 182884 [ 0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT [ 0.004] recv (stream_id=2) etag: "57656be2-2ca64" [ 0.004] recv (stream_id=2) accept-ranges: bytes [ 0.004] recv HEADERS frame ; END_HEADERS (padlen=0) ; First push response header [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] send WINDOW_UPDATE frame (window_size_increment=33248) [ 0.004] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] send WINDOW_UPDATE frame (window_size_increment=32925) [ 0.046] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.046] recv DATA frame [ 0.046] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.046] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.046] recv DATA frame [ 0.090] recv DATA frame [ 0.090] recv DATA frame [ 0.090] recv DATA frame [ 0.090] recv DATA frame [ 0.090] recv DATA frame [ 0.090] recv DATA frame [ 0.090] recv DATA frame [ 0.090] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.090] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.090] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.090] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.134] recv DATA frame [ 0.134] recv DATA frame [ 0.134] recv DATA frame ; END_STREAM [ 0.134] send GOAWAY frame (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
和
nghttp -nv https://127.0.0.1:8002/ [ 0.001] Connected 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: / :scheme: https :authority: 127.0.0.1:8002 accept: */* accept-encoding: gzip, deflate user-agent: nghttp2/1.25.0 [ 0.003] recv SETTINGS frame (niv=3) [SETTINGS_MAX_CONCURRENT_STREAMS(0x03):128] [SETTINGS_INITIAL_WINDOW_SIZE(0x04):65536] [SETTINGS_MAX_FRAME_SIZE(0x05):16777215] [ 0.003] recv WINDOW_UPDATE frame (window_size_increment=2147418112) [ 0.003] 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: /image.jpg [ 0.004] recv (stream_id=13) :scheme: http [ 0.004] recv (stream_id=13) :authority: 127.0.0.1:8002 [ 0.004] recv (stream_id=13) accept-encoding: gzip, deflate [ 0.004] recv (stream_id=13) user-agent: nghttp2/1.25.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.14.0 [ 0.004] recv (stream_id=13) date: Wed, 25 Apr 2018 15:08:45 GMT [ 0.004] recv (stream_id=13) content-type: text/html [ 0.004] recv (stream_id=13) content-length: 638 [ 0.004] recv (stream_id=13) last-modified: Wed, 25 Apr 2018 11:42:58 GMT [ 0.004] recv (stream_id=13) etag: "5ae069c2-27e" [ 0.004] recv (stream_id=13) accept-ranges: bytes [ 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.14.0 [ 0.004] recv (stream_id=2) date: Wed, 25 Apr 2018 15:08:45 GMT [ 0.004] recv (stream_id=2) content-type: image/jpeg [ 0.004] recv (stream_id=2) content-length: 182884 [ 0.004] recv (stream_id=2) last-modified: Sat, 18 Jun 2016 15:42:26 GMT [ 0.004] recv (stream_id=2) etag: "57656be2-2ca64" [ 0.004] recv (stream_id=2) accept-ranges: bytes [ 0.004] recv HEADERS frame ; END_HEADERS (padlen=0) ; First push response header [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] send WINDOW_UPDATE frame (window_size_increment=33406) [ 0.004] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.004] recv DATA frame [ 0.044] recv DATA frame [ 0.044] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.044] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.044] recv DATA frame [ 0.044] recv DATA frame [ 0.045] recv DATA frame [ 0.045] recv DATA frame [ 0.045] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.045] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.045] recv DATA frame [ 0.045] recv DATA frame [ 0.045] recv DATA frame [ 0.045] recv DATA frame [ 0.045] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.045] send WINDOW_UPDATE frame (window_size_increment=32767) [ 0.045] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.046] send WINDOW_UPDATE frame (window_size_increment=32768) [ 0.046] recv DATA frame [ 0.046] recv DATA frame [ 0.046] recv DATA frame ; END_STREAM [ 0.046] send GOAWAY frame (last_stream_id=2, error_code=NO_ERROR(0x00), opaque_data(0)=[])
看来 Chrome 确保如果在与通过 https
方案服务的请求相对应的流上发送推送,则承诺也使用相同的方案:https://chromium.googlesource.com/chromium/src/+/master/net/spdy/chromium/spdy_session.cc#1766
我不确定检查是否正确:RFC 7540 表示发送 PUSH_PROMISE
的服务器应该是权威的。对于 http
这意味着主机名匹配,因此浏览器应该能够处理该文件。
也就是说,即使浏览器接受了推送,它也只会在浏览器发出针对 http://127.0.0.1:8002/image.jpg
的请求时使用它。如果 HTML 是通过 https
获得的并且它请求 /image.jpg
,那么我不确定浏览器是否会接受获取 http://127.0.0.1:8002/image.jpg
.
这让我们将 nginx 设置为 http
。我认为这是由于 haproxy 执行 SSL 终止这一事实,因此 ngnix 看到一个明文连接传入,就它而言,方案 是 http
。我对 ngnix 的了解还不够,无法为此提出修复建议。
我最终在 NginX 跟踪器上开了一张票。它得到修复。该修复程序在最近发布的 1.15.1 版本中可用。
Bugfix: HTTP/2 server push did not work if SSL was terminated by a proxy server in front of nginx.
感谢您的帮助!