如何才能阻止 Caddy 的标题首字母大写?

如何才能阻止 Caddy 的标题首字母大写?

我使用 Caddy 作为我的 VPS 上的代理服务器,

这是我的 Caddyfile 配置:

https://api.yuhenabc.com {
    gzip
    tls /etc/ssl/caddy/chained.crt /etc/ssl/caddy/private.key
    proxy / 127.0.0.1:5000 {
        header_downstream -Server
    }
}

配置正常,你也可以使用其他的,

问题是代理后的标头是“小写”,

例如“Content-Type”==>“content-type”

那么,有没有办法阻止 Caddy 将首字母大写?

使用 curl 查看差异:

~ curl -I https://agent.yuhenabc.com/
HTTP/2 200 
accept-ranges: bytes
content-type: text/html
date: Sun, 04 Aug 2019 01:55:34 GMT
etag: "2d-573507058d0c0"
last-modified: Mon, 13 Aug 2018 12:43:23 GMT
server: Caddy
content-length: 45

原来的:

~ curl -I http://127.0.0.1:5000               
HTTP/1.1 200 OK
Date: Sun, 04 Aug 2019 02:19:06 GMT
Server: Apache/2.4.34 (Unix) LibreSSL/2.5.5 PHP/7.1.23
Last-Modified: Mon, 13 Aug 2018 12:43:23 GMT
ETag: "2d-573507058d0c0"
Accept-Ranges: bytes
Content-Length: 45
Content-Type: text/html

答案1

这个是正常的。

在 HTTP/1.x 中,标头名称不区分大小写. 应用程序是必需的接受Content-Typecontent-type和甚至CoNtEnT-tYpE作为相同的标题。

RFC 7230:3.2. 标头字段

每个标头字段由一个不区分大小写的字段名称(后跟冒号(“:”))、可选的前导空格、字段值和可选的尾随空格组成。

HTTP/2 也是如此,但标头还总是 以小写形式发送根据规范。由于 cURL 和 Caddy 都支持 HTTP/2 并尽可能使用它,因此您将始终看到全小写的标头 - 任何其他内容都会违反协议的规范。

RFC 7540:8.1.2. HTTP 标头字段

与 HTTP/1.x 一样,标头字段名称是 ASCII 字符串,以不区分大小写的方式进行比较。但是,在 HTTP/2 中,标头字段名称在编码之前必须转换为小写。包含大写标头字段名称的请求或响应必须被视为格式错误。

答案2

如果你真的非常勇敢,你可以用 Golang 1.19.5 创建一个新的 GOROOT,并将这四个文件替换为我制作的这个 Golang fork

  • src/net/http/header.go
  • src/net/http/request.go
  • src/net/http/server.go
  • src/net/textproto/reader.go

然后,使用指向你的 GOROOT 的 xcaddy 构建 Caddy:

GOROOT=/home/porech/my-custom-goroot/go1.19.5 XCADDY_WHICH_GO=/home/porech/my-custom-goroot/go1.19.5/bin/go xcaddy build

我当时非常绝望,我绝对需要这个,我建议你只有在同样的情况下才这样做。我在生产中使用它并且它有效,但可能存在我不知道的重要副作用!

相关内容