[phpBB Debug] PHP Warning: in file [ROOT]/includes/crs/crs_misc_functions.php on line 37: mime_content_type(): Empty filename or path
[phpBB Debug] PHP Warning: in file [ROOT]/includes/crs/crs_misc_functions.php on line 37: mime_content_type(): Empty filename or path
Zen Cart 源代码 http_client.php

Zen Cart 源代码 http_client.php




下载文件

文件名: http_client.php
文件类型: PHP文件
文件大小: 12.3 KiB
MD5: 52badddc1eb6489af56945245968616c

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