你正在使用的Go版本是什么(go version
)?
$ go version
go version go1.17 linux/amd64
这个问题在最新版本的发布中是否重现?
是的
你正在使用什么操作系统和处理器架构(go env
)?go env
输出
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOROOT="/root/sdk/go1.17"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/root/sdk/go1.17/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.17"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/dev/null"
CGO_CFLAGS="-I/opt/src//clidriver/include"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-L/opt/src//clidriver/lib"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build210934838=/tmp/go-build -gno-record-gcc-switches"
你做了什么?
我在Go中实现了一个HTTP代理服务器,使用了net/http包。该服务器应该处理并转发传入的请求而不修改它们。代理服务器遇到了一个特定场景,即传入的HTTP请求在其路径开头有一个双斜杠("//"),例如://PAM-OAuth/oauth2/token。
你期望看到什么?
我希望Go的net/http库能够像原样转发传入的请求,保留它们的原始形式,包括HTTP方法、带有双斜杠的路径以及所有请求参数。
你看到了什么?
我观察到的是,在代理过程中,HTTP请求的方法不经意地从POST更改为GET,请求路径从//PAM-OAuth/oauth2/token更改为/PAM-OAuth/oauth2/token(删除了双斜杠)。此外,在此过程中丢失了请求参数,导致到达最终目标服务器时出现失败的请求。
我理解net/http包可能试图通过删除双斜杠来清理请求路径。然而,在代理服务器的情况下,这种自动更改请求详细信息的举动会导致意外的后果和错误行为。
为了解决这个问题,我建议在net/http包中添加一个选项来禁用此自动清理或清理功能,尤其是在代理服务器场景中。这将确保传入的HTTP请求忠实地转发,不会对请求方法、路径或参数进行任何更改。
请考虑这个建议,因为它将显著提高Go net/http包在处理复杂实际场景(如代理服务器实现)中的可用性和健壮性。
我期待你的反馈,并随时准备提供进一步的详细信息或澄清。
5条答案
按热度按时间jtw3ybtb1#
我认为网络/HTTP服务器不会这样做。
ukxgm1gy2#
根据https://pkg.go.dev/net/http#Client.Do的描述:
“如果允许,301、302或303重定向会导致后续请求使用HTTP方法GET(如果原始请求是HEAD,则使用HEAD),没有主体。307或308重定向保留原始HTTP方法和主体,前提是Request.GetBody函数已定义。”
这也与RFC 9110中描述的行为一致;特别是在https://www.rfc-editor.org/rfc/rfc9110.html#section-15.4-3.1中的注解。
在服务器端,
(*ServeMux).Handler
here中的路径清理会涉及到这一点。如果路径不干净,它将隐式地使用代码301重定向,而不是保留方法的等效代码308。但这让我想问:
ServeMux.Handler
是否应该无条件地改为使用代码308而不是301?(注意@neild)
pnwntuvh3#
将
ServeMux.Handler
更改为使用308而不是301对我来说似乎是合理的。ctehm74n4#
我猜308状态码的注意事项是(根据https://www.rfc-editor.org/rfc/rfc7538#section-4)自2014年6月以来,该状态码仅被定义过,因此一些非常旧的HTTP客户端可能仍然无法理解它。
然而,尽管如此,我认为通过适当的GODEBUG设置恢复到301,308似乎更符合语义,而且9年的时间对于客户端来说已经足够长了,以便他们能够建立支持...
rfbsl7qr5#
这听起来是一个合理的网络/http更改,因此将其从提案流程中移除。如果您不同意,请发表评论。