Write HTTP request to web server with PHP.

I’ve recently built a proxy server that manually handles a lot of HTTP exchanges. I summarized the proxy’s read/writing to the server here. It actually is very simple: format a request in the form of an HTTP header, send the request to the server, and then read the server’s response.

// OPEN SOCKET TO SERVER
$_socket = @fsockopen($host, $port, $err_no, $err_str, 30);
 
// SET REQUEST HEADERS
$_request_headers  =  $_header_string;
 
fwrite($_socket, $_request_headers);
 
// PROCESS RESPONSE HEADERS
$_response_headers = $_response_keys = array();
$line = fgets($_socket, 8192);
while (strspn($line, "\r\n") !== strlen($line))
{
    @list($name, $value) = explode(':', $line, 2);
    $name = trim($name);
    $_response_headers[strtolower($name)][] = trim($value);
    $_response_keys[strtolower($name)] = $name;
    $line = fgets($_socket, 8192);
}
sscanf(current($_response_keys), 
    '%s %s', $_http_version, $_response_code);
 
// CHECK YOUR RESPONSE HEADERS
if (isset($_response_headers['location']))
{
    // DO SOMETHING WITH YOUR HEADER IF YOU WANT
}

You can format any $_header_string that you would like. For instance, one such header string that you could use would be a simple request to this blog, http://blog.gnucom.cc which would look something like this.

http://blog.gnucom.cc/\r\n
GET / HTTP/1.1\r\n
Host: blog.gnucom.cc\r\n
User-Agent: ThisScript\r\n Gecko/20100722 Firefox/3.6.8\r\n
Accept: text/html,application/xml;q=0.9,*/*;q=0.8\r\n
Accept-Language: en-us,en;q=0.5\r\n
Accept-Encoding: gzip,deflate\r\n
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n
Keep-Alive: 115\r\n
Connection: keep-alive\r\n

You can check any sort of header that is returned from the server. Any response will be formatted into an associative array that you can check in the same fashion as I did above for the ‘location’ header. You can check ‘set-cookie’ or ‘content-type’ or any other header possibly returned from your HTTP server.

Later on if you want to read the actual content data you can do so like this. This code will return the entire HTML response to the variable $_response_body. Do whatever you want with this response: proxify it, display it to the user, delete it or add to it.

$_response_body = '';
do
{
    $data = fgets($_socket, 8192);
    $_response_body .= $data;
}   
while (isset($data{0}));
unset($data);
fclose($_socket);

This is an extremely low level approach to handling HTTP requests. If you want to do something more complex it may be better for you to use a library like cURL. If you find problems in using this approach make sure to send me the problem and I’ll be happy to update the post.

Leave a Reply