0

For a reason beyond my control (an app that cannot be modified), I need to get a server that processes HTTP requests for PHP pages over FastCGI, to honour "Connection: Keep-alive" (sent by said client) with a request also declared as "HTTP/1.0".

This works great for static content, for regular proxied content, etc. (Meaning - if you use:

curl -0v http://server/static.html

you get "Connection: close" as expected, but if you also explicitly request the connection to be kept alive, like this:

curl -H "Connection: keep-alive" -0v http://server/static.html

as long as static.html is either locally on the server, or on another server, proxied by the web server (e.g. proxy_pass in Nginx)).

However, once you add a PHP backend over FastCGI and access http://server/file.php, it seems that all responses will become "Connection: close", no matter what you try... and this behaviour appears to be shared to latest stable Nginx and Apache 2.4.

Note, however, that Apache serving PHP under mod_php does NOT exhibit this issue; I would have used that, but I really need the performance, and unfortunately this app's PHP uses non-threadsafe libs, so can't use thread-based Apache MPMs.

What I already tried in Nginx based on various docs on the Internet and didn't help:

fastcgi_keep_conn on;

(on the PHP location {} block)

    upstream fastcgi_backend {
            server 127.0.0.1:9000;
            keepalive 8;
    }

(inside the http {} block)

I sniffed the FastCGI request and saw that it is sending SERVER_PROTOCOL 1.0 over the wire, so I edited /etc/nginx/fastcgi_params, and modified:

fastcgi_param  SERVER_PROTOCOL    $server_protocol;

to:

fastcgi_param  SERVER_PROTOCOL    HTTP/1.1;

saw it updating on the sniffer, but to no avail; All requests still return as "Connection: close", no matter what.

I even tried to tinker with the Nginx source code itself (which is an acceptable solution for me if no other solution exists) on various places (without understanding it much :)) to make it "think" that the request was "1.1", but so far without luck.

Any chance anyone ever encountered this and found a solution to this issue?

Thanks!

Shimi
  • 116
  • 2
  • 1
    There is no official way to do keepalive under HTTP1.0 https://en.wikipedia.org/wiki/HTTP_persistent_connection – Tim Apr 12 '16 at 21:52
  • Yes, I am aware of that (and I even told it to the owner of the software making these requests and expecting keep-alive to work). Despite that, when FPM is not involved, and you explicitly ask for it, it just works. The question is why it doesn't when the backend is FPM. After all, since it's a proxy, the keep-alive in front of the client shouldn't (IMHO) be affected by the way the requests are processed on the backend - it should be ignorant to that. CGI itself shouldn't be the cause, because it does work with mod_php. – Shimi Apr 12 '16 at 22:03
  • Why are you trying to do this? – Michael Hampton Apr 12 '16 at 22:17
  • I've explained in the beginning of the question - I have an app that makes HTTP requests, expects them to work with keep-alive, but uses "HTTP/1.0" in the request (and issues 'Connection: keep-alive' as one of the headers). If I had the source code of the app, I would have simply changed it and recompiled it. Alas, I do not. Hence I would like to have the server support it. (apparently some proprietary servers do, and this is how they got along with this so far; but there is a need to replace the existing solution with an open-source which is better-performant...) – Shimi Apr 12 '16 at 22:31
  • You just need a HTTP server that follows the optional part of latest RFC: https://tools.ietf.org/html/rfc7230#section-6.3 – Mikko Rantalainen Feb 10 '20 at 14:33

0 Answers0