Forum Moderators: coopster

Message Too Old, No Replies

Empty Response from PHP with cURL - HTTP/0.9 200 OK

         

davidjones

10:58 pm on Dec 8, 2007 (gmt 0)

10+ Year Member



Hi there,

I have a very serious problem that is causing my script to just send back a completely blank page with the HTTP/0.9 200 OK response header for no apparent reason. The code is as follows (simplified):

<?php

// Display errors
ini_set('display_errors',1);
error_reporting(E_ALL¦E_STRICT);

// Set up options
$toSet[CURLOPT_CONNECTTIMEOUT] = 20; // Time to wait for connection
$toSet[CURLOPT_TIMEOUT] = 45; // Time to wait for whole operation
$toSet[CURLOPT_RETURNTRANSFER] = true; // Return transfer instead of printing
$toSet[CURLOPT_FAILONERROR] = true;

// Forward the custom headers
if ( isset($_SERVER['HTTP_USER_AGENT']) ) $toSet[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];

// Show SSL without verifying
$toSet[CURLOPT_SSL_VERIFYPEER] = false;
$toSet[CURLOPT_SSL_VERIFYHOST] = false;

// Start curl
$curl = curl_init('http://www.facebook.com/');

// Load options
curl_setopt_array($curl, $toSet);

// Fetch page
$return = curl_exec($curl);

// Check for curl errors
if ( $error = curl_error($curl) )
echo 'ERROR: ',$error;

// Close handle
curl_close($curl);

// Print
echo $return;

?>

I've tried tweaking lots of different cURL options, searching for hours (found an occasional similar problem but never a solution or even explanation) and came up with nothing so I'm pretty stumped here. It also seems to only affect Facebook - every other site has worked out fine. The other strange thing is it seems to only affect certain configurations - my local machine has no problem with it, nor did my old VPS (the provider of which has now run off, hence no longer using it) but my current hosting acts as described, i.e. waits about 12 seconds then shows me a blank page.

It gives up at some point during the curl_exec() call and I'd be tempted to point the blame at cURL and leave it as out of my hands but it gets even stranger. In the process of debugging the script I used the CURLOPT_VERBOSE option and logged everything to a file. Upon running the script the same thing happened but then about 10 seconds after the browser stops loading/waiting for the page, my log file was filled with text that showed everything had worked fine - I was even able to record the response into the text file.

I don't really know enough about HTTP but at a guess, for some reason the server is cutting off the connection with my browser before the script finishes? I've obviously tried increasing every timeout limit value I can find but I'm not sure that's the problem - PHP would normally give an error message. I've just got nothing to work with here.

If anyone has anything to offer it would very very much appreciated. Thanks!

gergoe

1:04 am on Dec 9, 2007 (gmt 0)

10+ Year Member



Looks to be fine, probably it has something to do with the remote host or similar, although there are some minor mistakes, let's go though them:

<?php
//
// Display errors
ini_set('display_errors',1);
error_reporting(E_ALL¦E_STRICT);
//
// Set up options
$toSet[CURLOPT_CONNECTTIMEOUT] = 20; // Time to wait for connection
$toSet[CURLOPT_TIMEOUT] = 45; // Time to wait for whole operation
$toSet[CURLOPT_RETURNTRANSFER] = true; // Return transfer instead of printing
$toSet[CURLOPT_FAILONERROR] = true;
//
// Forward the custom headers
if ( isset($_SERVER['HTTP_USER_AGENT']) ) $toSet[CURLOPT_USERAGENT] = $_SERVER['HTTP_USER_AGENT'];
//
// Show SSL without verifying
$toSet[CURLOPT_SSL_VERIFYPEER] = false;
$toSet[CURLOPT_SSL_VERIFYHOST] = false;
//
// Start curl
$curl = curl_init('http://www.facebook.com/');
//
// Load options
curl_setopt_array($curl, $toSet);
//
// Fetch page
$return = curl_exec($curl);
// You will not necessarily get a string back, if the request failed for
// any reason, the return value will be the boolean false,
// you have to take special care for such a case. I'd suggest to examine
// the value of $return like this before going further in your code:
// if ($return!== false) echo $return; else echo curl_error($curl);

//
// Check for curl errors
if ( $error = curl_error($curl) )
echo 'ERROR: ',$error;

// curl_error does not return a logical value (see its documentation), but
// a string, which is empty when there was no error. Use the condition
// I described above to decide whether there is an error condition or not.

//
// Close handle
curl_close($curl);
//
// Print
echo $return;
// See my comment after curl_exec, you should make sure the $return does
// not contain a boolean false, because outputting that with echo will result
// in a null string sent to the browser.

?>

So I'd suggest you to add an extra check after the curl_exec, and make sure the return value is not false, if it's not, dump the response to the browser, if false, then use the curl_error to output the error.

This will probably not solve the problem, but at least will make your code better, and might produce some output from curl about the root cause.

davidjones

1:19 pm on Dec 9, 2007 (gmt 0)

10+ Year Member



Thanks but my actual code is a bit more complicated and very different - this is just a trimmed down version that shows the problem.

After the curl_exec() I can't output anything, even an echo "curl_exec() complete"; won't display. I can do other stuff like write to a file with the contents of the return but that only completes about 10 seconds after the browser stops loading and displays the blank page.

gergoe

12:29 am on Dec 10, 2007 (gmt 0)

10+ Year Member



Try setting CURLOPT_HTTP_VERSION to CURL_HTTP_VERSION_1_0, and while on it, it would also be interesting to see what happens if you enable headers, and disable any processing on the response (so both CURLOPT_HEADER and CURLOPT_BINARYTRANSFER set to true). But try these one by one, first force the http version to 1.0, then the other two.

By the way, what is the version of php and curl you are using?

davidjones

12:40 am on Dec 10, 2007 (gmt 0)

10+ Year Member



Thanks, good ideas. I had already tried setting HTTP version and it made no difference. I just tried with header and binary on but still no chance.

PHP Version 5.2.4
cURL libcurl/7.15.3 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.8

Thanks for your help!

gergoe

1:23 am on Dec 10, 2007 (gmt 0)

10+ Year Member



What happens if you do a flush (and ob_flush if applies) prior to the call to curl_exec?
Could you try opening stdout explicitly after curl_exec, and writing something (perhaps even the response) to it? I mean this:

... 
$h = fopen('php://output','w');
fwrite($h, 'TEST123');
...

It would also be interesting to see what the server sends back to your browser. If I remember well this version 0.9 response is the sign of a broken (or empty) http response. If you have a packet (or a http traffic) monitor at hand use that one, otherwise I'll suggest you to download Ethereal [ethereal.com].

Zbud

2:28 pm on Jan 15, 2008 (gmt 0)

10+ Year Member



Hi, I came across your post via a google search for "HTTP/0.9 200 OK". I am having the same issue, but my problem is when we have long server processes that can take anywhere from a few minutes to several hours. We have isolated the issue to where it is only happening to clients of ours who are going through a http proxy server. Have you been able to resolve this issue? Are you going through a proxy server? Thanks in advance for any help anyone can offer

irmdogg

4:42 pm on Mar 27, 2008 (gmt 0)

10+ Year Member



I came across a similar problem only not even that header was being returned. This was an issue only on GoDaddy (shared) hosting. The docs say that one need only use a proxy if cURLing across HTTPS (and we weren't), but forcing it to use the proxy seemed to help us out. I'll try to look up the outcome from a while back.