[ PHPXref.com ] [ Generated: Sun Jul 20 20:17:28 2008 ] [ Simplog 0.9.3 ]
[ Index ]     [ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/ -> class.HttpClient.php (source)

   1  <?php 
   2  
   3  /* Version 0.9, 6th April 2003 - Simon Willison ( http://simon.incutio.com/ )
   4     Manual: http://scripts.incutio.com/httpclient/
   5  */
   6  
   7  class HttpClient {
   8      // Request vars
   9      var $host;
  10      var $port;
  11      var $path;
  12      var $method;
  13      var $postdata = '';
  14      var $cookies = array();
  15      var $referer;
  16      var $accept = 'text/xml,application/xml,application/xhtml+xml,text/html,text/plain,image/png,image/jpeg,image/gif,*/*';
  17      var $accept_encoding = 'gzip';
  18      var $accept_language = 'en-us';
  19      var $user_agent = 'Incutio HttpClient v0.9';
  20      // Options
  21      var $timeout = 20;
  22      var $use_gzip = true;
  23      var $persist_cookies = true;  // If true, received cookies are placed in the $this->cookies array ready for the next request
  24                                    // Note: This currently ignores the cookie path (and time) completely. Time is not important, 
  25                                    //       but path could possibly lead to security problems.
  26      var $persist_referers = true; // For each request, sends path of last request as referer
  27      var $debug = false;
  28      var $handle_redirects = true; // Auaomtically redirect if Location or URI header is found
  29      var $max_redirects = 5;
  30      var $headers_only = false;    // If true, stops receiving once headers have been read.
  31      // Basic authorization variables
  32      var $username;
  33      var $password;
  34      // Response vars
  35      var $status;
  36      var $headers = array();
  37      var $content = '';
  38      var $errormsg;
  39      // Tracker variables
  40      var $redirect_count = 0;
  41      var $cookie_host = '';
  42      function HttpClient($host, $port=80) {
  43          $this->host = $host;
  44          $this->port = $port;
  45      }
  46      function get($path, $data = false) {
  47          $this->path = $path;
  48          $this->method = 'GET';
  49          if ($data) {
  50              $this->path .= '?'.$this->buildQueryString($data);
  51          }
  52          return $this->doRequest();
  53      }
  54      function post($path, $data) {
  55          $this->path = $path;
  56          $this->method = 'POST';
  57          $this->postdata = $this->buildQueryString($data);
  58          return $this->doRequest();
  59      }
  60      function buildQueryString($data) {
  61          $querystring = '';
  62          if (is_array($data)) {
  63              // Change data in to postable data
  64              foreach ($data as $key => $val) {
  65                  if (is_array($val)) {
  66                      foreach ($val as $val2) {
  67                          $querystring .= urlencode($key).'='.urlencode($val2).'&';
  68                      }
  69                  } else {
  70                      $querystring .= urlencode($key).'='.urlencode($val).'&';
  71                  }
  72              }
  73              $querystring = substr($querystring, 0, -1); // Eliminate unnecessary &
  74          } else {
  75              $querystring = $data;
  76          }
  77          return $querystring;
  78      }
  79      function doRequest() {
  80          // Performs the actual HTTP request, returning true or false depending on outcome
  81          if (!$fp = @fsockopen($this->host, $this->port, $errno, $errstr, $this->timeout)) {
  82              // Set error message
  83              switch($errno) {
  84                  case -3:
  85                      $this->errormsg = 'Socket creation failed (-3)';
  86                  case -4:
  87                      $this->errormsg = 'DNS lookup failure (-4)';
  88                  case -5:
  89                      $this->errormsg = 'Connection refused or timed out (-5)';
  90                  default:
  91                      $this->errormsg = 'Connection failed ('.$errno.')';
  92                  $this->errormsg .= ' '.$errstr;
  93                  $this->debug($this->errormsg);
  94              }
  95              return false;
  96          }
  97          socket_set_timeout($fp, $this->timeout);
  98          $request = $this->buildRequest();
  99          $this->debug('Request', $request);
 100          fwrite($fp, $request);
 101          // Reset all the variables that should not persist between requests
 102          $this->headers = array();
 103          $this->content = '';
 104          $this->errormsg = '';
 105          // Set a couple of flags
 106          $inHeaders = true;
 107          $atStart = true;
 108          // Now start reading back the response
 109          while (!feof($fp)) {
 110              $line = fgets($fp, 4096);
 111              if ($atStart) {
 112                  // Deal with first line of returned data
 113                  $atStart = false;
 114                  if (!preg_match('/HTTP\/(\\d\\.\\d)\\s*(\\d+)\\s*(.*)/', $line, $m)) {
 115                      $this->errormsg = "Status code line invalid: ".htmlentities($line);
 116                      $this->debug($this->errormsg);
 117                      return false;
 118                  }
 119                  $http_version = $m[1]; // not used
 120                  $this->status = $m[2];
 121                  $status_string = $m[3]; // not used
 122                  $this->debug(trim($line));
 123                  continue;
 124              }
 125              if ($inHeaders) {
 126                  if (trim($line) == '') {
 127                      $inHeaders = false;
 128                      $this->debug('Received Headers', $this->headers);
 129                      if ($this->headers_only) {
 130                          break; // Skip the rest of the input
 131                      }
 132                      continue;
 133                  }
 134                  if (!preg_match('/([^:]+):\\s*(.*)/', $line, $m)) {
 135                      // Skip to the next header
 136                      continue;
 137                  }
 138                  $key = strtolower(trim($m[1]));
 139                  $val = trim($m[2]);
 140                  // Deal with the possibility of multiple headers of same name
 141                  if (isset($this->headers[$key])) {
 142                      if (is_array($this->headers[$key])) {
 143                          $this->headers[$key][] = $val;
 144                      } else {
 145                          $this->headers[$key] = array($this->headers[$key], $val);
 146                      }
 147                  } else {
 148                      $this->headers[$key] = $val;
 149                  }
 150                  continue;
 151              }
 152              // We're not in the headers, so append the line to the contents
 153              $this->content .= $line;
 154          }
 155          fclose($fp);
 156          // If data is compressed, uncompress it
 157          if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] == 'gzip') {
 158              $this->debug('Content is gzip encoded, unzipping it');
 159              $this->content = substr($this->content, 10); // See http://www.php.net/manual/en/function.gzencode.php
 160              $this->content = gzinflate($this->content);
 161          }
 162          // If $persist_cookies, deal with any cookies
 163          if ($this->persist_cookies && isset($this->headers['set-cookie']) && $this->host == $this->cookie_host) {
 164              $cookies = $this->headers['set-cookie'];
 165              if (!is_array($cookies)) {
 166                  $cookies = array($cookies);
 167              }
 168              foreach ($cookies as $cookie) {
 169                  if (preg_match('/([^=]+)=([^;]+);/', $cookie, $m)) {
 170                      $this->cookies[$m[1]] = $m[2];
 171                  }
 172              }
 173              // Record domain of cookies for security reasons
 174              $this->cookie_host = $this->host;
 175          }
 176          // If $persist_referers, set the referer ready for the next request
 177          if ($this->persist_referers) {
 178              $this->debug('Persisting referer: '.$this->getRequestURL());
 179              $this->referer = $this->getRequestURL();
 180          }
 181          // Finally, if handle_redirects and a redirect is sent, do that
 182          if ($this->handle_redirects) {
 183              if (++$this->redirect_count >= $this->max_redirects) {
 184                  $this->errormsg = 'Number of redirects exceeded maximum ('.$this->max_redirects.')';
 185                  $this->debug($this->errormsg);
 186                  $this->redirect_count = 0;
 187                  return false;
 188              }
 189              $location = isset($this->headers['location']) ? $this->headers['location'] : '';
 190              $uri = isset($this->headers['uri']) ? $this->headers['uri'] : '';
 191              if ($location || $uri) {
 192                  $url = parse_url($location.$uri);
 193                  // This will FAIL if redirect is to a different site
 194                  return $this->get($url['path']);
 195              }
 196          }
 197          return true;
 198      }
 199      function buildRequest() {
 200          $headers = array();
 201          $headers[] = "{$this->method} {$this->path} HTTP/1.0"; // Using 1.1 leads to all manner of problems, such as "chunked" encoding
 202          $headers[] = "Host: {$this->host}";
 203          $headers[] = "User-Agent: {$this->user_agent}";
 204          $headers[] = "Accept: {$this->accept}";
 205          if ($this->use_gzip) {
 206              $headers[] = "Accept-encoding: {$this->accept_encoding}";
 207          }
 208          $headers[] = "Accept-language: {$this->accept_language}";
 209          if ($this->referer) {
 210              $headers[] = "Referer: {$this->referer}";
 211          }
 212          // Cookies
 213          if ($this->cookies) {
 214              $cookie = 'Cookie: ';
 215              foreach ($this->cookies as $key => $value) {
 216                  $cookie .= "$key=$value; ";
 217              }
 218              $headers[] = $cookie;
 219          }
 220          // Basic authentication
 221          if ($this->username && $this->password) {
 222              $headers[] = 'Authorization: BASIC '.base64_encode($this->username.':'.$this->password);
 223          }
 224          // If this is a POST, set the content type and length
 225          if ($this->postdata) {
 226              $headers[] = 'Content-Type: application/x-www-form-urlencoded';
 227              $headers[] = 'Content-Length: '.strlen($this->postdata);
 228          }
 229          $request = implode("\r\n", $headers)."\r\n\r\n".$this->postdata;
 230          return $request;
 231      }
 232      function getStatus() {
 233          return $this->status;
 234      }
 235      function getContent() {
 236          return $this->content;
 237      }
 238      function getHeaders() {
 239          return $this->headers;
 240      }
 241      function getHeader($header) {
 242          $header = strtolower($header);
 243          if (isset($this->headers[$header])) {
 244              return $this->headers[$header];
 245          } else {
 246              return false;
 247          }
 248      }
 249      function getError() {
 250          return $this->errormsg;
 251      }
 252      function getCookies() {
 253          return $this->cookies;
 254      }
 255      function getRequestURL() {
 256          $url = 'http://'.$this->host;
 257          if ($this->port != 80) {
 258              $url .= ':'.$this->port;
 259          }            
 260          $url .= $this->path;
 261          return $url;
 262      }
 263      // Setter methods
 264      function setUserAgent($string) {
 265          $this->user_agent = $string;
 266      }
 267      function setAuthorization($username, $password) {
 268          $this->username = $username;
 269          $this->password = $password;
 270      }
 271      function setCookies($array) {
 272          $this->cookies = $array;
 273      }
 274      // Option setting methods
 275      function useGzip($boolean) {
 276          $this->use_gzip = $boolean;
 277      }
 278      function setPersistCookies($boolean) {
 279          $this->persist_cookies = $boolean;
 280      }
 281      function setPersistReferers($boolean) {
 282          $this->persist_referers = $boolean;
 283      }
 284      function setHandleRedirects($boolean) {
 285          $this->handle_redirects = $boolean;
 286      }
 287      function setMaxRedirects($num) {
 288          $this->max_redirects = $num;
 289      }
 290      function setHeadersOnly($boolean) {
 291          $this->headers_only = $boolean;
 292      }
 293      function setDebug($boolean) {
 294          $this->debug = $boolean;
 295      }
 296      // "Quick" static methods
 297      function quickGet($url) {
 298          $bits = parse_url($url);
 299          $host = $bits['host'];
 300          $port = isset($bits['port']) ? $bits['port'] : 80;
 301          $path = isset($bits['path']) ? $bits['path'] : '/';
 302          if (isset($bits['query'])) {
 303              $path .= '?'.$bits['query'];
 304          }
 305          $client = new HttpClient($host, $port);
 306          if (!$client->get($path)) {
 307              return false;
 308          } else {
 309              return $client->getContent();
 310          }
 311      }
 312      function quickPost($url, $data) {
 313          $bits = parse_url($url);
 314          $host = $bits['host'];
 315          $port = isset($bits['port']) ? $bits['port'] : 80;
 316          $path = isset($bits['path']) ? $bits['path'] : '/';
 317          $client = new HttpClient($host, $port);
 318          if (!$client->post($path, $data)) {
 319              return false;
 320          } else {
 321              return $client->getContent();
 322          }
 323      }
 324      function debug($msg, $object = false) {
 325          if ($this->debug) {
 326              print '<div style="border: 1px solid red; padding: 0.5em; margin: 0.5em;"><strong>HttpClient Debug:</strong> '.$msg;
 327              if ($object) {
 328                  ob_start();
 329                  print_r($object);
 330                  $content = htmlentities(ob_get_contents());
 331                  ob_end_clean();
 332                  print '<pre>'.$content.'</pre>';
 333              }
 334              print '</div>';
 335          }
 336      }   
 337  }
 338  
 339  ?>


[ Powered by PHPXref - Served by Debian GNU/Linux ]