[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[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: Proxy.php 24818 2012-05-28 18:49:53Z rob $ 20 * @copyright Copyright (c) 2005-2012 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-2012 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 * Stores the last CONNECT handshake request 81 * 82 * @var string 83 */ 84 protected $connectHandshakeRequest; 85 86 /** 87 * Connect to the remote server 88 * 89 * Will try to connect to the proxy server. If no proxy was set, will 90 * fall back to the target server (behave like regular Socket adapter) 91 * 92 * @param string $host 93 * @param int $port 94 * @param boolean $secure 95 */ 96 public function connect($host, $port = 80, $secure = false) 97 { 98 // If no proxy is set, fall back to Socket adapter 99 if (! $this->config['proxy_host']) { 100 return parent::connect($host, $port, $secure); 101 } 102 103 /* Url might require stream context even if proxy connection doesn't */ 104 if ($secure) { 105 $this->config['sslusecontext'] = true; 106 } 107 108 // Connect (a non-secure connection) to the proxy server 109 return parent::connect( 110 $this->config['proxy_host'], 111 $this->config['proxy_port'], 112 false 113 ); 114 } 115 116 /** 117 * Send request to the proxy server 118 * 119 * @param string $method 120 * @param Zend_Uri_Http $uri 121 * @param string $http_ver 122 * @param array $headers 123 * @param string $body 124 * @return string Request as string 125 */ 126 public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') 127 { 128 // If no proxy is set, fall back to default Socket adapter 129 if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body); 130 131 // Make sure we're properly connected 132 if (! $this->socket) { 133 require_once 'Zend/Http/Client/Adapter/Exception.php'; 134 throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected"); 135 } 136 137 $host = $this->config['proxy_host']; 138 $port = $this->config['proxy_port']; 139 140 if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) { 141 require_once 'Zend/Http/Client/Adapter/Exception.php'; 142 throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server"); 143 } 144 145 // Add Proxy-Authorization header 146 if ($this->config['proxy_user']) { 147 // Check to see if one already exists 148 $hasProxyAuthHeader = false; 149 foreach ($headers as $k => $v) { 150 if ($k == 'proxy-authorization' || preg_match("/^proxy-authorization:/i", $v) ) { 151 $hasProxyAuthHeader = true; 152 break; 153 } 154 } 155 if (!$hasProxyAuthHeader) { 156 $headers[] = 'Proxy-authorization: ' . Zend_Http_Client::encodeAuthHeader( 157 $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth'] 158 ); 159 } 160 } 161 162 // if we are proxying HTTPS, preform CONNECT handshake with the proxy 163 if ($uri->getScheme() == 'https' && (! $this->negotiated)) { 164 $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers); 165 $this->negotiated = true; 166 } 167 168 // Save request method for later 169 $this->method = $method; 170 171 // Build request headers 172 if ($this->negotiated) { 173 $path = $uri->getPath(); 174 if ($uri->getQuery()) { 175 $path .= '?' . $uri->getQuery(); 176 } 177 $request = "$method $path HTTP/$http_ver\r\n"; 178 } else { 179 $request = "$method $uri HTTP/$http_ver\r\n"; 180 } 181 182 // Add all headers to the request string 183 foreach ($headers as $k => $v) { 184 if (is_string($k)) $v = "$k: $v"; 185 $request .= "$v\r\n"; 186 } 187 188 if(is_resource($body)) { 189 $request .= "\r\n"; 190 } else { 191 // Add the request body 192 $request .= "\r\n" . $body; 193 } 194 195 // Send the request 196 if (! @fwrite($this->socket, $request)) { 197 require_once 'Zend/Http/Client/Adapter/Exception.php'; 198 throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); 199 } 200 201 if(is_resource($body)) { 202 if(stream_copy_to_stream($body, $this->socket) == 0) { 203 require_once 'Zend/Http/Client/Adapter/Exception.php'; 204 throw new Zend_Http_Client_Adapter_Exception('Error writing request to server'); 205 } 206 } 207 208 return $request; 209 } 210 211 /** 212 * Preform handshaking with HTTPS proxy using CONNECT method 213 * 214 * @param string $host 215 * @param integer $port 216 * @param string $http_ver 217 * @param array $headers 218 */ 219 protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array()) 220 { 221 $request = "CONNECT $host:$port HTTP/$http_ver\r\n" . 222 "Host: " . $this->config['proxy_host'] . "\r\n"; 223 224 // Process provided headers, including important ones to CONNECT request 225 foreach ( $headers as $k=>$v ) { 226 switch ( strtolower(substr($v,0,strpos($v,':'))) ) { 227 case 'proxy-authorization': 228 // break intentionally omitted 229 case 'user-agent': 230 $request .= $v . "\r\n"; 231 break; 232 default: 233 break; 234 } 235 } 236 $request .= "\r\n"; 237 238 // @see ZF-3189 239 $this->connectHandshakeRequest = $request; 240 241 // Send the request 242 if (! @fwrite($this->socket, $request)) { 243 require_once 'Zend/Http/Client/Adapter/Exception.php'; 244 throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); 245 } 246 247 // Read response headers only 248 $response = ''; 249 $gotStatus = false; 250 while ($line = @fgets($this->socket)) { 251 $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); 252 if ($gotStatus) { 253 $response .= $line; 254 if (!chop($line)) break; 255 } 256 } 257 258 // Check that the response from the proxy is 200 259 if (Zend_Http_Response::extractCode($response) != 200) { 260 require_once 'Zend/Http/Client/Adapter/Exception.php'; 261 throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response); 262 } 263 264 // If all is good, switch socket to secure mode. We have to fall back 265 // through the different modes 266 $modes = array( 267 STREAM_CRYPTO_METHOD_TLS_CLIENT, 268 STREAM_CRYPTO_METHOD_SSLv3_CLIENT, 269 STREAM_CRYPTO_METHOD_SSLv23_CLIENT, 270 STREAM_CRYPTO_METHOD_SSLv2_CLIENT 271 ); 272 273 $success = false; 274 foreach($modes as $mode) { 275 $success = stream_socket_enable_crypto($this->socket, true, $mode); 276 if ($success) break; 277 } 278 279 if (! $success) { 280 require_once 'Zend/Http/Client/Adapter/Exception.php'; 281 throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" . 282 " HTTPS server through proxy: could not negotiate secure connection."); 283 } 284 } 285 286 /** 287 * Close the connection to the server 288 * 289 */ 290 public function close() 291 { 292 parent::close(); 293 $this->negotiated = false; 294 } 295 296 /** 297 * Destructor: make sure the socket is disconnected 298 * 299 */ 300 public function __destruct() 301 { 302 if ($this->socket) $this->close(); 303 } 304 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |