6

Setting up the rewriting rules for the request proved to be quite easy in Nginx. For the response, not so much (at least, not for me). I want to strip the Content-Type header from the response if the Content-Length header of the response isn't set. I have the NginxHttpHeadersMoreModule installed, so that should allow me to remove the header, but I can't seem to find a way to check for the existence of the Content-Length header of the response using a rule in Nginx's configuration. Any suggestions on how to do this would be most appreciated!

M. Schmidt
  • 193
  • 14
Victor Welling
  • 163
  • 1
  • 1
  • 5
  • Someone did warn you that this is generally a bad idea, right? Omitting `Content-Type` in the HTTP response basically gives the recipient [carte blanche to do whatever it wants](http://www.w3.org/Protocols/rfc2616/rfc2616-sec7.html#sec7.2.1), and you may not be able to predict that behavior. – Michael Hampton Aug 27 '12 at 08:48

4 Answers4

1

I guess you want something like the following in a location block:

if ($sent_http_content_length ~ '') {
    more_clear_headers Content-Type
    ...
}

See $sent_http_name

(Disclaimer: I haven't tried this; I just dug through the docs because I found the question interesting. This may or may not work)

nickgrim
  • 4,466
  • 1
  • 19
  • 28
  • `if` only applies to incoming client requests, you can't use upstream response headers in conditions because the response hasn't been received yet. – Martijn Pieters Oct 12 '21 at 12:06
1

Looks like someone asked this on Stack Overflow, and there is a variable for each sent header called $sent_http_my_custom_header.

See https://web.archive.org/web/20140606142058/http://wiki.nginx.org/HttpCoreModule#.24sent_http_HEADER for the details.

Reference: https://stackoverflow.com/questions/12431496/nginx-read-custom-header-from-upstream-server

bishop
  • 1,086
  • 10
  • 16
Dave
  • 126
  • 3
0

There is a variable $content_length that according the documentation is equal to line Content-Length header of request. You probably can do

if ($content_length = 0) {
    do stuff with header
}

I am not sure what value $content_length will assume, or even if it will exist if the header is absent, but you may use that as a starting point to the solution.

M. Schmidt
  • 193
  • 14
coredump
  • 12,713
  • 2
  • 36
  • 56
  • This variable contains the Content-Length of the request, not the response. So unfortunately, it doesn't really help me. – Victor Welling Jul 30 '10 at 14:42
  • Oh you right... :\ – coredump Jul 30 '10 at 16:38
  • Right now, documentation link to wiki returns 404, good urls don't change they say :( Also note that nginx says that [if is evil](https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/) you have been warned ;) – GabLeRoux Apr 14 '17 at 14:54
0

Well checking for the nonexistence of something is always a problem... but....

I generally telnet to the port nginx is listening on and make a hand crafted http repsonse:

telnet www.stackoverflow.com 80
Trying 69.59.196.211...
Connected to stackoverflow.com.
Escape character is '^]'.
GET /index.html HTTP/1.1
host: www.stackoverflow.com

HTTP/1.1 301 Moved Permanently
Server: nginx
Date: Fri, 30 Jul 2010 14:31:02 GMT
Content-Type: text/html; charset=UTF-8
Connection: keep-alive
Location: http://stackoverflow.com/index.html
Content-Length: 158

<head><title>Document Moved</title></head>
<body><h1>Object Moved</h1>This document may be found <a HREF="http://stackoverflow.com/index.html">here</a></body>

You can also use dump header options to curl or wget. For example wget supports:

   -S
   --server-response
       Print the headers sent by HTTP servers and responses sent by FTP
       servers.

Lastly, custom logging might let you add specific response headers, for example:

log_format up_head '$remote_addr - $remote_user [$time_local]  $request '
  'upstream_http_content_type $upstream_http_content_type';
M. Schmidt
  • 193
  • 14
Kyle Brandt
  • 83,619
  • 74
  • 305
  • 448