Posts Tagged ‘get’

Portable PHP HTTP(S) GET Request with HTTP Basic Authentication

I’m not sure where I found this class years ago (probably the php.net comments) but it’s a handy way to make simple HTTP GET requests in PHP without having to rely on the availability of allow_url_fopen or curl extensions. It supports automatic detection of SSL/TLS and non-default port numbers based on the URL you provide.

I’ve made a minor modification to include support for HTTP Basic Authentication.

class HTTPRequest
{
    var $_fp;          // HTTP socket
    var $_url;         // full URL
    var $_host;        // HTTP host
    var $_protocol;    // protocol (HTTP/HTTPS)
    var $_uri;         // request URI
    var $_port;        // port
    var $_user;        // HTTP Basic Auth User
    var $_pass;        // HTTP Basic Auth Password
   
    // scan url
    function _scan_url()
    {
        $req = $this->_url;
       
        $pos = strpos($req, '://');
        $this->_protocol = strtolower(substr($req, 0, $pos));
       
        $req = substr($req, $pos+3);
        $pos = strpos($req, '/');
        if($pos === false)
            $pos = strlen($req);
        $host = substr($req, 0, $pos);
       
        if(strpos($host, ':') !== false)
        {
            list($this->_host, $this->_port) = explode(':', $host);
        }
        else
        {
            $this->_host = $host;
            $this->_port = ($this->_protocol == 'https') ? 443 : 80;
        }
       
        $this->_uri = substr($req, $pos);
        if($this->_uri == '')
            $this->_uri = '/';
    }
   
    // constructor
    function HTTPRequest($url, $user='', $pass='')
    {
        $this->_url = $url;
        $this->_scan_url();
        $this->_user = $user;
        $this->_pass = $pass;
    }
   
    // download URL to string
    function DownloadToString()
    {
        $crlf = "\r\n";
       
        // generate request
        $req = 'GET ' . $this->_uri . ' HTTP/1.0' . $crlf
            .    'Host: ' . $this->_host . $crlf;
            if(!empty($this->_user))
                 $req .= "Authorization: Basic " . base64_encode($this->_user . ':' . $this->_pass) . $crlf;
       $req .= $crlf;
       
        // fetch
        $this->_fp = fsockopen(($this->_protocol == 'https' ? 'ssl://' : '') . $this->_host, $this->_port);
        fwrite($this->_fp, $req);
        while(is_resource($this->_fp) && $this->_fp && !feof($this->_fp))
            $response .= fread($this->_fp, 1024);
        fclose($this->_fp);
       
        // split header and body
        $pos = strpos($response, $crlf . $crlf);
        if($pos === false)
            return($response);
        $header = substr($response, 0, $pos);
        $body = substr($response, $pos + 2 * strlen($crlf));
       
        // parse headers
        $headers = array();
        $lines = explode($crlf, $header);
        foreach($lines as $line)
            if(($pos = strpos($line, ':')) !== false)
                $headers[strtolower(trim(substr($line, 0, $pos)))] = trim(substr($line, $pos+1));
       
        // redirection?
        if(isset($headers['location']))
        {
            $http = new HTTPRequest($headers['location']);
            return($http->DownloadToString($http));
        }
        else
        {
            return($body);
        }
    }
}

Usage:

$r = new HTTPRequest($url, [username], [password]);
$response = $r->DownloadToString();

The username and password variables are optional.

Disable Form Autocomplete

Disabling a visitor’s browser’s built-in form autocomplete feature sounds like it should be a simple enough task, but like many seemingly mundane things in web design it’s a bit asinine. I have personally never had to do this until yesterday when I made an AJAX-based autocompleting search field and realized it didn’t do much good hiding behind the browser’s. It could also be useful to avert the visitor’s autocomplete where the data shouldn’t be remembered by the browser (like credit card numbers) or re-entered for verification (like e-mail addresses).

The easiest method (and the one with which I went) is to add the

autocomplete="off"

attribute to your <form> or individual <input> tags. According to Mozilla Developer Network’s How to Turn Off Form Autocompletion:

This form attribute was first introduced in Microsoft’s Internet Explorer 5. Netscape introduced it in version 6.2 — in prior versions, this attribute is ignored. The autocomplete attribute was added at the insistance of banks and card issuers, but prior to HTML5 was never part of an official standard.

In practical terms this means the autocomplete attribute is perfectly valid and there is no good reason you shouldn’t use it. In ideological terms, unless you are using it in an HTML5 document, the attribute is not valid HTML and will fail a validation test.

Sometimes it’s OK to be a rebel. Sometimes there’s a cheat code, though. It’s possible to set this attribute in JavaScript and produce flawless HTML. There is only one drawback: those with JavaScript disabled (no one) will not be affected:

var q = document.getElementById('query');
q.autocomplete = 'off';

An alternative I thought of but rejected on the grounds that it would make untidy URLs is the use of hidden <input>s and the onchange event handler. It could work well for POSTed forms, however:

<input type="hidden" name="query" id="query">
<input type="text" name="<?php echo md5(time()); ?>" onchange="document.getElementById('query').value = this.value;">

ApacheBench Shows Lots of Failed Requests due to Length

Breathe easy. Smile. You’re probably here because you’ve just run ab and got output something like:

This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking **** (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Finished 1000000 requests


Server Software:        nginx/1.2.1
Server Hostname:        ****
Server Port:            80

Document Path:          ****
Document Length:        162 bytes

Concurrency Level:      5
Time taken for tests:   9502.884921 seconds
Complete requests:      1000000
Failed requests:        697730
   (Connect: 0, Length: 697730, Exceptions: 0)
Write errors:           0
Total transferred:      279019852 bytes
Total POSTed:           247000494
HTML transferred:       158019731 bytes
Requests per second:    105.23 [#/sec] (mean)
Time per request:       47.514 [ms] (mean)
Time per request:       9.503 [ms] (mean, across all concurrent requests)
Transfer rate:          28.67 [Kbytes/sec] received
                        25.38 kb/s sent
                        54.06 kb/s total

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0   15  26.7     13    3183
Processing:     0   31  18.8     29    2319
Waiting:        0   30  15.9     28    1719
Total:          0   46  38.9     42    4333

Percentage of the requests served within a certain time (ms)
  50%     42
  66%     45
  75%     46
  80%     47
  90%     51
  95%     55
  98%    104
  99%    201
 100%   4333 (longest request)

697730 out of 1 million requests failed? No, not really.

ApacheBench expects to be run against something that produces consistent output. Chances are you’ve specified a script that has dynamic output and the length of that output has changed since the first pull.

Let’s have a nice cup of tea :)

Return top
foxpa.ws
Online Marketing Toplist
Internet
Technology Blogs - Blog Rankings

Internet Blogs - BlogCatalog Blog Directory

Technology blogs
Bad Karma Networks

Please Donate!


Made in Canada  •  There's a fox in the Gibson!  •  2010-12