Nginx – Is it possible to tell nginx over fastcgi to pass a Connection: close header through unaltered

fastcgikeep-alivenginxPHPphp-fpm

TL;DR: How can I tell nginx from my php-fpm backend to a) send a "Connection: close" header and b) to not buffer my response?

I have a set up running php-fpm behind nginx. In general, this works very well and I'm happy with it, but there are a few scripts that would very much like to send a "Connection: close" header to the client browser (one to ensure that a completely new connection reaches HAProxy), one in order to be able to stream a response to clients that can't deal with chunked transfer encoding (.NET has a bug there).

Now if I do this in PHP:

<?php
header('Connection: close');
echo "foobar";

And try with curl, I get this:

curl -I http://localhost/foo.php
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Tue, 19 Feb 2013 08:07:03 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.4.11

As you can see, the "Close" has turned into a "keep-alive". But not only that: Apparently, nginx also buffers this response and sends it out all at once (confirmed by sending a lot of data, sleeping, sending more data).

Looking at the documentation, I found out about the 'X-Accel-Buffering' header which is documented for proxying here and for fastgi here. That header looks like it's supposed to be doing exactly what I want (well. it doesn't fix the connection-header issue, but it should at least stop the buffering), but, alas, no luck

<?php
header('Connection: close');
header('X-Accel-Buffering: no');
echo "foobar";


curl -I http://localhost/foo.php
HTTP/1.1 200 OK
Server: nginx/1.1.19
Date: Tue, 19 Feb 2013 08:16:22 GMT
Content-Type: text/html
Connection: keep-alive
X-Powered-By: PHP/5.4.11

Still keep-alive and still doing the buffering. My next thought was that maybe the ubuntu default config sets the fastcgi_ignore_headers option, but, nope:

crazyhat@app99:/etc/nginx$ grep -lri 'ingore_header' *
crazyhat@app99:/etc/nginx$

So now I'm at a loss and coming here – there's nothing obvious left for me to try out.

  • OS: Ubuntu 12.04
  • Nginx: 1.1.19 (stock)
  • PHP: PHP 5.4.11 (self-compiled)
  • nginx is configured to use php-fpm running with

    upstream php-5.4 {
        server unix:///opt/php/5.4/var/fpm.socket;
    }
    

    (and 5.3, but that's not relevant to this discussion)

Best Answer

Yes, nginx have special command for it, named "fastcgi_pass_header". Try this code in location or HTTP section:

fastcgi_pass_header Connection-close;
Related Topic