调试信息

调试信息

我刚刚设置了一个小型 Apache VM 并启用了 HTTP/2 模块,如文档中所述(HTTP/2 指南)。为了测试它,建议使用非浏览器客户端curl。但是,我注意到一些奇怪的问题。

curl被告知使用 HTTP2 ( curl --http2) 时,Apache 会在 中写入 2 行,access.log而不是通常的单行。此外,第一行的日期完全错误(有时甚至为空),第二行的协议是 HTTP/1.1 而不是预期的 HTTP/2:

192.168.122.1 - - [31/Dec/1969:21:00:00 -0300] "GET / HTTP/2.0" 200 10922 "-" "curl/7.74.0"
192.168.122.1 - - [19/Mar/2023:04:55:34 -0300] "GET / HTTP/1.1" 101 10967 "-" "curl/7.74.0"

以下是此类问题的更多示例access.log

192.168.122.1 - -  "GET / HTTP/2.0" 200 10922 "-" "curl/7.74.0"
192.168.122.1 - - [19/Mar/2023:06:26:31 -0300] "GET / HTTP/1.1" 101 10967 "-" "curl/7.74.0"
192.168.122.1 - -  "GET / HTTP/2.0" 200 10922 "-" "curl/7.74.0"
192.168.122.1 - - [19/Mar/2023:06:26:36 -0300] "GET / HTTP/1.1" 101 10967 "-" "curl/7.74.0"
192.168.122.1 - - [00/Jan/1900:00:00:00 +0000] "GET / HTTP/2.0" 200 10922 "-" "curl/7.74.0"
192.168.122.1 - - [19/Mar/2023:06:26:39 -0300] "GET / HTTP/1.1" 101 10967 "-" "curl/7.74.0"
192.168.122.1 - - [00/Jan/1900:00:00:00 +0000] "GET / HTTP/2.0" 200 10922 "-" "curl/7.74.0"
192.168.122.1 - - [19/Mar/2023:06:26:48 -0300] "GET / HTTP/1.1" 101 10950 "-" "curl/7.74.0"

curl当切换回 HTTP/1.0 或 HTTP/1.1时,不会出现此问题。

任何想法?


调试信息

虚拟机设置

  • 虚拟化: libvirt管理KVM

  • 操作系统:Debian 11(仅 CLI,无 DE)

  • 任务:

      [X] web server
      [X] SSH server
    

    注意:其他一切都未选中。

  • 阿帕奇:模块http2在其默认配置中启用

      root@debian:~# apachectl -M
      AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 127.0.1.1. Set the 'ServerName' directive globally to suppress this message
      Loaded Modules:
       [...]
       http2_module (shared)
    

    注意:http2模块在启用模块的情况下不起作用prefork。但是,默认情况下prefork模块被禁用。

通过curl的HTTP 1.0

root@debian:~# curl -v -s --http1.0 http://192.168.122.190/ > /dev/null

*   Trying 192.168.122.190:80...
* Connected to 192.168.122.190 (192.168.122.190) port 80 (#0)
> GET / HTTP/1.0
> Host: 192.168.122.190
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 19 Mar 2023 07:44:03 GMT
< Server: Apache/2.4.54 (Debian)
< Upgrade: h2,h2c
< Connection: Upgrade, close
< Last-Modified: Fri, 17 Mar 2023 08:12:30 GMT
< ETag: "29cd-5f7142383c2f1"
< Accept-Ranges: bytes
< Content-Length: 10701
< Vary: Accept-Encoding
< Content-Type: text/html
< 
{ [10701 bytes data]
* Closing connection 0


root@debian:~# tail -f /var/log/apache2/access.log
[...]
192.168.122.1 - - [19/Mar/2023:04:44:03 -0300] "GET / HTTP/1.0" 200 11001 "-" "curl/7.74.0"

通过curl的HTTP 1.1

root@debian:~# curl -v -s --http1.1 http://192.168.122.190/ > /dev/null

*   Trying 192.168.122.190:80...
* Connected to 192.168.122.190 (192.168.122.190) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.122.190
> User-Agent: curl/7.74.0
> Accept: */*
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Sun, 19 Mar 2023 07:47:42 GMT
< Server: Apache/2.4.54 (Debian)
< Upgrade: h2,h2c
< Connection: Upgrade
< Last-Modified: Fri, 17 Mar 2023 08:12:30 GMT
< ETag: "29cd-5f7142383c2f1"
< Accept-Ranges: bytes
< Content-Length: 10701
< Vary: Accept-Encoding
< Content-Type: text/html
< 
{ [6947 bytes data]
* Connection #0 to host 192.168.122.190 left intact


root@debian:~# tail -f /var/log/apache2/access.log
[...]
192.168.122.1 - - [19/Mar/2023:04:47:42 -0300] "GET / HTTP/1.1" 200 10994 "-" "curl/7.74.0"

通过curl的HTTP 2.0

root@debian:~# curl -v -s --http2 http://192.168.122.190/ > /dev/null

*   Trying 192.168.122.190:80...
* Connected to 192.168.122.190 (192.168.122.190) port 80 (#0)
> GET / HTTP/1.1
> Host: 192.168.122.190
> User-Agent: curl/7.74.0
> Accept: */*
> Connection: Upgrade, HTTP2-Settings
> Upgrade: h2c
> HTTP2-Settings: AAMAAABkAAQCAAAAAAIAAAAA
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 101 Switching Protocols
< Upgrade: h2c
< Connection: Upgrade
* Received 101
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200 
< last-modified: Fri, 17 Mar 2023 08:12:30 GMT
< etag: W/"29cd-5f7142383c2f1"
< accept-ranges: bytes
< content-length: 10701
< vary: Accept-Encoding
< content-type: text/html
< date: Thu, 01 Jan 1970 00:00:00 GMT
< server: Apache/2.4.54 (Debian)
< 
{ [7099 bytes data]
* Connection #0 to host 192.168.122.190 left intact


root@debian:~# tail -f /var/log/apache2/access.log
[...]
192.168.122.1 - - [31/Dec/1969:21:00:00 -0300] "GET / HTTP/2.0" 200 10922 "-" "curl/7.74.0"
192.168.122.1 - - [19/Mar/2023:04:55:34 -0300] "GET / HTTP/1.1" 101 10967 "-" "curl/7.74.0"

通过curl的HTTP 2.0(非TLS)

root@debian:~# curl -v -s --http2-prior-knowledge http://192.168.122.190/ > /dev/null

*   Trying 192.168.122.190:80...
* Connected to 192.168.122.190 (192.168.122.190) port 80 (#0)
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x561926605ce0)
> GET / HTTP/2
> Host: 192.168.122.190
> user-agent: curl/7.74.0
> accept: */*
> 
* Connection state changed (MAX_CONCURRENT_STREAMS == 100)!
< HTTP/2 200 
< last-modified: Fri, 17 Mar 2023 08:12:30 GMT
< etag: "29cd-5f7142383c2f1"
< accept-ranges: bytes
< content-length: 10701
< vary: Accept-Encoding
< content-type: text/html
< date: Sun, 19 Mar 2023 07:59:47 GMT
< server: Apache/2.4.54 (Debian)
< 
{ [10701 bytes data]
* Connection #0 to host 192.168.122.190 left intact


root@debian:~# tail -f /var/log/apache2/access.log
[...]
192.168.122.1 - - [19/Mar/2023:04:59:47 -0300] "GET / HTTP/2.0" 200 10920 "-" "curl/7.74.0"

检查curl功能:

root@debian:~# curl -V
curl 7.74.0 (x86_64-pc-linux-gnu) libcurl/7.74.0 OpenSSL/1.1.1n zlib/1.2.11 brotli/1.0.9 libidn2/2.3.0 libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.43.0 librtmp/2.3
Release-Date: 2020-12-09
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets

注意:因此,该curl版本支持HTTP/2。

答案1

除了似乎来自 Apache 中的 HTTP/2 子系统的时间戳被严重损坏之外,我们还看到您的 HTTP/2 连接是正在升级到 HTTP/2 的 HTTP/1.1 连接。从这个角度来看,拥有两个日志条目是完全明智的。

来自HTTP/2 常见问题解答:

我可以在不实现 HTTP/1.1 的情况下实现 HTTP/2 吗?

是的,大部分是。

对于 HTTP/2 over TLS (h2),如果您不实现 http1.1 ALPN 标识符,那么您将不需要支持任何 HTTP/1.1 功能。

对于 HTTP/2 over TCP (h2c),您需要实现初始升级请求。

你是不是执行 TLS,所以您正在执行h2c.因此,HTTP/1.1 请求是不可避免的。

答案2

您遇到了 Apache 的 http2 模块中的错误。我在2023年11月22日报告了这个问题,第二天就修复了,参见h2c w/ 的日期被破坏curl --http2· Issue #272 · icing/mod_h2

据开发者称,req->request_time = apr_time_now();中缺少a mod_http2/h2_request.c

相关内容