Read http status code by fsockopen

1.2k views Asked by At

according to @JoyceBabu on this post Get http-statuscode without body using cURL? it should be possible to get the http status code of a URL with fsockopen.

So I took the code from @JoyceBabu which works:

    <?php
$fp = fsockopen("www.google.com", 80, $errno, $errstr, 30);
if ($fp) {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.google.com\r\n";
    $out .= "Accept-Encoding: gzip, deflate, sdch\r\n";
    $out .= "Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n";
    $out .= "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36\r\n";
    $out .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    $tmp = explode(' ', fgets($fp, 13));
    echo $tmp[1];
    fclose($fp);
}

Then I changed the URL to read to www.raffiniert.biz/aktuell:

    <?php
$fp = fsockopen("www.raffiniert.biz", 80, $errno, $errstr, 30);
if ($fp) {
    $out = "GET / HTTP/1.1\r\n";
    $out .= "Host: www.raffiniert.biz/aktuell\r\n";
    $out .= "Accept-Encoding: gzip, deflate, sdch\r\n";
    $out .= "Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n";
    $out .= "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36\r\n";
    $out .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    $tmp = explode(' ', fgets($fp, 13));
    echo $tmp[1];
    fclose($fp);
}

which returns http 400 - this is not correct.

Another example: www.raffiniert.biz/kunden returns 301. This should be 403.

Any ideas what I'm doing wrong?

Thanks Raphael

2

There are 2 answers

2
outlyer On

This line

$out .= "Host: www.raffiniert.biz/aktuell\r\n";

is the problem.

In an HTTP GET, the Host header is just that, the host (domain name), and the path within the host is provided in the GET line. You should write it like this instead:

$out = "GET /aktuell HTTP/1.1\r\n";
$out .= "Host: www.raffiniert.biz\r\n";

About the updated information:

Another example: www.raffiniert.biz/kunden returns 301. This should be 403.

www.raffiniert.biz/kunden gives a 301, which redirects to www.raffiniert.biz/kunden/ (with a trailing slash), which gives the 403. A browser will do that redirection automatically (i.e. it will send two consecutive requests), and hide the 301.

If you request woth "GET /kunden/ HTTP/1.1\r\n" you'll get that 403 directly.

3
Demodave On

Below will give you an return of 200

I've updated the 4'th and 5'th line requesting the get of /aktuell

<?php
$fp = fsockopen("www.raffiniert.biz", 80, $errno, $errstr, 30);
if ($fp) {
    $out = "GET /aktuell HTTP/1.1\r\n";
    $out .= "Host: www.raffiniert.biz\r\n";
    $out .= "Accept-Encoding: gzip, deflate, sdch\r\n";
    $out .= "Accept-Language: en-GB,en-US;q=0.8,en;q=0.6\r\n";
    $out .= "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36\r\n";
    $out .= "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\r\n";
    $out .= "Connection: Close\r\n\r\n";
    fwrite($fp, $out);
    $tmp = explode(' ', fgets($fp, 13));
    echo $tmp[1];
    fclose($fp);
}
?>