I'm using a socket connection in PHP to post data to an Apache webserver. I'm a bit new to this technique, and I am not sure how to isolate the headers from the body of the response.
Sending Code:
<?php
// collect data to post
$postdata = array(
'hello' => 'world'
);
$postdata = http_build_query($postdata);
// open socket, send request
$fp = fsockopen('127.0.0.1', 80);
fwrite($fp, "POST /server.php HTTP/1.1\r\n");
fwrite($fp, "Host: fm1\r\n");
fwrite($fp, "Content-Type: application/x-www-form-urlencoded\r\n");
fwrite($fp, "Content-Length: ".strlen($postdata)."\r\n");
fwrite($fp, "Connection: close\r\n");
fwrite($fp, "\r\n");
fwrite($fp, $postdata);
// go through result
$result = "";
while(!feof($fp)){
$result .= fgets($fp);
}
// close
fclose($fp);
// display result
echo $result;
?>
Server Code:
Hello this is server. You posted:
<pre>
<?php print_r($_POST); ?>
</pre>
When posting to one server, I get:
HTTP/1.1 200 OK
Date: Fri, 06 Jan 2012 09:55:27 GMT
Server: Apache/2.2.15 (Win32) mod_ssl/2.2.15 OpenSSL/0.9.8m PHP/5.3.2
X-Powered-By: PHP/5.3.2
Content-Length: 79
Connection: close
Content-Type: text/html
Hello this is server. You posted:
<pre>
Array
(
[hello] => world
)
</pre>
As expected. I want to strip off the headers though, and just read the body from "Hello this is server....." onwards. How can i reliably detect the end of the headers and read the body into a variable?
Also, another server I've tested on replies with this:
HTTP/1.1 200 OK
Date: Fri, 06 Jan 2012 10:02:04 GMT
Server: Apache/2
X-Powered-By: PHP/5.2.17
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html
4d
Hello this is server. You posted:
<pre>
Array
(
[hello] => world
)
</pre>
0
What are the "4d" and "0" around the body text??
Thanks!
PS before someone says use CURL, I can't unfortunately :-(
You can separate the header from the the body by splitting up on a double linebreak. It should be
<CRLF><CRLF>
so this would normally work:More reliably you should use a regex to catch linebreak variations (super unlikely to ever happen):
The thing with the
4d
and0
is called the chunked encoding. (It's hex-numbers separated with another linebreak, and inidicate the length of the following raw content block).To clear that up you have to look at the headers first, and see if there is an according
Transfer-Encoding:
entry. This is were it gets complicated, and advisable to use one of the myriad of existing HTTP userland processing classes. PEAR has one.Headers should end with
"\r\n\r\n"
(two times). These 4d and 0 are possibly part of your php response (they are not part of the headers).In most cases Mario's answer should work but I have just tried to apply this method to response from Couch DB and there are some cases when it does not work.
If response does not contain any documents then Couch DB put "\r\n\r\n" inside response body trying to keep results well-formed and in this case it is not enough to just split response by "\r\n\r\n" because you can accidentally cut end part of the body.
Following parsing seems to be more reliable for Couch DB :