I posted this question to the NGINX mailing list a few days ago, but nobody has responded. It's quite possible that potential respondents are thinking, "This is a PHP question." And maybe it is.

I have a fairly simple PHP script that I have used in the past, under Apache, to "simulate an HTTP form POST".

For some reason, when I attempt to do the same under nginx, the browser hangs until some timeout is reached, at which point nginx returns a "504 Gateway Timeout" response to the browser.

If I enable verbose cURL output in PHP, all of the output is sent to the instance of cmd.exe (the Windows console) in which PHP's "php-cgi.exe" is running. This enables me to see that nginx is indeed handling the request. Here is the output:

* About to connect() to ben-pc port 443 (#0)
*   Trying fe80::1ddc:6806:70b6:8546...
* Connection refused
*   Trying fe80::61f9:7669:a282:252d...
* Connection refused
*   Trying 169.254.37.45...
* connected
* Connected to ben-pc (169.254.37.45) port 443 (#0)
* SSL connection using DHE-RSA-AES256-SHA
* Server certificate:
*        [redacted]
*        start date: 2013-07-05 18:17:36 GMT
*        expire date: 2014-07-05 18:17:36 GMT
*        [redacted]
*        SSL certificate verify result: self signed certificate (18), continuing anyway.
* Server auth using Basic with user 'me'
POST /myproject/trunk/public/jsapi/api-router/ HTTP/1.1
Authorization: Basic [redacted]
Host: ben-pc
Accept: */*
Content-Length: 85
Content-Type: application/x-www-form-urlencoded

* upload completely sent off: 85 out of 85 bytes
< HTTP/1.1 504 Gateway Time-out
< Server: nginx/1.5.2
< Date: Mon, 05 Aug 2013 22:28:06 GMT
< Content-Type: text/html
< Content-Length: 182
< Connection: keep-alive
<
* Connection #0 to host ben-pc left intact
* Closing connection #0

If I disable verbose cURL output (using curl_setopt($ch, CURLOPT_VERBOSE, 1)😉 no output is sent to the console, and the same timeout and 504 response occurs.

My setup is essentially the same as that described at http://wiki.nginx.org/PHPFastCGIOnWindows .

Is there a simple solution to this? I'm surprised by the dearth of search results for "nginx php-cgi curl 504", given that my stack configuration is relatively untouched.

I should mention that all other PHP behavior seems normal; the server is definitely "functional" in every other way.

I am happy to post details of my nginx installation, PHP configuration, script source code, etc. if any of it would be helpful.

Thanks for any pointers!

    13 days later

    I hate to bump this thread. I really do.

    But I'm running out of ideas. The thread on the NGINX forum remains silent, too.

    Surely, someone else has run into this scenario. A suggestion or two, even, would be most appreciated.

    Thanks in advance!

      Actually, I've not run into this. I might suspect, despite the fact that nginx has become more popular than IIS, that I've not had opportunity to use cURL against one. I generally use it only against .NET/IIS servers from what I've seen.

      Have you actually tried increasing timeouts? Both for PHP, and, if that doesn't help, for nginx...

      Maybe these will help?

      http://wiki.nginx.org/NginxHttpCoreModule#send_timeout
      http://wiki.nginx.org/HttpFastcgiModule#fastcgi_read_timeout

        Hi, dalecosp! Thank you for the reply; I really appreciate it.

        I tried increasing both send_timeout and fastcgi_read_timeout from their default values of 60s to 300s. The behavior is the same, essentially; the only difference now is that the CGI output that I pasted in my initial post hangs for 5 minutes instead of 1 before ultimately timing-out.

        I should add that I'm requesting a very simple script via cURL; in Apache, the server responds within a matter of milliseconds. So, it's not as though I'm calling a long-running script.

        Oh wait, here we go! I just started commenting-out calls to curl_setopt() and when I commented-out the following two lines, I at least got some output:

        //Turn off the server and peer verification (TrustManager Concept).
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        

        With those two lines commented-out, my script outputs "false" (I'm var_dump()-ing the result of curl_exec()), which is what I would expect if peer or host verification failed (and it seems to).

        I tried my script in Apache, with the same two lines commented-out, and the result is the same: "false".

        Here are the results from a series of tests with the various combinations of options, under each Web-server:

        Apache:

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, TRUE);
        

        Script returns expected result.

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, TRUE);
        

        Script returns "false".

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        

        Script returns "false".

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        

        Script returns expected result.

        NGINX:

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, TRUE);
        

        NGINX returns "504 Gateway Time-out".

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, TRUE);
        

        Script returns "false".

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, TRUE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        

        Script returns "false".

        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        

        NGINX returns "504 Gateway Time-out".

        According to the PHP manual ( http://php.net/manual/en/function.curl-setopt.php ), both of these options are set to their "most secure values" (my term) by default. CURLOPT_SSL_VERIFYPEER = 1 (perform the verification) and CURLOPT_SSL_VERIFYHOST = 2 (check the existence of a common name and also verify that it matches the hostname provided).

        I do realize that I am setting CURLOPT_SSL_VERIFYHOST to bool true when the value should be 1 or 2, but this doesn't seem to affect the problem behavior.

        Any thoughts on this new information?

        Thanks again!

          Write a Reply...