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 should use ErrAbortHandler on read error while copying body #23643

Closed
jameshartig opened this issue Jan 31, 2018 · 6 comments
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@jameshartig
Copy link
Contributor

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

1.9.2

Does this issue reproduce with the latest release?

Yes, additionally, looking at the code, it doesn't seem to be different in master.

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

OS independent (tested on Windows/Linux)

What did you do?

https://play.golang.org/p/dK-zOdvklm1

If there's an error reading the body of a request, the ReverseProxy returns 200. The above script uses http.MaxBytesReader to cause an error reading the body and then prints the status code returned by the proxy.

What did you expect to see?

I expect the proxy to return a 502 bad gateway error instead of 200.

It looks like the problem is that *ReverseProxy.copyResponse doesn't return the error from *ReverseProxy.copyBuffer. An error channel, or similar, will need to be used for the FlushInterval case, but I'd expect the error to make it back into ServeHTTP. However, since the headers are already written before the body is read, that would need to be changed.

What did you see instead?

If you run the go playground above you get:

2009/11/10 23:00:00 httputil: ReverseProxy read error during body copy: http: request body too large
200
@bradfitz
Copy link
Contributor

ReverseProxy is streaming. It doesn't slurp up the entire response from the backend before replying to the client.

So if the backend writes some bytes (which involves writing headers, triggering an implicit 200 OK if the backend is in Go), then the ReverseProxy will also copy that 200 and then begin copying (reading from backend, writing to client) the body.

So if the read error occurs after the header's been sent, the header's already been sent.

The best we can do is terminate the connection so the client knows there's an error (stream error in HTTP/2, unexpected EOF from Content-Length mismatch or premature chunking EOF without the zero chunk EOF)

@bradfitz
Copy link
Contributor

But I see we could do better here.

ReverseProxy should use https://golang.org/pkg/net/http/#ErrAbortHandler in copyResponse if copyBuffer returns an error.

That doesn't exactly address your issue, but it's the closest we can do without buffering everything, which I don't think we want to introduce as an option.

@bradfitz bradfitz changed the title net/http/httputil: ReverseProxy returns 200 despite error reading upstream body net/http/httputil: ReverseProxy should use ErrAbortHandler on read error while copying body Jan 31, 2018
@bradfitz bradfitz added help wanted NeedsFix The path to resolution is known, but the work has not been done. labels Jan 31, 2018
@bradfitz bradfitz added this to the Go1.11 milestone Jan 31, 2018
@jameshartig
Copy link
Contributor Author

So copyResponse should panic with the ErrAbortHandler? I can make a PR with that.

@bradfitz
Copy link
Contributor

bradfitz commented Feb 1, 2018

Yup.

@gopherbot
Copy link

Change https://golang.org/cl/91675 mentions this issue: net/http/httputil: ReverseProxy should panic on error while copying body

@gopherbot
Copy link

Change https://golang.org/cl/122819 mentions this issue: net/http/httputil: don't panic in ReverseProxy unless running under a Server

gopherbot pushed a commit that referenced this issue Jul 9, 2018
… Server

Prior to the fix to #23643, the ReverseProxy didn't panic with
ErrAbortHandler when the copy to a client failed.

During Go 1.11 beta testing, we found plenty of code using
ReverseProxy in tests that were unprepared for a panic.

Change the behavior to only panic when running under the http.Server
that'll handle the panic.

Updates #23643

Change-Id: Ic1fa8405fd54c858ce8c797cec79d006833a9f7d
Reviewed-on: https://go-review.googlesource.com/122819
Reviewed-by: Ian Lance Taylor <iant@golang.org>
@golang golang locked and limited conversation to collaborators Jul 9, 2019
mjudeikis added a commit to faroshq/faros that referenced this issue Sep 6, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge help wanted NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

3 participants