We have noticed that when using nginx internal 301 and 302 handling, nginx will serve a small document body with the appropriate Location: ... header.
Something along the lines of (in html): 301 redirect - nginx.
As appropriate in the above behaviour, a content-type text/html and content-length header is also sent.
We do a lot of 302 and some 301 redirects, the above behaviour is wasted bandwidth in our opinion.
Any way to disable this behaviour?
One idea that crossed our mind was to set error_page 301 302 to an empty text file. We have not tested this yet, but I am assuming even with the above, the content-type and content-length (0) headers will be sent.
So, is there a clean way to send a "body-less" 301/302 redirect with nginx?
Think very carefully about what you're asking for, and strongly consider not doing it.
RFC 2616 specifies that the entity bodies you want to remove should be present.
and...
SHOULD, in this context, is defined in RFC 2119:
Now you can do this without violating the RFC, but you should be aware of the full implications:
curl
, which is still in common use.This recommendation has been relaxed somewhat with RFC 7231, which merely says (for both 301 and 302):
Yes, you can ABSOLUTELY do it with NGINX!
Simply install an exception handler, a.k.a.
error_page
, to post-process required responses. Make sure to set it in such a way as to prevent the error page from modifying the HTTP Status Code, e.g., don't use the=
parameter (or use it to hardcode whichever code you desire).Make sure to
return
a response with a return status code that allows you to optionally set the[text]
, not theURL
.Specify
default_type
of""
, which appears to remove theContent-Type
headerHere's the full code, also at my GitHub in
StackOverflow.cnst.nginx.conf
repository:Here's the confirmation of it working properly:
I've tried it in the browsers, and it worked fine there, too.
P.S. Another option would be to modify the source code, and edit the
ngx_http_error_301_page
et al variables, but why go the hard route?! ^_^It's a bit ugly, but perhaps you could proxy 301/302 requests and use the proxy_method to change GET to HEAD requests. I haven't tested it, but head requests should only send headers without responses or (hopefully) content-* headers.
http://wiki.nginx.org/NginxHttpProxyModule#proxy_method