I’m seeing a strange problem with nginx (1.5.2 on Windows) and PHP
(5.4.8 on Windows).
Whenever I make a cURL request with PHP’s curl_exec() function to a
secure URL (https protocol), and I disable peer verification, like this
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
nginx responds with a “504 Gateway Time-out”.
If I set CURLOPT_SSL_VERIFYPEER to TRUE, nginx responds with a “200 OK”,
although curl_exec() returns false, which is expected due to the
verification failure (I’m using a self-signed certificate in nginx).
I have tried executing the same script under Apache and it functions as
expected with peer verification disabled.
On Fri, Aug 23, 2013 at 12:46:44PM -0400, Ben J. wrote:
nginx responds with a “504 Gateway Time-out”.
If I set CURLOPT_SSL_VERIFYPEER to TRUE, nginx responds with a “200 OK”,
although curl_exec() returns false, which is expected due to the
verification failure (I’m using a self-signed certificate in nginx).
I have tried executing the same script under Apache and it functions as
expected with peer verification disabled.
What URL is requested by your script? Symptoms described suggest
you are requesting some php script from the same server, and 504
is likely due to only one php backend process.
secure URL (https protocol), and I disable peer verification, like this
expected with peer verification disabled.
What URL is requested by your script? Symptoms described suggest
you are requesting some php script from the same server, and 504
is likely due to only one php backend process.
Thank you for the quick reply, Maxim! I appreciate it.
You are exactly right; my script requests another URL on the same server
(which happens to be localhost in this case).
Just so I understand the problem, are you saying that the script that
contains the cURL call (via PHP’s curl_exec() function) essentially
ties-up the only available PHP backend process, which causes curl_exec()
to time-out when it requests another URL on the same server?
nginx responds with a “504 Gateway Time-out”.
is likely due to only one php backend process.
to time-out when it requests another URL on the same server?
If you are using php-cgi, configuring PHP_FCGI_CHILDREN
environment variable before starting php-cgi should help.
Thank you for the suggestion, Maxim.
I set PHP_FCGI_CHILDREN to 4, 20, etc., but it doesn’t seem to make any
difference. Here is the Windows batch script that I’m using to start
php-cgi.exe (please excuse the wrapping):
@ECHO OFF
ECHO Starting PHP FastCGI…
SET PHP_FCGI_MAX_REQUESTS=0
SET PHP_FCGI_CHILDREN=4
SET PATH=“C:\Program Files\php;%PATH%”
“C:\Program Files\php\php-cgi.exe” -b 127.0.0.1:9000 -c “C:\Program
Files\php\php.ini”
I tried adding those directives to the batch script that starts
php-cgi.exe, but the problem persists.
What I find strange is that the problem occurs only when I set peer
verification to false:
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
When I set this value to true, I at least receive a response.
Maxim, you said:
“What URL is requested by your script? Symptoms described suggest
you are requesting some php script from the same server, and 504
is likely due to only one php backend process.”
If this were the root cause, wouldn’t the cURL call fail in the way way,
regardless of the CURLOPT_SSL_VERIFYPEER value? In other words, it
doesn’t seem like changing this cURL option would change the number of
backend processes required to handle the request(s). But I could be
wrong.
I’m pretty much out of ideas. Any further troubleshooting tips would be
much appreciated.
If this were the root cause, wouldn’t the cURL call fail in the way way,
regardless of the CURLOPT_SSL_VERIFYPEER value? In other words, it
doesn’t seem like changing this cURL option would change the number of
backend processes required to handle the request(s). But I could be wrong.
Yes, it there is a difference. CURLOPT_SSL_VERIFYPEER = true probably
masks
your real problem, because it fails at SSL level (due to certificate
validation failure; after all, thats why you disabled it, right?).
So the HTTP request passes only when you disable certificate validation,
which is way you see the 504 error only when its disabled. That doesn’t
mean there is a problem with curl or SSL. It means there is a problem
with your backend.
Any further troubleshooting tips would be much appreciated.
Triple check that your backend can handle multiple requests
simultanously
and that your script doesn’t somehow create a deadlook (requesting the
output of itself).
Check FCGI logs. If that doesn’t help, increment the debug levels on
nginx
and FCGI.
validation failure; after all, thats why you disabled it, right?).
That’s correct!
So the HTTP request passes only when you disable certificate validation,
which is way you see the 504 error only when its disabled. That doesn’t
mean there is a problem with curl or SSL. It means there is a problem
with your backend.
Okay; that makes sense.
Any further troubleshooting tips would be much appreciated.
Triple check that your backend can handle multiple requests simultanously
and that your script doesn’t somehow create a deadlook (requesting the
output of itself).
Is there a prescribed mechanism for the former (ensuring that the
backend can handle multiple requests simultaneously)? Or should I simply
write a script that, for example, uses a combination of “while” and
"sleep()"to force a lengthy execution time while outputting some type of
progress to indicate that each instance of the script is “alive”?
Check FCGI logs. If that doesn’t help, increment the debug levels on nginx
and FCGI.
By FCGI logs, you mean the PHP logs, correct? Unfortunately, they reveal
nothing, even at maximum verbosity.