[ Index ]

PHP Cross Reference of osCMax 2.0.4

title

Body

[close]

/admin/order_editor/ -> http_client.php (source)

   1  <?php
   2  /*
   3    $Id: http_client.php,v 1.1 2002/11/01 02:26:03 hpdl Exp $
   4  
   5    osCommerce, Open Source E-Commerce Solutions
   6    http://www.oscommerce.com
   7  
   8    Copyright (c) 2002 osCommerce
   9  
  10    Released under the GNU General Public License
  11  
  12    Copyright 2001 Leo West <[email protected]> Net_HTTP_Client v0.6
  13  
  14    Minimal Example:
  15  
  16    $http = new httpClient();
  17    $http->Connect("somehost", 80) or die("Connect problem");
  18    $status = $http->Get("/index.html");
  19    if ($status != 200) {
  20      die("Problem : " . $http->getStatusMessage());
  21    } else {
  22      echo $http->getBody();
  23    }
  24    $http->Disconnect();
  25  
  26    Persistent Example:
  27  
  28    $http = new httpClient("dir.yahoo.com", 80);
  29    $http->addHeader("Host", "dir.yahoo.com");
  30    $http->addHeader("Connection", "keep-alive");
  31  
  32    if ($http->Get("/Reference/Libraries/") == 200) $page1 = $http->getBody();
  33    if ($http->Get("/News_and_Media/") == 200 ) $page2 = $http->getBody();
  34    $http->disconnect();
  35  */
  36  
  37    class httpClient {
  38      var $url; // array containg server URL, similar to parseurl() returned array
  39      var $reply; // response code
  40      var $replyString; // full response
  41      var $protocolVersion = '1.1';
  42      var $requestHeaders, $requestBody;
  43      var $socket = false;
  44  // proxy stuff
  45      var $useProxy = false;
  46      var $proxyHost, $proxyPort;
  47  
  48  /**
  49   * httpClient constructor
  50   * Note: when host and port are defined, the connection is immediate
  51   * @seeAlso connect
  52   **/
  53      function httpClient($host = '', $port = '') {
  54        if (tep_not_null($host)) {
  55          $this->connect($host, $port);
  56        }
  57      }
  58  
  59  /**
  60   * turn on proxy support
  61   * @param proxyHost proxy host address eg "proxy.mycorp.com"
  62   * @param proxyPort proxy port usually 80 or 8080
  63   **/
  64      function setProxy($proxyHost, $proxyPort) {
  65        $this->useProxy = true;
  66        $this->proxyHost = $proxyHost;
  67        $this->proxyPort = $proxyPort;
  68      }
  69  
  70  /**
  71   * setProtocolVersion
  72   * define the HTTP protocol version to use
  73   * @param version string the version number with one decimal: "0.9", "1.0", "1.1"
  74   * when using 1.1, you MUST set the mandatory headers "Host"
  75   * @return boolean false if the version number is bad, true if ok
  76   **/
  77      function setProtocolVersion($version) {
  78        if ( ($version > 0) && ($version <= 1.1) ) {
  79          $this->protocolVersion = $version;
  80          return true;
  81        } else {
  82          return false;
  83        }
  84      }
  85  
  86  /**
  87   * set a username and password to access a protected resource
  88   * Only "Basic" authentication scheme is supported yet
  89   * @param username string - identifier
  90   * @param password string - clear password
  91   **/
  92      function setCredentials($username, $password) {
  93        $this->addHeader('Authorization', 'Basic ' . base64_encode($username . ':' . $password));
  94       }
  95  
  96  /**
  97   * define a set of HTTP headers to be sent to the server
  98   * header names are lowercased to avoid duplicated headers
  99   * @param headers hash array containing the headers as headerName => headerValue pairs
 100   **/
 101      function setHeaders($headers) {
 102        if (is_array($headers)) {
 103          reset($headers);
 104          while (list($name, $value) = each($headers)) {
 105            $this->requestHeaders[$name] = $value;
 106          }
 107        }
 108      }
 109  
 110  /**
 111   * addHeader
 112   * set a unique request header
 113   * @param headerName the header name
 114   * @param headerValue the header value, ( unencoded)
 115   **/
 116      function addHeader($headerName, $headerValue) {
 117        $this->requestHeaders[$headerName] = $headerValue;
 118      }
 119  
 120  /**
 121   * removeHeader
 122   * unset a request header
 123   * @param headerName the header name
 124   **/
 125      function removeHeader($headerName) {
 126        unset($this->requestHeaders[$headerName]);
 127      }
 128  
 129  /**
 130   * Connect
 131   * open the connection to the server
 132   * @param host string server address (or IP)
 133   * @param port string server listening port - defaults to 80
 134   * @return boolean false is connection failed, true otherwise
 135   **/
 136      function Connect($host, $port = '') {
 137        $this->url['scheme'] = 'http';
 138        $this->url['host'] = $host;
 139        if (tep_not_null($port)) $this->url['port'] = $port;
 140  
 141        return true;
 142      }
 143  
 144  /**
 145   * Disconnect
 146   * close the connection to the  server
 147   **/
 148      function Disconnect() {
 149        if ($this->socket) fclose($this->socket);
 150      }
 151  
 152  /**
 153   * head
 154   * issue a HEAD request
 155   * @param uri string URI of the document
 156   * @return string response status code (200 if ok)
 157   * @seeAlso getHeaders()
 158   **/
 159      function Head($uri) {
 160        $this->responseHeaders = $this->responseBody = '';
 161  
 162        $uri = $this->makeUri($uri);
 163  
 164        if ($this->sendCommand('HEAD ' . $uri . ' HTTP/' . $this->protocolVersion)) {
 165          $this->processReply();
 166        }
 167  
 168        return $this->reply;
 169      }
 170  
 171  /**
 172   * get
 173   * issue a GET http request
 174   * @param uri URI (path on server) or full URL of the document
 175   * @return string response status code (200 if ok)
 176   * @seeAlso getHeaders(), getBody()
 177   **/
 178      function Get($url) {
 179        $this->responseHeaders = $this->responseBody = '';
 180  
 181        $uri = $this->makeUri($url);
 182  
 183        if ($this->sendCommand('GET ' . $uri . ' HTTP/' . $this->protocolVersion)) {
 184          $this->processReply();
 185        }
 186  
 187        return $this->reply;
 188      }
 189  
 190  /**
 191   * Post
 192   * issue a POST http request
 193   * @param uri string URI of the document
 194   * @param query_params array parameters to send in the form "parameter name" => value
 195   * @return string response status code (200 if ok)
 196   * @example 
 197   * $params = array( "login" => "tiger", "password" => "secret" );
 198   * $http->post( "/login.php", $params );
 199   **/
 200      function Post($uri, $query_params = '') {
 201        $uri = $this->makeUri($uri);
 202  
 203        if (is_array($query_params)) {
 204          $postArray = array();
 205          reset($query_params);
 206          while (list($k, $v) = each($query_params)) {
 207            $postArray[] = urlencode($k) . '=' . urlencode($v);
 208          }
 209  
 210          $this->requestBody = implode('&', $postArray);
 211        }
 212  
 213  // set the content type for post parameters
 214        $this->addHeader('Content-Type', 'application/x-www-form-urlencoded');
 215  
 216        if ($this->sendCommand('POST ' . $uri . ' HTTP/' . $this->protocolVersion)) {
 217          $this->processReply();
 218        }
 219  
 220        $this->removeHeader('Content-Type');
 221        $this->removeHeader('Content-Length');
 222        $this->requestBody = '';
 223  
 224        return $this->reply;
 225      }
 226  
 227  /**
 228   * Put
 229   * Send a PUT request
 230   * PUT is the method to sending a file on the server. it is *not* widely supported
 231   * @param uri the location of the file on the server. dont forget the heading "/"
 232   * @param filecontent the content of the file. binary content accepted
 233   * @return string response status code 201 (Created) if ok
 234   * @see RFC2518 "HTTP Extensions for Distributed Authoring WEBDAV"
 235   **/
 236      function Put($uri, $filecontent) {
 237        $uri = $this->makeUri($uri);
 238        $this->requestBody = $filecontent;
 239  
 240        if ($this->sendCommand('PUT ' . $uri . ' HTTP/' . $this->protocolVersion)) {
 241          $this->processReply();
 242        }
 243  
 244        return $this->reply;
 245      }
 246  
 247  /**
 248   * getHeaders
 249   * return the response headers
 250   * to be called after a Get() or Head() call
 251   * @return array headers received from server in the form headername => value
 252   * @seeAlso get, head
 253   **/
 254      function getHeaders() {
 255        return $this->responseHeaders;
 256      }
 257  
 258  /**
 259   * getHeader
 260   * return the response header "headername"
 261   * @param headername the name of the header
 262   * @return header value or NULL if no such header is defined
 263   **/
 264      function getHeader($headername) {
 265        return $this->responseHeaders[$headername];
 266      }
 267  
 268  /**
 269   * getBody
 270   * return the response body
 271   * invoke it after a Get() call for instance, to retrieve the response
 272   * @return string body content
 273   * @seeAlso get, head
 274   **/
 275      function getBody() {
 276        return $this->responseBody;
 277      }
 278  
 279  /**
 280   * getStatus return the server response's status code
 281   * @return string a status code
 282   * code are divided in classes (where x is a digit)
 283   *  - 20x : request processed OK
 284   *  - 30x : document moved
 285   *  - 40x : client error ( bad url, document not found, etc...)
 286   *  - 50x : server error 
 287   * @see RFC2616 "Hypertext Transfer Protocol -- HTTP/1.1"
 288   **/
 289      function getStatus() {
 290        return $this->reply;
 291      }
 292  
 293  /** 
 294   * getStatusMessage return the full response status, of the form "CODE Message"
 295   * eg. "404 Document not found"
 296   * @return string the message 
 297   **/
 298      function getStatusMessage() {
 299        return $this->replyString;
 300      }
 301  
 302  /**
 303   * @scope only protected or private methods below
 304   **/
 305  
 306  /** 
 307   * send a request
 308   * data sent are in order
 309   * a) the command
 310   * b) the request headers if they are defined
 311   * c) the request body if defined
 312   * @return string the server repsonse status code
 313   **/
 314      function sendCommand($command) {
 315        $this->responseHeaders = array();
 316        $this->responseBody = '';
 317  
 318  // connect if necessary
 319        if ( ($this->socket == false) || (feof($this->socket)) ) {
 320          if ($this->useProxy) {
 321            $host = $this->proxyHost;
 322            $port = $this->proxyPort;
 323          } else {
 324            $host = $this->url['host'];
 325            $port = $this->url['port'];
 326          }
 327  
 328          if (!tep_not_null($port)) $port = 80;
 329  
 330          if (!$this->socket = fsockopen($host, $port, $this->reply, $this->replyString)) {
 331            return false;
 332          }
 333  
 334          if (tep_not_null($this->requestBody)) {
 335            $this->addHeader('Content-Length', strlen($this->requestBody));
 336          }
 337  
 338          $this->request = $command;
 339          $cmd = $command . "\r\n";
 340          if (is_array($this->requestHeaders)) {
 341            reset($this->requestHeaders);
 342            while (list($k, $v) = each($this->requestHeaders)) {
 343              $cmd .= $k . ': ' . $v . "\r\n";
 344            }
 345          }
 346  
 347          if (tep_not_null($this->requestBody)) {
 348            $cmd .= "\r\n" . $this->requestBody;
 349          }
 350  
 351  // unset body (in case of successive requests)
 352          $this->requestBody = '';
 353  
 354          fputs($this->socket, $cmd . "\r\n");
 355  
 356          return true;
 357        }
 358      }
 359  
 360      function processReply() {
 361        $this->replyString = trim(fgets($this->socket, 1024));
 362  
 363        if (preg_match('|^HTTP/\S+ (\d+) |i', $this->replyString, $a )) {
 364          $this->reply = $a[1];
 365        } else {
 366          $this->reply = 'Bad Response';
 367        }
 368  
 369  //get response headers and body
 370        $this->responseHeaders = $this->processHeader();
 371        $this->responseBody = $this->processBody();
 372  
 373        return $this->reply;
 374      }
 375  
 376  /**
 377   * processHeader() reads header lines from socket until the line equals $lastLine
 378   * @scope protected
 379   * @return array of headers with header names as keys and header content as values
 380   **/
 381      function processHeader($lastLine = "\r\n") {
 382        $headers = array();
 383        $finished = false;
 384  
 385        while ( (!$finished) && (!feof($this->socket)) ) {
 386          $str = fgets($this->socket, 1024);
 387          $finished = ($str == $lastLine);
 388          if (!$finished) {
 389            list($hdr, $value) = split(': ', $str, 2);
 390  // nasty workaround broken multiple same headers (eg. Set-Cookie headers) @FIXME 
 391            if (isset($headers[$hdr])) {
 392              $headers[$hdr] .= '; ' . trim($value);
 393            } else {
 394              $headers[$hdr] = trim($value);
 395            }
 396          }
 397        }
 398  
 399        return $headers;
 400      }
 401  
 402  /**
 403   * processBody() reads the body from the socket
 404   * the body is the "real" content of the reply
 405   * @return string body content 
 406   * @scope private
 407   **/
 408      function processBody() {
 409        $data = '';
 410        $counter = 0;
 411  
 412        do {
 413          $status = socket_get_status($this->socket);
 414          if ($status['eof'] == 1) {
 415            break;
 416          }
 417  
 418          if ($status['unread_bytes'] > 0) {
 419            $buffer = fread($this->socket, $status['unread_bytes']);
 420            $counter = 0;
 421          } else {
 422            $buffer = fread($this->socket, 128);
 423            $counter++;
 424            usleep(2);
 425          }
 426  
 427          $data .= $buffer;
 428        } while ( ($status['unread_bytes'] > 0) || ($counter++ < 10) );
 429  
 430        return $data;
 431      }
 432  
 433  /**
 434   * Calculate and return the URI to be sent ( proxy purpose )
 435   * @param the local URI
 436   * @return URI to be used in the HTTP request
 437   * @scope private
 438   **/
 439      function makeUri($uri) {
 440        $a = parse_url($uri);
 441  
 442        if ( (isset($a['scheme'])) && (isset($a['host'])) ) {
 443          $this->url = $a;
 444        } else {
 445          unset($this->url['query']);
 446          unset($this->url['fragment']);
 447          $this->url = array_merge($this->url, $a);
 448        }
 449  
 450        if ($this->useProxy) {
 451          $requesturi = 'http://' . $this->url['host'] . (empty($this->url['port']) ? '' : ':' . $this->url['port']) . $this->url['path'] . (empty($this->url['query']) ? '' : '?' . $this->url['query']);
 452        } else {
 453          $requesturi = $this->url['path'] . (empty($this->url['query']) ? '' : '?' . $this->url['query']);
 454        }
 455  
 456        return $requesturi;
 457      }
 458    }
 459  ?>


Generated: Fri Jan 1 13:43:16 2010 Cross-referenced by PHPXref 0.7