Jump to content

PHP sockets - getting 2 different responses


davidp

Recommended Posts

Wow...this is a pretty mind boggling bug I am having.

 

I am using the socket API in PHP to connect to a server called GeoNames and retrieve some information.

 

I formulate my request as such:

 

//Now we start to set up our sockets.  We will be using port 80, and we specify the host and the path we want.
$service_port = 80;
$address = gethostbyname('ws.geonames.org');

$path = '/countrycodeJSON?lat='.$lat.'&lng='.$lon;
//$path = '/findNearbyPlaceNameJSON?lat='.$lat.'&lng='.$lon;

//Create a socket for us to use
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($socket === false) {
	echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "\n";
}

//Connect to the host
$result = socket_connect($socket, $address, $service_port);
if ($result === false) {
	echo "socket_connect() failed.\nReason: ($result) " . socket_strerror(socket_last_error($socket)) . "\n";
}

//Now that we have a socket connected to the host, we need to form our HTTP request.  
$in = "GET ".$path." HTTP/1.1\r\n";
$in .= "Accept: */*\r\n";
$in .= "Host: ws.geonames.org\r\n";
$in .= "\r\n";
$out = '';

//Now we send our HTTP request to the host
socket_write($socket, $in, strlen($in));

 

It is pretty simple socket code that anybody familiar with sockets should understand.

 

Here is the fun part: when I run this same PHP script on my own computer, and then run it again on a different machine in the Computer Science labs on campus at my university, I get two different responses from the GeoNames server.

 

Let me explain how I retrieve the response.

 

I wrote this code to retrieve the response initially:

 

//Now we read a reply
while ($out = socket_read($socket, 2048)) {
	$out = trim ( $out );
	$len = strlen ( $out );
	if ( $out[$len - 1] == '0' )
		break;
}

 

Running this code on my machine, I get a response from the GeoNames server formatted like this:

 

HTTP/1.1 200 OK

Date: Tue, 22 Jan 2008 06:07:42 GMT

Server: Apache/2.0.54 (Linux/SUSE)

Cache-Control: no-cache

Vary: User-Agent

Content-Type: application/json;charset=UTF-8

Transfer-Encoding: chunked

Set-Cookie: JSESSIONID=68E951A10BA522A56C89906FBEC7DC68; Path=/

Connection: Keep-Alive

 

25

{"countryName":"","countryCode":""}

 

0

 

As you can see, there is no "Content-Length" header.  I figured out however, that the "25" contained right at the beginning of the content is actually the hexidecimal representation of the number of bytes contained in the content.  That, then, is essentially this other server's way of telling me the content length.  Then the "0" tells me when I have reached the end of the response.

 

So...that is what happens on my own computer when I run this PHP script.

 

Now, I also coded up a 2nd way of receiving the response from the GeoNames server that is much more C/C++ in style.  Here it is:

 

$bytesReceived = -1;
$httpResponse = "";
$responseMessage = "";
while ( $bytesReceived != 0 )
{
	$httpResponse = "";
	$bytesReceived = socket_recv ( $socket, $httpResponse, 2048, 0 );		
	$responseMessage .= $httpResponse;
}

 

This is how I normally handle responses using the socket API in C/C++, so I wanted to try it in PHP.  Unfortunately, when I tested this on my own machine, it entered an infinite loop.

 

Soooo....

 

I then transferred my PHP script to a machine on campus in our CS labs, and I ran it there (using method 1 of retrieving a response from the GeoNames server).  Doing this...it crashed.  Well, it didn't crash, but I simply didn't receive ANY response from the GeoNames server.  The response came back blank.  I decided to implement method 2 of retrieving a response (the C/C++ way of doing things), and I tested that way on that machine.  I got a response perfectly!  (No infinite loop occurred like had happened on my machine).  However....the response is different than the response I receive on my own machine.  Here is the response I get when I run the script on the CS lab machine:

 

HTTP/1.0 200 OK

Date: Tue, 22 Jan 2008 06:01:27 GMT

Server: Apache/2.0.54 (Linux/SUSE)

Cache-Control: no-cache

Vary: User-Agent

Content-Type: application/json;charset=UTF-8

Set-Cookie: JSESSIONID=D3608996B6BF4822F52FB1AA08E40A99; Path=/

X-Cache: MISS from firewall.cs.byu.edu

X-Cache-Lookup: MISS from firewall.cs.byu.edu:3128

Via: 1.0 firewall.cs.byu.edu:3128 (squid/2.6.STABLE6)

Proxy-Connection: close

 

{"countryName":"Kazakhstan","countryCode":"KZ"}

 

As you can see, for some reason the connection has been downgraded from HTTP/1.1 to HTTP/1.0.  Also, there is still no "Content-Length" header, and the number contained at the beginning of the content that acted as a content-length identifier does not exist anymore!  And there is no "0" to signal the end of the response like there was when I ran it on my own machine!

 

So my question is: How can the two HTTP responses be so different?  Is it a factor of the differences in my PHP code when I retrieve the responses?  Why does the C/C++ style of doing things enter an infinite loop on my own machine, but work perfectly on another machine?  And vise-versa for the first method I used of retrieving a response?  I don't understand exactly what is going wrong here.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.