[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Zend Framework 5 * 6 * LICENSE 7 * 8 * This source file is subject to the new BSD license that is bundled 9 * with this package in the file LICENSE.txt. 10 * It is also available through the world-wide-web at this URL: 11 * http://framework.zend.com/license/new-bsd 12 * If you did not receive a copy of the license and are unable to 13 * obtain it through the world-wide-web, please send an email 14 * to [email protected] so we can send you a copy immediately. 15 * 16 * @category Zend 17 * @package Zend_Http 18 * @subpackage Client_Adapter 19 * @version $Id$ 20 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 21 * @license http://framework.zend.com/license/new-bsd New BSD License 22 */ 23 24 /** 25 * @see Zend_Uri_Http 26 */ 27 require_once 'Zend/Uri/Http.php'; 28 /** 29 * @see Zend_Http_Client 30 */ 31 require_once 'Zend/Http/Client.php'; 32 /** 33 * @see Zend_Http_Client_Adapter_Socket 34 */ 35 require_once 'Zend/Http/Client/Adapter/Socket.php'; 36 37 /** 38 * HTTP Proxy-supporting Zend_Http_Client adapter class, based on the default 39 * socket based adapter. 40 * 41 * Should be used if proxy HTTP access is required. If no proxy is set, will 42 * fall back to Zend_Http_Client_Adapter_Socket behavior. Just like the 43 * default Socket adapter, this adapter does not require any special extensions 44 * installed. 45 * 46 * @category Zend 47 * @package Zend_Http 48 * @subpackage Client_Adapter 49 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 50 * @license http://framework.zend.com/license/new-bsd New BSD License 51 */ 52 class Zend_Http_Client_Adapter_Proxy extends Zend_Http_Client_Adapter_Socket 53 { 54 /** 55 * Parameters array 56 * 57 * @var array 58 */ 59 protected $config = array( 60 'ssltransport' => 'ssl', 61 'sslcert' => null, 62 'sslpassphrase' => null, 63 'sslusecontext' => false, 64 'proxy_host' => '', 65 'proxy_port' => 8080, 66 'proxy_user' => '', 67 'proxy_pass' => '', 68 'proxy_auth' => Zend_Http_Client::AUTH_BASIC, 69 'persistent' => false 70 ); 71 72 /** 73 * Whether HTTPS CONNECT was already negotiated with the proxy or not 74 * 75 * @var boolean 76 */ 77 protected $negotiated = false; 78 79 /** 80 * Connect to the remote server 81 * 82 * Will try to connect to the proxy server. If no proxy was set, will 83 * fall back to the target server (behave like regular Socket adapter) 84 * 85 * @param string $host 86 * @param int $port 87 * @param boolean $secure 88 */ 89 public function connect($host, $port = 80, $secure = false) 90 { 91 // If no proxy is set, fall back to Socket adapter 92 if (! $this->config['proxy_host']) { 93 return parent::connect($host, $port, $secure); 94 } 95 96 /* Url might require stream context even if proxy connection doesn't */ 97 if ($secure) { 98 $this->config['sslusecontext'] = true; 99 } 100 101 // Connect (a non-secure connection) to the proxy server 102 return parent::connect( 103 $this->config['proxy_host'], 104 $this->config['proxy_port'], 105 false 106 ); 107 } 108 109 /** 110 * Send request to the proxy server 111 * 112 * @param string $method 113 * @param Zend_Uri_Http $uri 114 * @param string $http_ver 115 * @param array $headers 116 * @param string $body 117 * @return string Request as string 118 */ 119 public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') 120 { 121 // If no proxy is set, fall back to default Socket adapter 122 if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body); 123 124 // Make sure we're properly connected 125 if (! $this->socket) { 126 require_once 'Zend/Http/Client/Adapter/Exception.php'; 127 throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected"); 128 } 129 130 $host = $this->config['proxy_host']; 131 $port = $this->config['proxy_port']; 132 133 if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) { 134 require_once 'Zend/Http/Client/Adapter/Exception.php'; 135 throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server"); 136 } 137 138 // Add Proxy-Authorization header 139 if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) { 140 $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader( 141 $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth'] 142 ); 143 } 144 145 // if we are proxying HTTPS, preform CONNECT handshake with the proxy 146 if ($uri->getScheme() == 'https' && (! $this->negotiated)) { 147 $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers); 148 $this->negotiated = true; 149 } 150 151 // Save request method for later 152 $this->method = $method; 153 154 // Build request headers 155 if ($this->negotiated) { 156 $path = $uri->getPath(); 157 if ($uri->getQuery()) { 158 $path .= '?' . $uri->getQuery(); 159 } 160 $request = "$method $path HTTP/$http_ver\r\n"; 161 } else { 162 $request = "$method $uri HTTP/$http_ver\r\n"; 163 } 164 165 // Add all headers to the request string 166 foreach ($headers as $k => $v) { 167 if (is_string($k)) $v = "$k: $v"; 168 $request .= "$v\r\n"; 169 } 170 171 if(is_resource($body)) { 172 $request .= "\r\n"; 173 } else { 174 // Add the request body 175 $request .= "\r\n" . $body; 176 } 177 178 // Send the request 179 if (! @fwrite($this->socket, $request)) { 180 require_once 'Zend/Http/Client/Adapter/Exception.php'; 181 throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); 182 } 183 184 if(is_resource($body)) { 185 if(stream_copy_to_stream($body, $this->socket) == 0) { 186 require_once 'Zend/Http/Client/Adapter/Exception.php'; 187 throw new Zend_Http_Client_Adapter_Exception('Error writing request to server'); 188 } 189 } 190 191 return $request; 192 } 193 194 /** 195 * Preform handshaking with HTTPS proxy using CONNECT method 196 * 197 * @param string $host 198 * @param integer $port 199 * @param string $http_ver 200 * @param array $headers 201 */ 202 protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array()) 203 { 204 $request = "CONNECT $host:$port HTTP/$http_ver\r\n" . 205 "Host: " . $this->config['proxy_host'] . "\r\n"; 206 207 // Add the user-agent header 208 if (isset($this->config['useragent'])) { 209 $request .= "User-agent: " . $this->config['useragent'] . "\r\n"; 210 } 211 212 // If the proxy-authorization header is set, send it to proxy but remove 213 // it from headers sent to target host 214 if (isset($headers['proxy-authorization'])) { 215 $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n"; 216 unset($headers['proxy-authorization']); 217 } 218 219 $request .= "\r\n"; 220 221 // Send the request 222 if (! @fwrite($this->socket, $request)) { 223 require_once 'Zend/Http/Client/Adapter/Exception.php'; 224 throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); 225 } 226 227 // Read response headers only 228 $response = ''; 229 $gotStatus = false; 230 while ($line = @fgets($this->socket)) { 231 $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); 232 if ($gotStatus) { 233 $response .= $line; 234 if (!chop($line)) break; 235 } 236 } 237 238 // Check that the response from the proxy is 200 239 if (Zend_Http_Response::extractCode($response) != 200) { 240 require_once 'Zend/Http/Client/Adapter/Exception.php'; 241 throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response); 242 } 243 244 // If all is good, switch socket to secure mode. We have to fall back 245 // through the different modes 246 $modes = array( 247 STREAM_CRYPTO_METHOD_TLS_CLIENT, 248 STREAM_CRYPTO_METHOD_SSLv3_CLIENT, 249 STREAM_CRYPTO_METHOD_SSLv23_CLIENT, 250 STREAM_CRYPTO_METHOD_SSLv2_CLIENT 251 ); 252 253 $success = false; 254 foreach($modes as $mode) { 255 $success = stream_socket_enable_crypto($this->socket, true, $mode); 256 if ($success) break; 257 } 258 259 if (! $success) { 260 require_once 'Zend/Http/Client/Adapter/Exception.php'; 261 throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" . 262 " HTTPS server through proxy: could not negotiate secure connection."); 263 } 264 } 265 266 /** 267 * Close the connection to the server 268 * 269 */ 270 public function close() 271 { 272 parent::close(); 273 $this->negotiated = false; 274 } 275 276 /** 277 * Destructor: make sure the socket is disconnected 278 * 279 */ 280 public function __destruct() 281 { 282 if ($this->socket) $this->close(); 283 } 284 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |