H2PushResource 指令不适用于 Apache 中的 http2 服务器推送

H2PushResource directive not working for http2 server push in Apache

我正在使用启用了 h2 的 Apache HTTP 服务器。 H2PushResource 未按预期工作。我想测试服务器推送。

我在 httpd.conf 文件中添加了以下额外的配置行。

Protocols h2 http/1.1
H2PushResource on
<If "%{DOCUMENT_URI} == '/testhttp2.html'">
        H2PushResource add hello3.jpg
</If>

我在 chrome dev-tools 的启动器字段中没有看到此资源的 PUSH。

预加载的添加 Link header 工作正常。预加载的启动器作为 "Other" 出现(如预期的那样)。

此外,有人可以向我解释一下 HTTP2_SESSION_RECV_PUSH_PROMISE 和 HTTP2_SESSION_SEND_RST_STREAM 吗?我可以在 chrome://net-internals/

中看到推送资源
t=62561 [st=   4]    HTTP2_SESSION_RECV_PUSH_PROMISE
                     --> :scheme: https
                         :authority: newapache.com:442
                         :path: style1.css
                         :method: GET
                         cache-control: no-cache
                         user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36
                         accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
                         accept-encoding: gzip, deflate, br
                         accept-language: en-US,en;q=0.9
                         host: newapache.com:442
                     --> id = 1
                     --> promised_stream_id = 4
t=62561 [st=   4]    HTTP2_SESSION_SEND_RST_STREAM
                     --> description = "Invalid pushed request headers."
                     --> error_code = "7 (REFUSED_STREAM)"
                     --> stream_id = 4

t=62562 [st=   5]    HTTP2_SESSION_RECV_RST_STREAM
                     --> error_code = "7 (REFUSED_STREAM)"
                     --> stream_id = 4

你没有正确使用它。

这个命令:

    H2PushResource add hello3.jpg

应该有相对于基本目录的完整路径,所以至少应该有一个前导斜杠:

    H2PushResource add /hello3.jpg

PUSH_PROMISE 消息是从服务器发送到客户端的消息 "I know you didn't ask for it, but I'm going to send you this resource now, let me know if that's a problem." 它的结构类似于 HTTP 请求(HTTP/2 中的 HEADER 帧) 除了它来自服务器而不是客户端 - 它基本上是服务器使用推送资源响应的虚假请求。

RST_STREAM 消息用于重置流 - 这意味着结束正在进行的下载。在这种情况下,客户端(网络浏览器)说 "I don't want the pushed resource because I believe some of the headers are invalid so this is a bad request that I'm going to ignore anyway"。无效的 header 是 :path 伪 header 应该是 /hello3.jpg 而不是 hello3.jpg.

解决此问题后,还应注意其他一些事项:

  1. 该资源必须被页面使用,否则会推送但不显示在网络选项卡中,属于无意义、浪费的推送。虽然它将显示在 chrome://net-internals.

  2. Chrome 不允许缓存(包括推送缓存)用于不安全的连接(例如使用不可信的 self-signed 证书)。因此,除非您在 Chrome 中显示绿色挂锁,否则推送的资源将被忽​​略。

  3. Apache 会记住它在该连接上推送了哪些资源,因此如果在同一连接上,则不应再次推送。使用此命令关闭此功能以使其更易于测试:

    H2PushDiarySize 0
    

推送可能非常复杂,因此请查看我即将出版的书中关于此的章节以获取更多信息:https://livebook.manning.com/#!/book/http2-in-action/chapter-5