go net/http: redirect with 308 rather than 301

omqzjyyz  于 4个月前  发布在  Go
关注(0)|答案(5)|浏览(40)

你正在使用的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包在处理复杂实际场景(如代理服务器实现)中的可用性和健壮性。
我期待你的反馈,并随时准备提供进一步的详细信息或澄清。

jtw3ybtb

jtw3ybtb1#

我认为网络/HTTP服务器不会这样做。

ukxgm1gy

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).Handlerhere中的路径清理会涉及到这一点。如果路径不干净,它将隐式地使用代码301重定向,而不是保留方法的等效代码308。
但这让我想问:ServeMux.Handler是否应该无条件地改为使用代码308而不是301?
(注意@neild)

pnwntuvh

pnwntuvh3#

ServeMux.Handler更改为使用308而不是301对我来说似乎是合理的。

ctehm74n

ctehm74n4#

我猜308状态码的注意事项是(根据https://www.rfc-editor.org/rfc/rfc7538#section-4)自2014年6月以来,该状态码仅被定义过,因此一些非常旧的HTTP客户端可能仍然无法理解它。
然而,尽管如此,我认为通过适当的GODEBUG设置恢复到301,308似乎更符合语义,而且9年的时间对于客户端来说已经足够长了,以便他们能够建立支持...

rfbsl7qr

rfbsl7qr5#

这听起来是一个合理的网络/http更改,因此将其从提案流程中移除。如果您不同意,请发表评论。

相关问题