4

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)

pilif
  • 638
  • 9
  • 11

2 Answers2

1

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

fastcgi_pass_header Connection-close;
Paul Rudnitskiy
  • 399
  • 2
  • 4
  • 1
    testing this with both "fastcgi_pass_header Connection-close;" and "fastcgi_pass_header Connection;" (which seems more correct) I'm still seeing the exact same behavior: It both buffers and keeps the keep-alive header. (I deleted my previous comment which said it the buffering problem was solved. it wasn't, I just misinterpreted data) – pilif Feb 19 '13 at 09:44
0

You mentioned HAProxy. Have tried using the option httpclose or option forceclose on the HAProxy side?

chrskly
  • 1,539
  • 11
  • 16
  • The setup is nginx (ssl termination, geoip lookup) -> haproxy -> nginx (fastcgi, static files). haproxy is actually configures with httpclose and forceclose, but that still leaves the problem of the frontend nginx. I'll have to solve this through the whole chain. – pilif Feb 19 '13 at 12:17