diff -r 8d50c48361b8 -r ba5f4046635b web/lib/Zend/Http/Client/Adapter/Proxy.php --- a/web/lib/Zend/Http/Client/Adapter/Proxy.php Fri Mar 22 10:44:46 2013 +0100 +++ b/web/lib/Zend/Http/Client/Adapter/Proxy.php Fri Mar 22 10:47:04 2013 +0100 @@ -16,8 +16,8 @@ * @category Zend * @package Zend_Http * @subpackage Client_Adapter - * @version $Id: Proxy.php 21792 2010-04-08 00:27:06Z stas $ - * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @version $Id: Proxy.php 25273 2013-03-06 08:02:21Z frosch $ + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ @@ -46,7 +46,7 @@ * @category Zend * @package Zend_Http * @subpackage Client_Adapter - * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) + * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) * @license http://framework.zend.com/license/new-bsd New BSD License */ class Zend_Http_Client_Adapter_Proxy extends Zend_Http_Client_Adapter_Socket @@ -66,7 +66,7 @@ 'proxy_user' => '', 'proxy_pass' => '', 'proxy_auth' => Zend_Http_Client::AUTH_BASIC, - 'persistent' => false + 'persistent' => false, ); /** @@ -75,6 +75,13 @@ * @var boolean */ protected $negotiated = false; + + /** + * Stores the last CONNECT handshake request + * + * @var string + */ + protected $connectHandshakeRequest; /** * Connect to the remote server @@ -89,13 +96,13 @@ public function connect($host, $port = 80, $secure = false) { // If no proxy is set, fall back to Socket adapter - if (! $this->config['proxy_host']) { + if (!$this->config['proxy_host']) { return parent::connect($host, $port, $secure); } - + /* Url might require stream context even if proxy connection doesn't */ if ($secure) { - $this->config['sslusecontext'] = true; + $this->config['sslusecontext'] = true; } // Connect (a non-secure connection) to the proxy server @@ -115,36 +122,63 @@ * @param array $headers * @param string $body * @return string Request as string + * @throws Zend_Http_Client_Adapter_Exception */ - public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '') + public function write( + $method, $uri, $http_ver = '1.1', $headers = array(), $body = '' + ) { // If no proxy is set, fall back to default Socket adapter - if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body); + if (!$this->config['proxy_host']) { + return parent::write($method, $uri, $http_ver, $headers, $body); + } // Make sure we're properly connected - if (! $this->socket) { + if (!$this->socket) { require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are not connected"); + throw new Zend_Http_Client_Adapter_Exception( + 'Trying to write but we are not connected' + ); } $host = $this->config['proxy_host']; $port = $this->config['proxy_port']; - if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) { + if ($this->connected_to[0] != "tcp://$host" + || $this->connected_to[1] != $port + ) { require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server"); + throw new Zend_Http_Client_Adapter_Exception( + 'Trying to write but we are connected to the wrong proxy server' + ); } // Add Proxy-Authorization header - if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) { - $headers['proxy-authorization'] = Zend_Http_Client::encodeAuthHeader( - $this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth'] - ); + if ($this->config['proxy_user']) { + // Check to see if one already exists + $hasProxyAuthHeader = false; + foreach ($headers as $k => $v) { + if ((string) $k == 'proxy-authorization' + || preg_match("/^proxy-authorization:/i", $v) + ) { + $hasProxyAuthHeader = true; + break; + } + } + if (!$hasProxyAuthHeader) { + $headers[] = 'Proxy-authorization: ' + . Zend_Http_Client::encodeAuthHeader( + $this->config['proxy_user'], + $this->config['proxy_pass'], $this->config['proxy_auth'] + ); + } } // if we are proxying HTTPS, preform CONNECT handshake with the proxy - if ($uri->getScheme() == 'https' && (! $this->negotiated)) { - $this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers); + if ($uri->getScheme() == 'https' && (!$this->negotiated)) { + $this->connectHandshake( + $uri->getHost(), $uri->getPort(), $http_ver, $headers + ); $this->negotiated = true; } @@ -174,20 +208,24 @@ // Add the request body $request .= "\r\n" . $body; } - + // Send the request - if (! @fwrite($this->socket, $request)) { + if (!@fwrite($this->socket, $request)) { require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); + throw new Zend_Http_Client_Adapter_Exception( + 'Error writing request to proxy server' + ); } - + if(is_resource($body)) { if(stream_copy_to_stream($body, $this->socket) == 0) { require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception('Error writing request to server'); + throw new Zend_Http_Client_Adapter_Exception( + 'Error writing request to server' + ); } } - + return $request; } @@ -198,30 +236,41 @@ * @param integer $port * @param string $http_ver * @param array $headers + * @return void + * @throws Zend_Http_Client_Adapter_Exception */ - protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array()) + protected function connectHandshake( + $host, $port = 443, $http_ver = '1.1', array &$headers = array() + ) { $request = "CONNECT $host:$port HTTP/$http_ver\r\n" . "Host: " . $this->config['proxy_host'] . "\r\n"; - // Add the user-agent header - if (isset($this->config['useragent'])) { - $request .= "User-agent: " . $this->config['useragent'] . "\r\n"; - } + // Process provided headers, including important ones to CONNECT request + foreach ($headers as $k => $v) { + switch (strtolower(substr($v,0,strpos($v,':')))) { + case 'proxy-authorization': + // break intentionally omitted - // If the proxy-authorization header is set, send it to proxy but remove - // it from headers sent to target host - if (isset($headers['proxy-authorization'])) { - $request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n"; - unset($headers['proxy-authorization']); + case 'user-agent': + $request .= $v . "\r\n"; + break; + + default: + break; + } } - $request .= "\r\n"; + + // @see ZF-3189 + $this->connectHandshakeRequest = $request; // Send the request - if (! @fwrite($this->socket, $request)) { + if (!@fwrite($this->socket, $request)) { require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Error writing request to proxy server"); + throw new Zend_Http_Client_Adapter_Exception( + 'Error writing request to proxy server' + ); } // Read response headers only @@ -231,14 +280,18 @@ $gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false); if ($gotStatus) { $response .= $line; - if (!chop($line)) break; + if (!chop($line)) { + break; + } } } // Check that the response from the proxy is 200 if (Zend_Http_Response::extractCode($response) != 200) { require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response); + throw new Zend_Http_Client_Adapter_Exception( + 'Unable to connect to HTTPS proxy. Server response: ' . $response + ); } // If all is good, switch socket to secure mode. We have to fall back @@ -253,13 +306,17 @@ $success = false; foreach($modes as $mode) { $success = stream_socket_enable_crypto($this->socket, true, $mode); - if ($success) break; + if ($success) { + break; + } } - if (! $success) { - require_once 'Zend/Http/Client/Adapter/Exception.php'; - throw new Zend_Http_Client_Adapter_Exception("Unable to connect to" . - " HTTPS server through proxy: could not negotiate secure connection."); + if (!$success) { + require_once 'Zend/Http/Client/Adapter/Exception.php'; + throw new Zend_Http_Client_Adapter_Exception( + 'Unable to connect to HTTPS server through proxy: could not ' + . 'negotiate secure connection.' + ); } } @@ -279,6 +336,8 @@ */ public function __destruct() { - if ($this->socket) $this->close(); + if ($this->socket) { + $this->close(); + } } }