From 45cd26b2df058a443fcf3b214e79b1d36dc328d5 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 29 Nov 2017 16:37:00 +0100 Subject: [PATCH 1/2] Fix test and actually check that we get hasAuthentication called for different domains --- tests/Composer/Test/Util/RemoteFilesystemTest.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tests/Composer/Test/Util/RemoteFilesystemTest.php b/tests/Composer/Test/Util/RemoteFilesystemTest.php index b2276bc01..faba402a7 100644 --- a/tests/Composer/Test/Util/RemoteFilesystemTest.php +++ b/tests/Composer/Test/Util/RemoteFilesystemTest.php @@ -247,11 +247,17 @@ class RemoteFilesystemTest extends \PHPUnit_Framework_TestCase ->withAnyParameters() ->willReturn(array()); + $domains = array(); $io + ->expects($this->any()) ->method('hasAuthentication') - ->with('bitbucket.org') - ->willReturn(true); + ->will($this->returnCallback(function($arg) use (&$domains) { + $domains[] = $arg; + // first time is called with bitbucket.org, then it redirects to bbuseruploads.s3.amazonaws.com so next time we have no auth configured + return $arg === 'bitbucket.org'; + })); $io + ->expects($this->at(1)) ->method('getAuthentication') ->with('bitbucket.org') ->willReturn(array( @@ -266,6 +272,7 @@ class RemoteFilesystemTest extends \PHPUnit_Framework_TestCase $result = $rfs->getContents($hostname, $url, false); $this->assertEquals($contents, $result); + $this->assertEquals(array('bitbucket.org', 'bbuseruploads.s3.amazonaws.com'), $domains); } protected function callGetOptionsForUrl($io, array $args = array(), array $options = array(), $fileUrl = '') From b52fd608734b1554def7b485c8e48821d1bfbdc4 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Wed, 29 Nov 2017 16:37:45 +0100 Subject: [PATCH 2/2] Always follow redirects in userland as we need to check if we have authentication every time for the new domain --- src/Composer/Util/RemoteFilesystem.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index 1ace44c96..f107599cc 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -245,7 +245,6 @@ class RemoteFilesystem $options = $this->getOptionsForUrl($originUrl, $tempAdditionalOptions); unset($tempAdditionalOptions); - $userlandFollow = isset($options['http']['follow_location']) && !$options['http']['follow_location']; $origFileUrl = $fileUrl; @@ -382,9 +381,9 @@ class RemoteFilesystem } } - // handle 3xx redirects for php<5.6, 304 Not Modified is excluded + // handle 3xx redirects, 304 Not Modified is excluded $hasFollowedRedirect = false; - if ($userlandFollow && $statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $this->redirects < $this->maxRedirects) { + if ($statusCode >= 300 && $statusCode <= 399 && $statusCode !== 304 && $this->redirects < $this->maxRedirects) { $hasFollowedRedirect = true; $result = $this->handleRedirect($http_response_header, $additionalOptions, $result); } @@ -694,11 +693,7 @@ class RemoteFilesystem if ($this->disableTls === false && PHP_VERSION_ID < 50600 && !stream_is_local($this->fileUrl)) { $host = parse_url($this->fileUrl, PHP_URL_HOST); - if (PHP_VERSION_ID >= 50304) { - // Must manually follow when setting CN_match because this causes all - // redirects to be validated against the same CN_match value. - $userlandFollow = true; - } else { + if (PHP_VERSION_ID < 50304) { // PHP < 5.3.4 does not support follow_location, for those people // do some really nasty hard coded transformations. These will // still breakdown if the site redirects to a domain we don't @@ -764,12 +759,9 @@ class RemoteFilesystem $authStr = base64_encode($auth['username'] . ':' . $auth['password']); $headers[] = 'Authorization: Basic '.$authStr; } - $userlandFollow = true; // always perform userland follow (to be able to change Authorization headers when redirected) } - if (isset($userlandFollow)) { - $options['http']['follow_location'] = 0; - } + $options['http']['follow_location'] = 0; if (isset($options['http']['header']) && !is_array($options['http']['header'])) { $options['http']['header'] = explode("\r\n", trim($options['http']['header'], "\r\n"));