Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net/http/httputil: ReverseProxy does not flush header writes #31126

Closed
PaulSD opened this issue Mar 29, 2019 · 4 comments
Closed

net/http/httputil: ReverseProxy does not flush header writes #31126

PaulSD opened this issue Mar 29, 2019 · 4 comments

Comments

@PaulSD
Copy link

PaulSD commented Mar 29, 2019

What version of Go are you using (go version)?

go version go1.12.1 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/dev/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/dev/docker-auth-proxy/go.mod"
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 -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build232253968=/tmp/go-build -gno-record-gcc-switches"

What did you do?

I have a server with a long-poll endpoint which returns response headers immediately, then delays writing anything in the response body until an event occurs. Events typically occur after a long delay.
The client waits for the response headers with a very short timeout (and throws an error if the headers aren't received), then waits for a response body with a very long timeout.
I'm trying to use httputil.ReverseProxy to write a proxy that sits between this client and server. However, the client almost always errors out because it didn't receive response headers within its timeout.
The problem is that httputil.ReverseProxy only flushes response body writes to the client. It does not flush header writes, regardless of the FlushInterval.

More specifically, ReverseProxy calls rw.WriteHeader(res.StatusCode) then waits for a read on the response body. Neither WriteHeader() nor ReverseProxy flushes rw before ReverseProxy begins waiting for a body read.

Example code: https://play.golang.org/p/SRbVbyZYsnp

What did you expect to see?

2009/11/10 23:00:00 Server wrote status
2009/11/10 23:00:00 Client got status
2009/11/10 23:00:05 Server wrote body
2009/11/10 23:00:10 Server done writing

What did you see instead?

2009/11/10 23:00:00 Server wrote status
2009/11/10 23:00:05 Server wrote body
2009/11/10 23:00:05 Client got status
2009/11/10 23:00:10 Server done writing

@liggitt
Copy link
Contributor

liggitt commented Mar 29, 2019

just opened #31125 for the same issue :)

@gopherbot
Copy link

Change https://golang.org/cl/170066 mentions this issue: net/http/httputil: make ReverseProxy flush headers on FlushInterval

@PaulSD
Copy link
Author

PaulSD commented Mar 29, 2019

Seriously? 22 minutes apart? What are the odds?
LOL

@ALTree
Copy link
Member

ALTree commented Mar 29, 2019

Closing here as a dup of #31125 then. Feel free to post your analysis on that issue, if you believe it could be helpful.

@ALTree ALTree closed this as completed Mar 29, 2019
gopherbot pushed a commit that referenced this issue Mar 29, 2019
A regression was introduced in CL 137335 (5440bfc) that caused FlushInterval
to not be honored until the first Write() call was encountered. This change
starts the flush timer as part of setting up the maxLatencyWriter.

Fixes #31125
Fixes #31126

Change-Id: I75325bd926652922219bd1457b2b00ac6d0d41b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/170066
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Mar 28, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants