go net/http/httputil: ReverseProxy无法正确处理连接/流重置 翻译结果:在net/http/httputil中,ReverseProxy无法正确处理连接和流的重置,

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

你正在使用的Go版本是什么( go version )?

$ go version
net/http/httputil: ReverseProxy

这个问题在最新版本的发布中是否重现?

你正在使用什么操作系统和处理器架构( go env )?
go env 输出

$ go env
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/jzhan/Library/Caches/go-build"
GOENV="/Users/jzhan/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/jzhan/gocode"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.13/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.13/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/4p/ch6dsl490v9227wwhd9rnb7w0000gn/T/go-build248622450=/tmp/go-build -gno-record-gcc-switches -fno-common"

你做了什么?
我正在尝试使用 httputil.Reverseproxy 测试HTTP转发的行为。特别是当后端服务器关闭连接(对于HTTP/1)或重置流(对于HTTP/2)时的行为。为了测试流重置行为,服务器在处理程序中使用了 panic(http.ErrAbortHandler)
为这些写了一些测试。
对于HTTP1:https://github.com/jaricftw/go-http-reverseproxy/blob/master/http1_test.go#L20,其中测试了:
1). http1客户端 -> http1服务器
2). http1客户端 -> httputil.Reverseproxy -> http1服务器
对于HTTP2:https://github.com/jaricftw/go-http-reverseproxy/blob/master/http2_test.go#L25,同样:
1). h2c客户端 -> h2c服务器
2). h2c客户端 -> httputil.Reverseproxy(带有h2c设置) -> h2c服务器

你期望看到什么?
我希望所有测试都能通过。也就是说,在流重置场景下,W/和W/O反向代理的响应应该是相同的。

你看到了什么?
在正常情况下,无论是HTTP/1还是HTTP/2,w/和w/o反向代理的测试都通过了。
然而,我发现W/和W/O反向代理在连接/流重置测试用例中有不同的响应:

对于HTTP/1:

W/O reverseproxy:

PASS: TestHTTP1/direct,_server_panic (0.00s)
        http1_test.go:62: got err: Get http://127.0.0.1:6666: EOF
        http1_test.go:63: got resp: <nil>

W/ reverseproxy:

FAIL: TestHTTP1/via_proxy,_server_panic (0.00s)
        http1_test.go:62: got err: <nil>
        http1_test.go:63: got resp: &{502 Bad Gateway 502 HTTP/1.1 1 1 map[Content-Length:[0] Date:[Thu, 19 Sep 2019 20:52:56 GMT]] {} 0 [] false false map[] 0xc0001da300 <nil>}
        require.go:248:
                Error Trace:    http1_test.go:65
                Error:          An error is expected but got nil.
                Test:           TestHTTP1/via_proxy,_server_panic

对于HTTP/2:

W/O reverseproxy:

PASS: TestHTTP2/direct,_server_panic (0.00s)
        http2_test.go:78: got err: Get http://127.0.0.1:7777: stream error: stream ID 3; INTERNAL_ERROR
        http2_test.go:79: got resp: <nil>

W/ reverseproxy:

FAIL: TestHTTP2/via_proxy,_server_panic (0.00s)
        http2_test.go:78: got err: <nil>
        http2_test.go:79: got resp: &{502 Bad Gateway 502 HTTP/2.0 2 0 map[Content-Length:[0] Date:[Thu, 19 Sep 2019 19:01:15 GMT]] 0xc00022e700 0 [] false false map[] 0xc000250800 <nil>}
        require.go:248:
                Error Trace:    http2_test.go:81
                Error:          An error is expected but got nil.
                Test:           TestHTTP2/via_proxy,_server_panic
FAIL
von4xj4u

von4xj4u1#

你好@jaricftw,

在这个场景中,来自反向代理的502似乎对我来说是合理的,但我对http/2.0不如包所有者@bradfitz熟悉。

eyh26e7m

eyh26e7m2#

@toothrot 我已经更新了这个问题,将HTTP/1也包括在内,似乎反向代理既没有处理HTTP/1连接关闭,也没有处理HTTP/2流重置——客户端将收到默认的502错误。
风险可能是代理在HTTP/1中没有关闭与客户端的连接,或者在HTTP/2中没有向客户端发送RST_STREAM?

wz1wpwve

wz1wpwve3#

你可以通过设置自己的ErrorHandler来改变ReverseProxy的默认502行为,具体策略取决于你的需求:https://golang.org/pkg/net/http/httputil/#ReverseProxy.ErrorHandler
风险在于代理在HTTP/1中没有关闭与客户端的连接,或者在HTTP/2中没有向客户端发送RST_STREAM。
抱歉,我不明白。你能重新表述一下吗?或者给我一些背景信息?我阅读了你上面的测试代码(感谢提供的很好的bug报告!),但我对这个最新的陈述/问题感到困惑。

3bygqnnd

3bygqnnd4#

风险在于代理在HTTP/1中没有关闭与客户端的连接,或者在HTTP/2中没有向客户端发送RST_STREAM?

抱歉,我不明白。您能重新表述一下吗?或者给我一些背景信息?我阅读了您上面的测试代码(感谢您提供的很好的错误报告!),但我对这个最新的陈述/问题感到困惑。

抱歉给您带来困惑。我还没有足够的测试来支持这个观点。我的意思是,代理看到的连接错误没有正确地返回给客户端,这可能会让客户端在收到常规状态码502时感到困惑。例如,客户端可能会根据响应代码/错误选择其重试机制。而且我假设从客户端的Angular 来看,client <-> proxy 连接/流仍然会被当作“已连接”,尽管proxy->server 已经关闭了?

相关问题