fasthttp icon indicating copy to clipboard operation
fasthttp copied to clipboard

ErrBodyTooLarge response sometimes does not reach client

Open xtrafrancyz opened this issue 3 years ago • 7 comments

If the request body is larger than MaxRequestBodySize, the server sometimes closes the connection before the client receives a response. Related: https://github.com/gofiber/fiber/issues/1940

The error rate is different depending on client:

  • Google Chrome always got net::ERR_CONNECTION_ABORTED
  • Insomnia (Postman alternative) got Recv failure: Connection was reset in 9 requests of 10
  • Curl got Recv failure: Connection was reset in 1 of 30 requests
  • Go net/http got wsasend: An existing connection was forcibly closed by the remote host. but rarely

In the test below, I got ~30 errors out of 1000 requests, which is the best I can do with Go.

func TestFasthttp(t *testing.T) {
	s := fasthttp.Server{
		Logger:             log.New(io.Discard, "", 0),
		MaxRequestBodySize: 4 * 1024 * 1024,
		Handler: func(ctx *fasthttp.RequestCtx) {
			ctx.WriteString("never happens")
		},
		ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) {
			ctx.WriteString("expected response")
		},
	}
	go s.ListenAndServe("127.0.0.1:10992")

	data := bytes.Repeat([]byte{1}, 50*1024*1024)

	for i := 0; i < 1000; i++ {
		r, err := http.Post("http://127.0.0.1:10992", "", bytes.NewBuffer(data))
		if err != nil {
			t.Error(err)
			continue
		}
		r.Body.Close()
	}
}

xtrafrancyz avatar Jul 24 '22 18:07 xtrafrancyz

The problem is that after MaxRequestBodySize bytes have been received a response is written to the socket and the socket is closed. This makes future writes to the socket fail. So net/http does receive the response, but it ignores it and returns a write error because it wasn't done writing the body yet.

The only way in fasthttp to fix this would be to read (and discard) the whole body, and this is exactly what we want to prevent. Otherwise you could still ddoss fasthttp servers.

erikdubbelboer avatar Jul 30 '22 09:07 erikdubbelboer

I have the same problem with GoFiber and Flutter, when I set BodyLimit to 8 MB: https://github.com/cfug/dio/issues/1776

michaldev avatar Mar 30 '23 09:03 michaldev

As described above I'm afraid this will not be fixed as that's not what fasthttp is for.

erikdubbelboer avatar Mar 30 '23 22:03 erikdubbelboer

Then how can I use gofiber for my use case? I have to send to server 6-8mb file.

michaldev avatar Apr 27 '23 19:04 michaldev

Just set MaxRequestBodySize big enough to always fit the body.

erikdubbelboer avatar Apr 27 '23 20:04 erikdubbelboer

It doesn't work. I set like this: MaxRequestBodySize: 8 * 1024 * 1024,

Upload size is 6mb.

I have 504 error

michaldev avatar Apr 27 '23 20:04 michaldev

504 is not something fasthttp returns.

erikdubbelboer avatar Apr 27 '23 20:04 erikdubbelboer