title: Unable to turn off chunked transfer encoding in nginx with gzip for static assets served from Node backend
body: <p>We have a <code>Node/express</code> web app that is serving static assets in addition to normal content, via <code>express.static()</code>. There is an <code>nginx</code> server in front of it that is currently configured to <code>gzip</code> these static asset requests, if the <code>user agent</code> is up for it.</p>
  
  <p>However, though <code>nginx</code> is doing the <code>gzip</code> as expected, it is dropping the <code>Content-Length</code> header from the origin, and setting <code>Transfer-Encoding: chunked</code> instead. This breaks caching on our <code>CDN</code>.</p>
  
  <p>Below are the responses for a typical static asset request (a <code>JS</code> file in this case), from the node backend, and from <code>nginx</code>:</p>
  
  <p><strong>Request</strong>:</p>
  
  <pre><code>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
  </code></pre>
  
  <p><strong>Response Headers from Node</strong>:</p>
  
  <pre><code>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   // &lt;--- The expected header
  Connection: keep-alive
  </code></pre>
  
  <p><strong>Response Headers from nginx</strong>:</p>
  
  <pre><code>HTTP/1.1 200 OK
  Server: nginx
  Date: Wed, 07 Jan 2015 02:24:55 GMT
  Content-Type: application/javascript
  Transfer-Encoding: chunked  // &lt;--- 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
  </code></pre>
  
  <p>Our current <code>nginx</code> configuration for the static assets <code>location</code> looks like below:</p>
  
  <p><strong>nginx config</strong>:</p>
  
  <pre><code># cache file paths that start with /res/
  location /res/ {
      limit_except GET HEAD { }
  
      # http://nginx.com/resources/admin-guide/caching/
      # http://nginx.org/en/docs/http/ngx_http_proxy_module.html
  
      proxy_buffers 8 128k;
      #proxy_buffer_size 256k;
      #proxy_busy_buffers_size 256k;
  
      # The cache depends on proxy buffers, and will not work if proxy_buffering is set to off.
      proxy_buffering     on;
      proxy_http_version  1.1;
      proxy_set_header  Connection "";
      proxy_connect_timeout  2s;
      proxy_read_timeout  5s;
      proxy_pass          http://node_backend;
  
      chunked_transfer_encoding off;
  
      proxy_cache         my_app;
      proxy_cache_valid   15m;
      proxy_cache_key     $uri$is_args$args;
  }
  </code></pre>
  
  <p>As can be seen from the above config, even though we've explicitly set <code>chunked_transfer_encoding</code> <code>off</code> for such paths as per the <code>nginx</code> docs, have <code>proxy_buffering</code> <code>on</code>, and have a big enough <code>proxy_buffers</code> <code>size</code>, the response is still being chunked.</p>
  
  <p>What are we missing here?</p>
  
  <p>--Edit 1: version info--</p>
  
  <pre><code>$ nginx -v
  nginx version: nginx/1.6.1
  
  $ node -v
  v0.10.30
  </code></pre>
  
  <p>--Edit 2: <code>nginx</code> gzip config--</p>
  
  <pre><code># http://nginx.org/en/docs/http/ngx_http_gzip_module.html
  gzip on;
  gzip_buffers 32 4k;
  gzip_comp_level 1;
  gzip_min_length 1000;
  #gzip_http_version 1.0;
  gzip_types application/javascript text/css
  gzip_proxied any;
  gzip_vary on;
  </code></pre>