Browse Source

Proxy credentials are now passed as part of HTTP headers

Maxim Chernyshev 13 years ago
parent
commit
419a1cedf0

+ 33 - 5
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);

+ 6 - 7
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 {