Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Http/Client/Adapter/Proxy.php
Go to the documentation of this file.
00001 <?php
00002 
00027 require_once 'Zend/Uri/Http.php';
00031 require_once 'Zend/Http/Client.php';
00035 require_once 'Zend/Http/Client/Adapter/Socket.php';
00036 
00052 class Zend_Http_Client_Adapter_Proxy extends Zend_Http_Client_Adapter_Socket
00053 {
00059     protected $config = array(
00060         'ssltransport'  => 'ssl',
00061         'sslcert'       => null,
00062         'sslpassphrase' => null,
00063         'sslusecontext' => false,
00064         'proxy_host'    => '',
00065         'proxy_port'    => 8080,
00066         'proxy_user'    => '',
00067         'proxy_pass'    => '',
00068         'proxy_auth'    => Zend_Http_Client::AUTH_BASIC,
00069         'persistent'    => false
00070     );
00071 
00077     protected $negotiated = false;
00078 
00089     public function connect($host, $port = 80, $secure = false)
00090     {
00091         // If no proxy is set, fall back to Socket adapter
00092         if (! $this->config['proxy_host']) {
00093             return parent::connect($host, $port, $secure);
00094         }
00095         
00096         /* Url might require stream context even if proxy connection doesn't */
00097         if ($secure) {
00098                 $this->config['sslusecontext'] = true;
00099         }
00100 
00101         // Connect (a non-secure connection) to the proxy server
00102         return parent::connect(
00103             $this->config['proxy_host'],
00104             $this->config['proxy_port'],
00105             false
00106         );
00107     }
00108 
00119     public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
00120     {
00121         // If no proxy is set, fall back to default Socket adapter
00122         if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body);
00123 
00124         // Make sure we're properly connected
00125         if (! $this->socket) {
00126             require_once 'Zend/Http/Client/Adapter/Exception.php';
00127             throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected");
00128         }
00129 
00130         $host = $this->config['proxy_host'];
00131         $port = $this->config['proxy_port'];
00132 
00133         if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) {
00134             require_once 'Zend/Http/Client/Adapter/Exception.php';
00135             throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server");
00136         }
00137 
00138         // Add Proxy-Authorization header
00139         if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) {
00140             $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader(
00141                 $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth']
00142             );
00143         }
00144 
00145         // if we are proxying HTTPS, preform CONNECT handshake with the proxy
00146         if ($uri->getScheme() == 'https' && (! $this->negotiated)) {
00147             $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers);
00148             $this->negotiated = true;
00149         }
00150 
00151         // Save request method for later
00152         $this->method = $method;
00153 
00154         // Build request headers
00155         if ($this->negotiated) {
00156             $path = $uri->getPath();
00157             if ($uri->getQuery()) {
00158                 $path .= '?' . $uri->getQuery();
00159             }
00160             $request = "$method $path HTTP/$http_ver\r\n";
00161         } else {
00162             $request = "$method $uri HTTP/$http_ver\r\n";
00163         }
00164 
00165         // Add all headers to the request string
00166         foreach ($headers as $k => $v) {
00167             if (is_string($k)) $v = "$k: $v";
00168             $request .= "$v\r\n";
00169         }
00170 
00171         if(is_resource($body)) {
00172             $request .= "\r\n";
00173         } else {
00174             // Add the request body
00175             $request .= "\r\n" . $body;
00176         }
00177         
00178         // Send the request
00179         if (! @fwrite($this->socket, $request)) {
00180             require_once 'Zend/Http/Client/Adapter/Exception.php';
00181             throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
00182         }
00183         
00184         if(is_resource($body)) {
00185             if(stream_copy_to_stream($body, $this->socket) == 0) {
00186                 require_once 'Zend/Http/Client/Adapter/Exception.php';
00187                 throw new Zend_Http_Client_Adapter_Exception('Error writing request to server');
00188             }
00189         }
00190         
00191         return $request;
00192     }
00193 
00202     protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array())
00203     {
00204         $request = "CONNECT $host:$port HTTP/$http_ver\r\n" .
00205                    "Host: " . $this->config['proxy_host'] . "\r\n";
00206 
00207         // Add the user-agent header
00208         if (isset($this->config['useragent'])) {
00209             $request .= "User-agent: " . $this->config['useragent'] . "\r\n";
00210         }
00211 
00212         // If the proxy-authorization header is set, send it to proxy but remove
00213         // it from headers sent to target host
00214         if (isset($headers['proxy-authorization'])) {
00215             $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n";
00216             unset($headers['proxy-authorization']);
00217         }
00218 
00219         $request .= "\r\n";
00220 
00221         // Send the request
00222         if (! @fwrite($this->socket, $request)) {
00223             require_once 'Zend/Http/Client/Adapter/Exception.php';
00224             throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server");
00225         }
00226 
00227         // Read response headers only
00228         $response = '';
00229         $gotStatus = false;
00230         while ($line = @fgets($this->socket)) {
00231             $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
00232             if ($gotStatus) {
00233                 $response .= $line;
00234                 if (!chop($line)) break;
00235             }
00236         }
00237 
00238         // Check that the response from the proxy is 200
00239         if (Zend_Http_Response::extractCode($response) != 200) {
00240             require_once 'Zend/Http/Client/Adapter/Exception.php';
00241             throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response);
00242         }
00243 
00244         // If all is good, switch socket to secure mode. We have to fall back
00245         // through the different modes
00246         $modes = array(
00247             STREAM_CRYPTO_METHOD_TLS_CLIENT,
00248             STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
00249             STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
00250             STREAM_CRYPTO_METHOD_SSLv2_CLIENT
00251         );
00252 
00253         $success = false;
00254         foreach($modes as $mode) {
00255             $success = stream_socket_enable_crypto($this->socket, true, $mode);
00256             if ($success) break;
00257         }
00258 
00259         if (! $success) {
00260                 require_once 'Zend/Http/Client/Adapter/Exception.php';
00261                 throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" .
00262                     " HTTPS server through proxy: could not negotiate secure connection.");
00263         }
00264     }
00265 
00270     public function close()
00271     {
00272         parent::close();
00273         $this->negotiated = false;
00274     }
00275 
00280     public function __destruct()
00281     {
00282         if ($this->socket) $this->close();
00283     }
00284 }
 All Data Structures Namespaces Files Functions Variables Enumerations