ProxyPass changes 304 status to 200 and adds content-type

apache-2.4mod-proxyPROXYproxypassreverse-proxy

The probelm

I am running a node server (sqlpad) through an Apache2 reverse proxy.

On some requests, the node server returns a 304 status code with no Content-Type when accessed directly. However, when accessed via the reverse proxy, the status code is changed to 200 and the Content-Type is added with a value of text/html. The addition of the Content-Type is causing the app to not load JS and CSS because X-Content-Type-Options: nosniff is in the header.

I really do not want to make changes to the node server since it is not my project. I would like to fix this with the reverse proxy configuration.

How can I configure Apache2 ProxyPass to forward the original 304 response, or at the very least, to not fill in the missing Content-Type with the default?

Here are my specifics:

Configuration

# /etc/apache2/sites-enabled/xxxx.conf
...
<Location "/sqlpad">
  ProxyPass http://x.x.x.x:xxxx # IP address of Node server
  ProxyPassReverse http://x.x.x.x:xxxx # IP address of Node server
</Location>

Headers

Original request/response (no proxy):

Request Url: http://xxxx/sqlpad/static/js/main.266789c5.js
Request Method: Get
Status: 304 Not Modified

Response Headers:

HTTP/1.1 304 Not Modified
X-DNS-Prefetch-Control: off
Strict-Transport-Security: max-age=15552000; includeSubDomains
X-Download-Options: noopen
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: same-origin
Accept-Ranges: bytes
Cache-Control: public, max-age=0
Last-Modified: Sat, 26 Oct 1985 08:15:00 GMT
ETag: W/"1d86fc-7438674ba0"
Date: Wed, 13 Jun 2018 15:04:20 GMT
Connection: keep-alive

Request Headers:

GET /sqlpad/static/js/main.266789c5.js HTTP/1.1
Host: xxxx
Connection: keep-alive
If-None-Match: W/"1d86fc-7438674ba0"
If-Modified-Since: Sat, 26 Oct 1985 08:15:00 GMT
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: */*
Referer: http://localhost:56173/sqlpad/signin
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

Proxied request/response:

Request Url: http://xxxx/sqlpad/static/js/main.266789c5.js
Request Method: Get
Status: 200 OK

Response Headers:

Connection: Keep-Alive
Content-Encoding: gzip
Content-Length: 496
Content-Type: text/html; charset=utf-8
Date: Wed, 13 Jun 2018 15:18:29 GMT
ETag: W/"320-Lp3a/E+wIigPW+CnI/Elyd7OYoA-gzip"
Keep-Alive: timeout=5, max=98
Referrer-Policy: same-origin
Server: Apache/2.4.33 (Ubuntu)
Strict-Transport-Security: max-age=15552000; includeSubDomains
Vary: Accept-Encoding
X-Content-Type-Options: nosniff
X-DNS-Prefetch-Control: off
X-Download-Options: noopen
X-XSS-Protection: 1; mode=block

Request Headers:

GET /sqlpad/static/js/main.266789c5.js HTTP/1.1
Host: xxxx
Connection: keep-alive
If-None-Match: W/"320-Lp3a/E+wIigPW+CnI/Elyd7OYoA-gzip"
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36
Accept: */*
Referer: http://xxxx/sqlpad
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cookie: __zlcmid=xxxx; PHPSESSID=xxxx

I am using Apache/2.4.33 on Ubuntu 16.04.4

Best Answer

With response status 304(not modified) no content is sent to HTTP client. Instead content from the client cache is used. Hence there is no question of changing its Content-type. Apache HTTPD server does forward 304 response from the original server as it is with default configuration. I have some nodejs applications behind Apache HTTP proxy and I counted the number of 200 and 304 responses per page refresh using proxy and direct application access. They are same. So I strongly suspect that reason behind the issue you are facing is not about response code but something else.

Related Topic