【问题标题】:httputil DumpRequest Host header excluded?排除 httputil DumpRequest Host 标头?
【发布时间】:2021-04-30 20:31:30
【问题描述】:

我正在编写一个需要调用 DumpRequest 的 http 代理。出于某种原因,客户端在服务器需要时不提供“主机”标头。然后我这样做:

if req.Header.Get("host") == "" {
    req.Header.Set("Host", "www.domain.com:80")
}
data, _ := httputil.DumpRequest(req, true)
conn.Write(data)

问题是我设置“主机”后,data 仍然没有。我深入研究了 DumpRequest 的源代码,发现了这个:

var reqWriteExcludeHeaderDump = map[string]bool{
    "Host":              true, // not in Header map anyway
    "Transfer-Encoding": true,
    "Trailer":           true,
}

为什么Host“反正不在Header map中”?

【问题讨论】:

  • 主机在请求上有一个专用参数
  • @Chris Townsend 不明白这意味着什么。这是我的代理尝试转发的请求。后端服务器返回“400 Bad Request missing required header Host”...这就是我尝试添加 Host: 标头的原因。
  • 您不要使用Header.Set 更改主机。您可以使用req.Host 直接访问它,就像我的回答显示的那样
  • @ChrisTownsend 看到 Header.Set 和 Header.Add 的源代码,逻辑一清二楚。

标签: http go proxy


【解决方案1】:

简答

我猜你应该使用Header.Add() 而不是Header.Set()

我没试过。因此,如果我的回答有误,请自行解决。

参考

来自source code,它说。

它替换与键关联的任何现有值

但在你的情况下,你没有那个 K 存在。所以它的行为符合我们的预期。

如果你使用Set() 方法,那就太酷了。

【讨论】:

  • 我确信这个答案是错误的。因为当我使用 Set 并转储 req.Header 时,主机已设置。唯一的问题是它不在 DumpRequest() 的输出中
【解决方案2】:

不应使用 DumpRequest 来实现代理 - 请参阅 doc

It should only be used by servers to debug client requests. The returned
representation is an approximation only ...

【讨论】:

    【解决方案3】:

    如果您在通过代理时尝试更改请求的原始主机值,则无需更改主机标头。您可以执行以下操作:

    if req.Host == "" {
        req.Host = "www.domain.com"
    }
    data, _ := httputil.DumpRequest(req, true)
    conn.Write(data)
    

    游乐场 https://play.golang.org/p/f-qaZRC0RMO

    【讨论】:

    • 这正是我所做的。请仔细阅读问题并自行测试:在 DumpRequest() 之后,数据中没有“Host”标头。
    • 游乐场显示数据以字节为单位
    • 这也不完全是您所做的,您使用的是req.Header.Set("Host", "www.domain.com:80"),它不会更改主机。它不起作用,而这个答案使用req.Host
    猜你喜欢
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-05
    • 2013-01-28
    • 1970-01-01
    • 2020-05-03
    相关资源
    最近更新 更多