Le mercredi 02 juillet 2014 18:56:48 Willy Tarreau a écrit : > Hi guys, > > On Wed, Jul 02, 2014 at 05:19:20PM +0200, Guillaume Castagnino wrote: > > Le mercredi 02 juillet 2014 16:53:06 Lukas Tribus a écrit : > > > Hi Guillaume, > > > > > > > I made a small quick and dirty TCP server that mimic this > > > > behaviour > > > > to use as a backend (see attached). > > > > Then I send posts like this: > > > > curl -H "Expect:" -F "file=@big-file" -v http://haproxy-ip/ > > > > > > Thanks, but it works for me (tm). In both latest (git) and 1.4.25 > > > curl> > > > sees the 413 response: > > Not here :( > > With local network, I need to use quite big uploads (I use a 50MB > > file to be sure) because haproxy may have the time to send the > > whole file before the backend closes the socket (and in this case, > > the phenomenon is of course hidden). On my test machine, haproxy > > has the time to send 170kB before being interrupted because of the > > socket closing. As you can see in the pcap file attached. > > I know what's happening, welcome to HTTP over TCP, which are not > compatible :-) > > Seriously speaking, what's happening here is that the server sends the > 413 and does not drain the incoming data, so the TCP stack sees a > close with pending input data and immediately flushes the outgoing > queue and emits a TCP reset instead of the 413 that you hoped was > pending. This TCP reset is received by haproxy which never has any > chance to get the 413. > > The only solution here is for the server to continue to read the > incoming data until the client (here haproxy) at least receives the > 413. In practice, since TCP stacks rarely offer the option to verify > the outgoing queue (at least in a portable way), servers have to > drain as much as possible before closing, hoping it will leave enough > time to the client to get the data. Many products including haproxy > do that nowadays, at least to have a chance to correctly perform > redirects on POSTs. > > I'd suggest you run an strace on haproxy and you'll see an ECONNRESET > on the recv() without ever a sign of 413. Tcpdump will happily show > you the RST from the server. That's why I was saying that HTTP is > incompatible with TCP by design. > > The fix is only on the server side unfortunately here. Note, if you > put haproxy in front of the server and use a unix socket instead of a > TCP socket to connect to the server, it should work since there's no > reset in this case on unix sockets, so haproxy will receive the 413, > will be able to deliver it to the external client over TCP and drain > as much as it can of its uploaded data. That *may* work, but it's not > guaranteed. > > Hoping this helps, > Willy
Thank you very much, I will play with strace tomorrow arround this ECONNRESET. Too bad I cannot workaround on haproxy side, it will be complicated to fix the backend :( Anyway, thanks a lot !! -- Guillaume Castagnino ca...@xwing.info / guilla...@castagnino.org