From fbab2bfa173e1bf3667051b99bf544cccad1ad9d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 23 Nov 2015 12:33:50 +0000 Subject: [PATCH] Move user agent definition to StreamContextFactory so it is available in all contexts --- src/Composer/Util/RemoteFilesystem.php | 16 +-------- src/Composer/Util/StreamContextFactory.php | 18 ++++++++++ .../Test/Util/RemoteFilesystemTest.php | 8 ----- .../Test/Util/StreamContextFactoryTest.php | 33 +++++++++++-------- 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index e37f41117..512203133 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -449,21 +449,7 @@ class RemoteFilesystem protected function getOptionsForUrl($originUrl, $additionalOptions) { - if (defined('HHVM_VERSION')) { - $phpVersion = 'HHVM ' . HHVM_VERSION; - } else { - $phpVersion = 'PHP ' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION; - } - - $headers = array( - sprintf( - 'User-Agent: Composer/%s (%s; %s; %s)', - Composer::VERSION === '@package_version@' ? 'source' : Composer::VERSION, - php_uname('s'), - php_uname('r'), - $phpVersion - ), - ); + $headers = array(); if (extension_loaded('zlib')) { $headers[] = 'Accept-Encoding: gzip'; diff --git a/src/Composer/Util/StreamContextFactory.php b/src/Composer/Util/StreamContextFactory.php index cd8c05d92..484145f45 100644 --- a/src/Composer/Util/StreamContextFactory.php +++ b/src/Composer/Util/StreamContextFactory.php @@ -12,6 +12,8 @@ namespace Composer\Util; +use Composer\Composer; + /** * Allows the creation of a basic context supporting http proxy * @@ -127,6 +129,22 @@ final class StreamContextFactory $options['http']['header'] = self::fixHttpHeaderField($options['http']['header']); } + if (defined('HHVM_VERSION')) { + $phpVersion = 'HHVM ' . HHVM_VERSION; + } else { + $phpVersion = 'PHP ' . PHP_MAJOR_VERSION . '.' . PHP_MINOR_VERSION . '.' . PHP_RELEASE_VERSION; + } + + if (!isset($options['http']['header']) || false === strpos(strtolower(implode('', $options['http']['header'])), 'user-agent')) { + $options['http']['header'][] = sprintf( + 'User-Agent: Composer/%s (%s; %s; %s)', + Composer::VERSION === '@package_version@' ? 'source' : Composer::VERSION, + php_uname('s'), + php_uname('r'), + $phpVersion + ); + } + return stream_context_create($options, $defaultParams); } diff --git a/tests/Composer/Test/Util/RemoteFilesystemTest.php b/tests/Composer/Test/Util/RemoteFilesystemTest.php index d09993130..eaa4850eb 100644 --- a/tests/Composer/Test/Util/RemoteFilesystemTest.php +++ b/tests/Composer/Test/Util/RemoteFilesystemTest.php @@ -27,14 +27,6 @@ class RemoteFilesystemTest extends \PHPUnit_Framework_TestCase $res = $this->callGetOptionsForUrl($io, array('http://example.org', array())); $this->assertTrue(isset($res['http']['header']) && is_array($res['http']['header']), 'getOptions must return an array with headers'); - $found = false; - foreach ($res['http']['header'] as $header) { - if (0 === strpos($header, 'User-Agent:')) { - $found = true; - } - } - - $this->assertTrue($found, 'getOptions must have a User-Agent header'); } public function testGetOptionsForUrlWithAuthorization() diff --git a/tests/Composer/Test/Util/StreamContextFactoryTest.php b/tests/Composer/Test/Util/StreamContextFactoryTest.php index 590a868fd..64d35eeb3 100644 --- a/tests/Composer/Test/Util/StreamContextFactoryTest.php +++ b/tests/Composer/Test/Util/StreamContextFactoryTest.php @@ -51,11 +51,11 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase { return array( array( - $a = array('http' => array('follow_location' => 1, 'max_redirects' => 20)), array(), + $a = array('http' => array('follow_location' => 1, 'max_redirects' => 20, 'header' => array('User-Agent: foo'))), array('http' => array('header' => 'User-Agent: foo')), array('options' => $a), array(), ), array( - $a = array('http' => array('method' => 'GET', 'max_redirects' => 20, 'follow_location' => 1)), array('http' => array('method' => 'GET')), + $a = array('http' => array('method' => 'GET', 'max_redirects' => 20, 'follow_location' => 1, 'header' => array('User-Agent: foo'))), array('http' => array('method' => 'GET', 'header' => 'User-Agent: foo')), array('options' => $a, 'notification' => $f = function () {}), array('notification' => $f), ), ); @@ -66,14 +66,14 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase $_SERVER['http_proxy'] = 'http://username:p%40ssword@proxyserver.net:3128/'; $_SERVER['HTTP_PROXY'] = 'http://proxyserver/'; - $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET'))); + $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET', 'header' => 'User-Agent: foo'))); $options = stream_context_get_options($context); $this->assertEquals(array('http' => array( 'proxy' => 'tcp://proxyserver.net:3128', 'request_fulluri' => true, 'method' => 'GET', - 'header' => array("Proxy-Authorization: Basic " . base64_encode('username:p@ssword')), + 'header' => array('User-Agent: foo', "Proxy-Authorization: Basic " . base64_encode('username:p@ssword')), 'max_redirects' => 20, 'follow_location' => 1, )), $options); @@ -84,13 +84,14 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:3128/'; $_SERVER['no_proxy'] = 'foo,example.org'; - $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET'))); + $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET', 'header' => 'User-Agent: foo'))); $options = stream_context_get_options($context); $this->assertEquals(array('http' => array( 'method' => 'GET', 'max_redirects' => 20, 'follow_location' => 1, + 'header' => array('User-Agent: foo'), )), $options); } @@ -99,13 +100,14 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:3128/'; $_SERVER['no_proxy'] = '*'; - $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET'))); + $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET', 'header' => 'User-Agent: foo'))); $options = stream_context_get_options($context); $this->assertEquals(array('http' => array( 'method' => 'GET', 'max_redirects' => 20, 'follow_location' => 1, + 'header' => array('User-Agent: foo'), )), $options); } @@ -113,14 +115,14 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase { $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net:3128/'; - $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET', 'header' => array("X-Foo: bar"), 'request_fulluri' => false))); + $context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET', 'header' => array('User-Agent: foo', "X-Foo: bar"), 'request_fulluri' => false))); $options = stream_context_get_options($context); $this->assertEquals(array('http' => array( 'proxy' => 'tcp://proxyserver.net:3128', 'request_fulluri' => false, 'method' => 'GET', - 'header' => array("X-Foo: bar", "Proxy-Authorization: Basic " . base64_encode('username:password')), + 'header' => array('User-Agent: foo', "X-Foo: bar", "Proxy-Authorization: Basic " . base64_encode('username:password')), 'max_redirects' => 20, 'follow_location' => 1, )), $options); @@ -130,7 +132,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase { $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net'; - $context = StreamContextFactory::getContext('https://example.org', array('http' => array('method' => 'GET'))); + $context = StreamContextFactory::getContext('https://example.org', array('http' => array('method' => 'GET', 'header' => 'User-Agent: foo'))); $options = stream_context_get_options($context); $expected = array( @@ -138,7 +140,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase 'proxy' => 'tcp://proxyserver.net:80', 'request_fulluri' => true, 'method' => 'GET', - 'header' => array("Proxy-Authorization: Basic " . base64_encode('username:password')), + 'header' => array('User-Agent: foo', "Proxy-Authorization: Basic " . base64_encode('username:password')), 'max_redirects' => 20, 'follow_location' => 1, ), 'ssl' => array( @@ -161,7 +163,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase $_SERVER['http_proxy'] = 'http://username:password@proxyserver.net'; $_SERVER['https_proxy'] = 'https://woopproxy.net'; - $context = StreamContextFactory::getContext('https://example.org', array('http' => array('method' => 'GET'))); + $context = StreamContextFactory::getContext('https://example.org', array('http' => array('method' => 'GET', 'header' => 'User-Agent: foo'))); $options = stream_context_get_options($context); $expected = array( @@ -171,6 +173,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase 'method' => 'GET', 'max_redirects' => 20, 'follow_location' => 1, + 'header' => array('User-Agent: foo'), ), 'ssl' => array( 'SNI_enabled' => true, 'SNI_server_name' => 'example.org', @@ -190,7 +193,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase $_SERVER['http_proxy'] = $proxy; if (extension_loaded('openssl')) { - $context = StreamContextFactory::getContext('http://example.org'); + $context = StreamContextFactory::getContext('http://example.org', array('http' => array('header' => 'User-Agent: foo'))); $options = stream_context_get_options($context); $this->assertEquals(array('http' => array( @@ -198,6 +201,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase 'request_fulluri' => true, 'max_redirects' => 20, 'follow_location' => 1, + 'header' => array('User-Agent: foo'), )), $options); } else { try { @@ -221,12 +225,13 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase { $options = array( 'http' => array( - 'header' => "X-Foo: bar\r\nContent-Type: application/json\r\nAuthorization: Basic aW52YWxpZA==", + 'header' => "User-agent: foo\r\nX-Foo: bar\r\nContent-Type: application/json\r\nAuthorization: Basic aW52YWxpZA==", ), ); $expectedOptions = array( 'http' => array( 'header' => array( + "User-agent: foo", "X-Foo: bar", "Authorization: Basic aW52YWxpZA==", "Content-Type: application/json", @@ -235,6 +240,6 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase ); $context = StreamContextFactory::getContext('http://example.org', $options); $ctxoptions = stream_context_get_options($context); - $this->assertEquals(end($ctxoptions['http']['header']), end($expectedOptions['http']['header'])); + $this->assertEquals(end($expectedOptions['http']['header']), end($ctxoptions['http']['header'])); } }