From 419a1cedf0ebcf190b7c27634eb87db856c87192 Mon Sep 17 00:00:00 2001 From: Maxim Chernyshev Date: Wed, 2 May 2012 08:26:27 +0800 Subject: [PATCH] Proxy credentials are now passed as part of HTTP headers --- src/Composer/Util/StreamContextFactory.php | 38 ++++++++++++++++--- .../Test/Util/StreamContextFactoryTest.php | 13 +++---- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/src/Composer/Util/StreamContextFactory.php b/src/Composer/Util/StreamContextFactory.php index 6541d811b..9826628e3 100644 --- a/src/Composer/Util/StreamContextFactory.php +++ b/src/Composer/Util/StreamContextFactory.php @@ -35,20 +35,48 @@ final class StreamContextFactory if (isset($_SERVER['HTTP_PROXY']) || isset($_SERVER['http_proxy'])) { // Some systems seem to rely on a lowercased version instead... $proxy = isset($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']; - + + $proxyURL = parse_url($proxy, PHP_URL_SCHEME) . "://"; + $proxyURL .= parse_url($proxy, PHP_URL_HOST); + + $proxyPort = parse_url($proxy, PHP_URL_PORT); + + if (isset($proxyPort)) { + $proxyURL .= ":" . $proxyPort; + } + // http(s):// is not supported in proxy - $proxy = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxy); + $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL); - if (0 === strpos($proxy, 'ssl:') && !extension_loaded('openssl')) { + if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) { throw new \RuntimeException('You must enable the openssl extension to use a proxy over https'); } $options['http'] = array( - 'proxy' => $proxy, + 'proxy' => $proxyURL, 'request_fulluri' => true, ); + + // Extract authentication credentials from the proxy url + $user = parse_url($proxy, PHP_URL_USER); + $pass = parse_url($proxy, PHP_URL_PASS); + + if (isset($user)) { + $auth = $user; + if (isset($pass)) { + $auth .= ":{$pass}"; + } + $auth = base64_encode($auth); + + // Preserve headers if already set in default options + if (isset($defaultOptions['http']) && isset($defaultOptions['http']['header'])) { + $defaultOptions['http']['header'] .= "Proxy-Authorization: Basic {$auth}\r\n"; + } else { + $options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n"; + } + } } - + $options = array_merge_recursive($options, $defaultOptions); return stream_context_create($options, $defaultParams); diff --git a/tests/Composer/Test/Util/StreamContextFactoryTest.php b/tests/Composer/Test/Util/StreamContextFactoryTest.php index 8429d078b..0e9928ede 100644 --- a/tests/Composer/Test/Util/StreamContextFactoryTest.php +++ b/tests/Composer/Test/Util/StreamContextFactoryTest.php @@ -57,31 +57,30 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase public function testHttpProxy() { - $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:port/'; - $_SERVER['HTTP_PROXY'] = 'http://proxyserver/'; + $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:1234'; + $_SERVER['HTTP_PROXY'] = 'http://proxyserver'; $context = StreamContextFactory::getContext(array('http' => array('method' => 'GET'))); $options = stream_context_get_options($context); - $this->assertSame('http://proxyserver/', $_SERVER['HTTP_PROXY']); - $this->assertEquals(array('http' => array( - 'proxy' => 'tcp://username:password@proxyserver.net:port/', + 'proxy' => 'tcp://proxyserver.net:1234', 'request_fulluri' => true, 'method' => 'GET', + 'header' => "Proxy-Authorization: Basic " . base64_encode('username:password') . "\r\n" )), $options); } public function testSSLProxy() { - $_SERVER['http_proxy'] = 'https://proxyserver/'; + $_SERVER['http_proxy'] = 'https://proxyserver'; if (extension_loaded('openssl')) { $context = StreamContextFactory::getContext(); $options = stream_context_get_options($context); $this->assertSame(array('http' => array( - 'proxy' => 'ssl://proxyserver/', + 'proxy' => 'ssl://proxyserver', 'request_fulluri' => true, )), $options); } else {