Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

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)

share|improve this question
add comment

2 Answers

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

fastcgi_pass_header Connection-close;
share|improve this answer
    
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 9:44
add comment

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

share|improve this answer
    
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
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.