3

I am using CURL to test HEAD requests to my nginx server. The file being served is a simple PHP file.

If I use GET:

$ curl -XGET http://test.com/phpinfo.php -I
HTTP/1.1 200 OK
Date: Tue, 09 Apr 2013 00:35:35 GMT
Content-Type: text/html
Connection: keep-alive
Content-Length: 72080

However, if I use HEAD:

$ curl -XHEAD http://test.com/phpinfo.php -I
HTTP/1.1 200 OK
Date: Tue, 09 Apr 2013 00:37:00 GMT
Content-Type: text/html
Connection: keep-alive

Why is it that if the request is HEAD, nginx omits the Content-Length header? The php script is very simple and is not responding to HEAD in any special way.

Is there any option I can turn on in nginx, so that it will send the Content-Length for HEAD as well?

Relevant nginx info:

nginx version: nginx/1.2.8
built by gcc 4.7.2 (Ubuntu/Linaro 4.7.2-2ubuntu1) 
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.2.8 --with-http_ssl_module --with-http_realip_module --with-http_gzip_static_module --with-pcre --conf-path=/etc/nginx/nginx.conf --add-module=../headers-more-nginx-module-0.19rc1

Configuration:

user  www-user;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include mime.types;
    default_type  application/octet-stream;
    client_max_body_size 10M;

    sendfile        on;
    keepalive_timeout  65;

    more_clear_headers "Server";

    gzip  on;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/javascript text/xml application/xml application/rss+xml application/atom+xml application/rdf+xml;

    server {
        server_name test.com;
        root   /www;
        index index.php index.html index.htm;

        listen       80  default_server;

        rewrite ^/(.*)/$ /$1 permanent; #remove trailing slash

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        include      general/*.conf;

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        location ~ \.php$ {

    fastcgi_intercept_errors on;

    fastcgi_pass   unix:/run/php/php-fpm.sock;

    fastcgi_index index.php;

    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

    include        fastcgi_params;

        }
    }
}
F21
  • 706
  • 3
  • 11
  • 20

1 Answers1

2

One reason that nginx probably doesn't include the Content-Length response header for an HTTP HEAD request is that, by definition, the response to a HEAD request must not contain a message body in the response (see RFC 2616 for more details).

Now, an HTTP server could send Content-Length: 0 for responses to HEAD requests, but that's additional information over the wire that is not necessarily needed. I suspect, then, that nginx is simply omitting an otherwise redundant response header by not including the Content-Length header in the response to your HEAD requests.

Hope this helps!

Castaglia
  • 3,349
  • 3
  • 21
  • 42
  • 1
    no, this (AFAICT) is a (somewhat) violation of spec. quoting from RFC 2616: "The metainformation contained in the HTTP headers in response to a HEAD request SHOULD be identical to the information sent in response to a GET request." that metainformation includes `Content-Length`. – strugee May 19 '16 at 21:14
  • note that the spec also implies that it might be a good idea to send `Content-Lengh`: "If the new field values indicate that the cached entity differs from the current entity (as would be indicated by a change in Content-Length, Content-MD5, ETag or Last-Modified), then the cache MUST treat the cache entry as stale." – strugee May 19 '16 at 21:15