From f98bd971f23d9c723e4470039ba2888fcaae7821 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 18 Mar 2012 21:05:10 +0100 Subject: [PATCH] Add Gzip handling to RemoteFilesystem --- src/Composer/Downloader/FileDownloader.php | 1 - src/Composer/Util/RemoteFilesystem.php | 44 ++++++++++++++----- .../Test/Util/RemoteFilesystemTest.php | 3 +- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 1b440048f..d2bfc845b 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -74,7 +74,6 @@ class FileDownloader implements DownloaderInterface $url = $this->processUrl($url); $this->rfs->copy($package->getSourceUrl(), $url, $fileName); - $this->io->write(''); if (!file_exists($fileName)) { throw new \UnexpectedValueException($url.' could not be saved to '.$fileName.', make sure the' diff --git a/src/Composer/Util/RemoteFilesystem.php b/src/Composer/Util/RemoteFilesystem.php index e14201a13..6c70a2f14 100644 --- a/src/Composer/Util/RemoteFilesystem.php +++ b/src/Composer/Util/RemoteFilesystem.php @@ -12,6 +12,7 @@ namespace Composer\Util; +use Composer\Composer; use Composer\IO\IOInterface; use Composer\Downloader\TransportException; @@ -101,22 +102,39 @@ class RemoteFilesystem } $result = @file_get_contents($fileUrl, false, $ctx); - if (null !== $fileName) { - $result = @file_put_contents($fileName, $result) ? true : false; - } // fix for 5.4.0 https://bugs.php.net/bug.php?id=61336 if (!empty($http_response_header[0]) && preg_match('{^HTTP/\S+ 404}i', $http_response_header[0])) { $result = false; } + // decode gzip + if (false !== $result && extension_loaded('zlib') && substr($fileUrl, 0, 4) === 'http') { + foreach ($http_response_header as $header) { + if (preg_match('{^content-encoding: *gzip *$}i', $header)) { + if (version_compare(PHP_VERSION, '5.4.0', '>=')) { + $result = zlib_decode($result); + } else { + // work around issue with gzuncompress & co that do not work with all gzip checksums + $result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result)); + } + break; + } + } + } + + // handle copy command if download was successful + if (false !== $result && null !== $fileName) { + $result = (Boolean) @file_put_contents($fileName, $result); + } + // avoid overriding if content was loaded by a sub-call to get() if (null === $this->result) { $this->result = $result; } if ($this->progress) { - $this->io->overwrite(" Downloading", false); + $this->io->write(''); } if (false === $this->result) { @@ -184,17 +202,21 @@ class RemoteFilesystem } } - protected function getOptionsForUrl($url) + protected function getOptionsForUrl($originUrl) { - $options = array(); - if ($this->io->hasAuthorization($url)) { - $auth = $this->io->getAuthorization($url); + $options['http']['header'] = 'User-Agent: Composer/'.Composer::VERSION."\r\n"; + if (extension_loaded('zlib')) { + $options['http']['header'] .= 'Accept-Encoding: gzip'."\r\n"; + } + + if ($this->io->hasAuthorization($originUrl)) { + $auth = $this->io->getAuthorization($originUrl); $authStr = base64_encode($auth['username'] . ':' . $auth['password']); - $options['http'] = array('header' => "Authorization: Basic $authStr\r\n"); + $options['http']['header'] .= "Authorization: Basic $authStr\r\n"; } elseif (null !== $this->io->getLastUsername()) { $authStr = base64_encode($this->io->getLastUsername() . ':' . $this->io->getLastPassword()); - $options['http'] = array('header' => "Authorization: Basic $authStr\r\n"); - $this->io->setAuthorization($url, $this->io->getLastUsername(), $this->io->getLastPassword()); + $options['http']['header'] .= "Authorization: Basic $authStr\r\n"; + $this->io->setAuthorization($originUrl, $this->io->getLastUsername(), $this->io->getLastPassword()); } return $options; diff --git a/tests/Composer/Test/Util/RemoteFilesystemTest.php b/tests/Composer/Test/Util/RemoteFilesystemTest.php index 97e50b848..e196fa3f4 100644 --- a/tests/Composer/Test/Util/RemoteFilesystemTest.php +++ b/tests/Composer/Test/Util/RemoteFilesystemTest.php @@ -31,7 +31,8 @@ class RemoteFilesystemTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue(null)) ; - $this->assertEquals(array(), $this->callGetOptionsForUrl($io, array('http://example.org'))); + $res = $this->callGetOptionsForUrl($io, array('http://example.org')); + $this->assertTrue(isset($res['http']['header']) && false !== strpos($res['http']['header'], 'User-Agent'), 'getOptions must return an array with a header containing a User-Agent'); } public function testGetOptionsForUrlWithAuthorization()