We have a Node/express web application that serves static resources in addition to normal content via express.static() . In front of it is the nginx server, which is currently configured to gzip these static resource requests if it has a user agent .
However, although nginx does gzip as expected, it drops the Content-Length header from the origin and sets Transfer-Encoding: chunked instead. This interrupts caching on our CDN .
Below are the answers to a typical request for a static asset (in this case a JS file), from the backend node and nginx :
Request
curl -s -D - 'http://my_node_app/res/my_js.js' -H 'Accept-Encoding: gzip, deflate, sdch' -H 'Connection: keep-alive' --compressed -o /dev/null
Node response headers :
HTTP/1.1 200 OK Accept-Ranges: bytes Date: Wed, 07 Jan 2015 02:24:55 GMT Cache-Control: public, max-age=0 Last-Modified: Wed, 07 Jan 2015 01:12:05 GMT Content-Type: application/javascript Content-Length: 37386 // <
Response headers from nginx :
HTTP/1.1 200 OK Server: nginx Date: Wed, 07 Jan 2015 02:24:55 GMT Content-Type: application/javascript Transfer-Encoding: chunked // <--- The problematic header Connection: keep-alive Vary: Accept-Encoding Cache-Control: public, max-age=0 Last-Modified: Wed, 07 Jan 2015 01:12:05 GMT Content-Encoding: gzip
Our current nginx configuration for static location assets is as follows:
nginx config :
# cache file paths that start with /res/ location /res/ { limit_except GET HEAD { }
As you can see from the above configuration, although we explicitly set chunked_transfer_encoding off for paths such as in nginx docs, we have proxy_buffering on and a large enough proxy_buffers size , the response is still blocked.
What are we missing here?
- Edit 1: version information -
$ nginx -v nginx version: nginx/1.6.1 $ node -v v0.10.30
- Edit 2: nginx gzip config -
# http: