Nginx – chunked response in nginx not working

nginx

I ran into this post which shows my problem EXACTLY

http://nginx.org/en/docs/faq/chunked_encoding_from_backend.html

BUT browsers are using http 1.1 these days so I really don't understand. Our backend is the playframework and I don't mind fixing it but I don't really understand what is not working ESPECIALLY since firefox, safari, chrome ALL download the response just fine with no problems. ONLY when we stick NGINX in the middle do things break and we end up with extra data in our json responses.

Any idea how to fix this? as the doc above just seems wrong since we are now on later versions of http PLUS the browsers seem to work just fine.

thanks,
Dean

Best Answer

When your setup looks like browser -> nginx -> backend, it more or less irrelevant what browser is able to handle when we are talking about connection between nginx and backend.

The protocol nginx uses to talk to backends by default is HTTP/1.0, and use of chunked encoding is explicitly forbidden by RFC 2616:

A server MUST NOT send transfer-codings to an HTTP/1.0 client.

If your backend returns chunked responses to HTTP/1.0 requests - it does wrong thing and needs fixing, regardless of the fact whether you see the problem in a browser or not. Common result is that chunk-size strings (hex numbers like 47 in the FAQ) are interpreted as a part of response body by various HTTP/1.0 clients.

In case of (old versions of) nginx what used to happen is that while passing data to a browser (which talks HTTP/1.1 and hence undersand chunked) nginx added it's own chunked encoding on top of incorrect body with chunk-size strings embedded. As a result browsers used to see the response body in a way nginx did.

From the above it should be clear enough that there is only one correct way to solve the problem - fix the backend. On the other hand, with newer nginx versions (1.1.4+) you shouldn't see the problem as outlined in the FAQ. If you see - this means that either your assumption about nginx version used is wrong, or you aren't using proxy_pass (but some other backend module?), or you have more than one problem. Using nginx debug log might help to find out what's going on here. Or you may start with fixing the backend (which is right thing to do anyway).

Related Topic