7

After struggling for half a day, I finally manage to get reCAPTCHA to work by converting this function:

function _recaptcha_http_post($host, $path, $data, $port = 80) {

 $req = _recaptcha_qsencode ($data);

 $http_request  = "POST $path HTTP/1.0\r\n";
 $http_request .= "Host: $host\r\n";
 $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
 $http_request .= "Content-Length: " . strlen($req) . "\r\n";
 $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
 $http_request .= "\r\n";
 $http_request .= $req;

 $response = "";
 if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
  die ("Could not open socket");
 }

 fwrite($fs, $http_request);

 while ( !feof($fs) )
  $response .= fgets($fs, 1160); // One TCP-IP packet
 fclose($fs);
 $response = explode("\r\n\r\n", $response, 2);
 return $response;
}

to:

function _recaptcha_http_post($host, $path, $data, $port = 80) {
 $req = _recaptcha_qsencode ($data);
 $request = curl_init("http://".$host.$path);

 curl_setopt($request, CURLOPT_USERAGENT, "reCAPTCHA/PHP");
 curl_setopt($request, CURLOPT_POST, true);
 curl_setopt($request, CURLOPT_POSTFIELDS, $req);
 curl_setopt($request, CURLOPT_RETURNTRANSFER, true);

 $response = curl_exec($request);
 return $response;
}

Basically, I am interested to find out why curl works while fsockopen fails with "Could not open socket". Thanks.

In addition: Sockets Support is enabled.

Question Overflow
  • 10,925
  • 18
  • 72
  • 110

4 Answers4

1

I might be wrong, but you use $port = 80 in fsockopen() while in cURL case this variable is not used at all. I had same problem when tried to connect to SSL via port 80 instead of port 443; as far as I know, cURL checks SSL by default and connects accordingly.

Also, try running cURL with CURLOPT_VERBOSE to see what it does.

Damaged Organic
  • 8,175
  • 6
  • 58
  • 84
0

What is in $errno and $errstr inside if(false === ...)? So, what does it output if you change to

 if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
  die ("Could not open socket, error: " . $errstr);
 }
Alexey
  • 3,414
  • 7
  • 26
  • 44
  • It says "php_network_getaddresses: getaddrinfo failed: Name or service not known" – Question Overflow May 07 '12 at 01:37
  • what does say? – Alexey May 07 '12 at 10:35
  • what is in $host when you dump it before fsockopen call? What if you replace it with its IP? If you try to resolve this hostname right on the server where you're testing this code, will it do that? Just try to ping $host from shell there if you have access. – Alexey May 08 '12 at 06:58
  • `$host` is "www.google.com" when dumped before `fsockopen` call. If I replace it with the ip address "74.125.235.52", the error disappears, but the response I get from `fgets($fs, 1160)` is bool(false). – Question Overflow May 08 '12 at 10:06
  • if you do "ping google.com" from that server shell (do you have access to it?), does it resolve to IP or not? – Alexey May 08 '12 at 12:25
  • Yes, I did a ping using the server shell script to www.google.com and "74.125.235.52" is the resolved IP address which I used to replace `$host` for the test as described in my earlier comment. – Question Overflow May 08 '12 at 13:03
  • not sure what it can be, some people adise to restart web server and them try again, if it doesn't help, then you can try calling gethostbyname($host) in php and then use this IP. It works with google - fine, but with other multi-site hosts you may need to supply Host: domain.name header when connecting – Alexey May 08 '12 at 13:48
  • I think it has something to do with the port. If I try "www.google.com:443" it says connection reset. If I try "www.google.com:80", it redirects me to my local google domain. In `curl`, I don't need to specify the port number. Could it be that google is not using port 80 and port 443 for the connection? – Question Overflow May 08 '12 at 15:30
0

Googling for your error leads to wonder if your /etc/resolv.conf is readable by PHP. Do ls -lah /etc/resolv.conf in the bash to see if it is readable. You will get something like:

myserver:~ myname$ ls -lah /ets/resolv.conf
lrwxr-xr-x  1 root  wheel    20B 16 mrt  2011 /etc/resolv.conf
       ^ if there is an 'r' here it is readable. if you have '-' here, it is not.

If it is not readable, try doing in the bash: chmod 644 /etc/resolv.conf to make it readable.

nl-x
  • 11,762
  • 7
  • 33
  • 61
-1

Woah,

  if( false == ( $fs = @fsockopen($host, $port, $errno, $errstr, 10) ) ) {
  die ("Could not open socket");
 }

That doesn't make any sense surely. Try:

    $fs = fsockopen($host, $port, $errno, $errstr, 10); // @ ignores errors
 if(!$fs) die ("Could not open Socket");

Also Skype also blocks port 80 sometimes.

  • 2
    it does make sense. In PHP, the result of an assignment is the value being assigned. so $fs gets the return value of fsockopen, and then that value is also tested against false. This is how `$x = $y = $z = 42;` would assign 42 to all three variables at once. – Marc B Sep 18 '13 at 18:22
  • omg, now I also answered this question, but not before realizing that you bumped up this 16 months old question :) – nl-x Sep 18 '13 at 19:53