-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: #62547
Comments
you're not reading the body Unlike many projects, the Go project does not use GitHub Issues for general discussion or asking questions. GitHub Issues are used for tracking bugs and proposals only. For questions please refer to https://github.com/golang/go/wiki/Questions |
I am reporting an BUG, this is the most simplified version, I have no right to provide you with the source code of the project. behavior does not depend on reading the body. so that the answer is that the body is too large, should the entire body of size 100500 GB be read? in addition, when using HTTP 2 this bug is not observed just repeat this test and everything will become clear if the text does not describe it clearly |
https://datatracker.ietf.org/doc/html/rfc9110#name-413-content-too-large
and with this bug there is no way to transfer any information to the client, he believes that the error is network and can repeat requests endlessly |
@libjs your handler still needs to be correct, that is handle the body data. |
no, it shouldn't process the body if it's too big, especially if it's known from the header Content-Length for example and this is not my handler, this is a test that you can easily repeat by adding anything, the result will be the same, I spent a week on this bug |
I repeat once again, to save resources, if after receiving the headers or in the process of reading the body, there is a need to respond to the client, then this is impossible without finishing reading the body, which can be very large and everything would be solved by using HTTP 2, but proxies use HTTP 1.1, it is this fact that breaks the ability to respond to the client |
in fact, this bug is a vulnerability, if you force the developer to read the entire body to be able to correctly complete the request, then it is easy to carry out a DDOS attack on such a server, sending it a body with the maximum possible body size, and this takes up at least network resources |
your client is closing the connection before the response can be written because you've filled up whatever buffers there may be. there's nothing the server can do. |
It’s not my client that does this, it’s the server that closes the connection and this happens to any client, use any browser |
Just answer, what do you need to understand the problem? I'll provide everything |
tnx, im test it. and let you know the result |
sorry, its not working package main import ( "fmt" "net/http" ) // wget -t1 -qSO - --method=PUT --body-file=video.mp4 'http://localhost:8888/' type handler struct { } func (h *handler) ServeHTTP (w http.ResponseWriter, r *http.Request) { rc := http.NewResponseController(w) log(rc.EnableFullDuplex()) go func() { ctx := r.Context() <- ctx.Done() log(ctx.Err()) }() log(r.Method + " " + r.RequestURI + " " + r.Proto) d := w.Header() d.Set("Server", "foo/1.0") if origin := r.Header.Get("Origin"); "" != origin { d.Set("Access-Control-Allow-Origin", origin) } switch r.Method { case "PUT": w.WriteHeader(http.StatusRequestEntityTooLarge) case "OPTIONS": d.Set("Access-Control-Allow-Methods", "OPTIONS, GET, HEAD, PUT, DELETE") d.Set("Access-Control-Allow-Headers", "Content-Type") d.Set("Access-Control-Allow-Max-Age", "86400") d.Set("Access-Control-Allow-Credentials", "true") w.WriteHeader(http.StatusNoContent) } log("Done") } func log (i any) { fmt.Printf("%v\n", i) } func main () { srv := &http.Server{ Addr: ":8888", Handler: &handler{}, } log(srv.ListenAndServe()) } server log nil PUT / HTTP/1.1 Done context canceled and client dont receive response |
if add at end of ServeHTTP rc.Flush() its not working too I'm ready to test everything you suggest |
it still looks like a client error: https://go.dev/play/p/NZ3b61LjNMr |
wow! good test, but it's more likely a server error fatal error: all goroutines are asleep - deadlock! goroutine 1 [IO wait]: internal/poll.runtime_pollWait(0x7f0abe264ea0, 0x72) /usr/local/go-faketime/src/runtime/netpoll.go:343 +0x85 internal/poll.(*pollDesc).wait(0xc00012c000?, 0x4?, 0x0) /usr/local/go-faketime/src/internal/poll/fd_poll_runtime.go:84 +0x27 internal/poll.(*pollDesc).waitRead(...) /usr/local/go-faketime/src/internal/poll/fd_poll_runtime.go:89 internal/poll.(*FD).Accept(0xc00012c000) /usr/local/go-faketime/src/internal/poll/fd_unix.go:611 +0x2ac net.(*netFD).accept(0xc00012c000) /usr/local/go-faketime/src/net/fd_unix.go:172 +0x29 net.(*TCPListener).accept(0xc0000680e0) /usr/local/go-faketime/src/net/tcpsock_posix.go:152 +0x1e net.(*TCPListener).Accept(0xc0000680e0) /usr/local/go-faketime/src/net/tcpsock.go:315 +0x30 net/http.(*Server).Serve(0xc000128000, {0x731c40, 0xc0000680e0}) /usr/local/go-faketime/src/net/http/server.go:3056 +0x364 net/http.(*Server).ListenAndServe(0xc000128000) /usr/local/go-faketime/src/net/http/server.go:2985 +0x71 main.main() /tmp/sandbox1756637940/prog.go:61 +0x65 you can use netclobber to make sure, and also, we won’t rewrite all browsers to create a perfect server |
that's just there's else to run in the playground |
ok, need to add wireshark log for browser request? |
just add size to body https://go.dev/play/p/T_d-FcSNk-U |
even such a server can respond to requests from any clients with any body size #!/bin/sh while true; do printf 'HTTP/1.1 413 Request Entity Too Large\r\nServer: foo/1.0\r\nContent-Length: 0\r\n\r\n' \ | nc -q-1 -vvlp 8888 | sed -n '1,9 p' done I can't help you fix this bug until you recognize it as a bug) the issue status is expected to change |
@libjs Did you manage to solve your problem? I encountered the same issue. |
Денис, в треде написал как решить, использовать HTTP/2.0. Но это не решение бага в гошке, а обход проблемы. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
server.go code
I do (file size 10MB)
server log
clent log empty and connection reset
man wget (4 = Network failure.)
ok, I do (file size 1MB)
client log now
What did you expect to see?
expected behavior, client receives response
What did you see instead?
client does not receive a response, and connection is closed
Additionally, when using encryption and HTTP 2, the error does not recur; it seems that the context is canceled due to a timeout and the client does not have time to read the response when the header Content-Length contains a sufficiently large value. And, if the request is made from the browser, the browser sends another repeat request
The text was updated successfully, but these errors were encountered: