浏览代码

Minor fixes and updated the rest of the code/tests to use HttpDownloader

Jordi Boggiano 6 年之前
父节点
当前提交
713bc4de1d
共有 51 个文件被更改,包括 461 次插入436 次删除
  1. 2 2
      doc/articles/plugins.md
  2. 1 1
      src/Composer/Command/ArchiveCommand.php
  3. 2 2
      src/Composer/Downloader/FileDownloader.php
  4. 2 2
      src/Composer/Downloader/GzipDownloader.php
  5. 2 2
      src/Composer/Downloader/RarDownloader.php
  6. 2 2
      src/Composer/Downloader/XzDownloader.php
  7. 2 2
      src/Composer/Downloader/ZipDownloader.php
  8. 13 19
      src/Composer/Factory.php
  9. 1 2
      src/Composer/Package/Loader/ArrayLoader.php
  10. 16 1
      src/Composer/Repository/ComposerRepository.php
  11. 10 6
      src/Composer/Repository/Pear/BaseChannelReader.php
  12. 5 5
      src/Composer/Repository/Pear/ChannelReader.php
  13. 3 2
      src/Composer/Repository/Pear/ChannelRest10Reader.php
  14. 4 2
      src/Composer/Repository/Pear/ChannelRest11Reader.php
  15. 5 5
      src/Composer/Repository/PearRepository.php
  16. 3 3
      src/Composer/Repository/RepositoryFactory.php
  17. 4 4
      src/Composer/Repository/RepositoryManager.php
  18. 15 10
      src/Composer/Repository/Vcs/BitbucketDriver.php
  19. 1 1
      src/Composer/Repository/Vcs/GitBitbucketDriver.php
  20. 29 24
      src/Composer/Repository/Vcs/GitHubDriver.php
  21. 29 26
      src/Composer/Repository/Vcs/GitLabDriver.php
  22. 1 1
      src/Composer/Repository/Vcs/HgBitbucketDriver.php
  23. 9 8
      src/Composer/Repository/Vcs/VcsDriver.php
  24. 6 6
      src/Composer/Util/Bitbucket.php
  25. 5 5
      src/Composer/Util/GitHub.php
  26. 6 6
      src/Composer/Util/GitLab.php
  27. 3 0
      src/Composer/Util/Http/Response.php
  28. 3 7
      src/Composer/Util/HttpDownloader.php
  29. 2 2
      src/Composer/Util/RemoteFilesystem.php
  30. 5 1
      tests/Composer/Test/Downloader/ArchiveDownloaderTest.php
  31. 3 3
      tests/Composer/Test/Downloader/FileDownloaderTest.php
  32. 2 2
      tests/Composer/Test/Downloader/XzDownloaderTest.php
  33. 13 25
      tests/Composer/Test/Downloader/ZipDownloaderTest.php
  34. 3 2
      tests/Composer/Test/InstallerTest.php
  35. 5 7
      tests/Composer/Test/Mock/HttpDownloaderMock.php
  36. 8 1
      tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php
  37. 21 11
      tests/Composer/Test/Repository/ComposerRepositoryTest.php
  38. 1 1
      tests/Composer/Test/Repository/PathRepositoryTest.php
  39. 7 3
      tests/Composer/Test/Repository/Pear/ChannelReaderTest.php
  40. 2 2
      tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php
  41. 2 2
      tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php
  42. 2 2
      tests/Composer/Test/Repository/PearRepositoryTest.php
  43. 3 1
      tests/Composer/Test/Repository/RepositoryFactoryTest.php
  44. 4 2
      tests/Composer/Test/Repository/RepositoryManagerTest.php
  45. 32 36
      tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php
  46. 43 42
      tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php
  47. 42 64
      tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php
  48. 7 7
      tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php
  49. 40 32
      tests/Composer/Test/Util/BitbucketTest.php
  50. 15 16
      tests/Composer/Test/Util/GitHubTest.php
  51. 15 16
      tests/Composer/Test/Util/GitLabTest.php

+ 2 - 2
doc/articles/plugins.md

@@ -176,8 +176,8 @@ class AwsPlugin implements PluginInterface, EventSubscriberInterface
 
         if ($protocol === 's3') {
             $awsClient = new AwsClient($this->io, $this->composer->getConfig());
-            $s3RemoteFilesystem = new S3RemoteFilesystem($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient);
-            $event->setRemoteFilesystem($s3RemoteFilesystem);
+            $s3Downloader = new S3Downloader($this->io, $event->getRemoteFilesystem()->getOptions(), $awsClient);
+            $event->setHttpdownloader($s3Downloader);
         }
     }
 }

+ 1 - 1
src/Composer/Command/ArchiveCommand.php

@@ -104,7 +104,7 @@ EOT
             $archiveManager = $composer->getArchiveManager();
         } else {
             $factory = new Factory;
-            $downloadManager = $factory->createDownloadManager($io, $config);
+            $downloadManager = $factory->createDownloadManager($io, $config, $factory->createHttpDownloader($io, $config));
             $archiveManager = $factory->createArchiveManager($config, $downloadManager);
         }
 

+ 2 - 2
src/Composer/Downloader/FileDownloader.php

@@ -51,12 +51,12 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
      *
      * @param IOInterface      $io              The IO instance
      * @param Config           $config          The config
+     * @param HttpDownloader   $httpDownloader  The remote filesystem
      * @param EventDispatcher  $eventDispatcher The event dispatcher
      * @param Cache            $cache           Cache instance
-     * @param HttpDownloader   $httpDownloader  The remote filesystem
      * @param Filesystem       $filesystem      The filesystem
      */
-    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, Cache $cache, HttpDownloader $httpDownloader, Filesystem $filesystem = null)
+    public function __construct(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, Filesystem $filesystem = null)
     {
         $this->io = $io;
         $this->config = $config;

+ 2 - 2
src/Composer/Downloader/GzipDownloader.php

@@ -30,10 +30,10 @@ class GzipDownloader extends ArchiveDownloader
 {
     protected $process;
 
-    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null)
+    public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
     {
         $this->process = $process ?: new ProcessExecutor($io);
-        parent::__construct($io, $config, $eventDispatcher, $cache, $downloader);
+        parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
     }
 
     protected function extract($file, $path)

+ 2 - 2
src/Composer/Downloader/RarDownloader.php

@@ -33,10 +33,10 @@ class RarDownloader extends ArchiveDownloader
 {
     protected $process;
 
-    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null)
+    public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
     {
         $this->process = $process ?: new ProcessExecutor($io);
-        parent::__construct($io, $config, $eventDispatcher, $cache, $downloader);
+        parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
     }
 
     protected function extract($file, $path)

+ 2 - 2
src/Composer/Downloader/XzDownloader.php

@@ -30,11 +30,11 @@ class XzDownloader extends ArchiveDownloader
 {
     protected $process;
 
-    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null)
+    public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
     {
         $this->process = $process ?: new ProcessExecutor($io);
 
-        parent::__construct($io, $config, $eventDispatcher, $cache, $downloader);
+        parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
     }
 
     protected function extract($file, $path)

+ 2 - 2
src/Composer/Downloader/ZipDownloader.php

@@ -36,10 +36,10 @@ class ZipDownloader extends ArchiveDownloader
     protected $process;
     private $zipArchiveObject;
 
-    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null, HttpDownloader $downloader = null)
+    public function __construct(IOInterface $io, Config $config, HttpDownloader $downloader, EventDispatcher $eventDispatcher = null, Cache $cache = null, ProcessExecutor $process = null)
     {
         $this->process = $process ?: new ProcessExecutor($io);
-        parent::__construct($io, $config, $eventDispatcher, $cache, $downloader);
+        parent::__construct($io, $config, $downloader, $eventDispatcher, $cache);
     }
 
     /**

+ 13 - 19
src/Composer/Factory.php

@@ -325,14 +325,14 @@ class Factory
             $io->loadConfiguration($config);
         }
 
-        $rfs = self::createHttpDownloader($io, $config);
+        $httpDownloader = self::createHttpDownloader($io, $config);
 
         // initialize event dispatcher
         $dispatcher = new EventDispatcher($composer, $io);
         $composer->setEventDispatcher($dispatcher);
 
         // initialize repository manager
-        $rm = RepositoryFactory::manager($io, $config, $dispatcher, $rfs);
+        $rm = RepositoryFactory::manager($io, $config, $httpDownloader, $dispatcher);
         $composer->setRepositoryManager($rm);
 
         // load local repository
@@ -357,7 +357,7 @@ class Factory
 
         if ($fullLoad) {
             // initialize download manager
-            $dm = $this->createDownloadManager($io, $config, $dispatcher, $rfs);
+            $dm = $this->createDownloadManager($io, $config, $httpDownloader, $dispatcher);
             $composer->setDownloadManager($dm);
 
             // initialize autoload generator
@@ -451,7 +451,7 @@ class Factory
      * @param  EventDispatcher            $eventDispatcher
      * @return Downloader\DownloadManager
      */
-    public function createDownloadManager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null)
+    public function createDownloadManager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
     {
         $cache = null;
         if ($config->get('cache-files-ttl') > 0) {
@@ -484,14 +484,14 @@ class Factory
         $dm->setDownloader('fossil', new Downloader\FossilDownloader($io, $config, $executor, $fs));
         $dm->setDownloader('hg', new Downloader\HgDownloader($io, $config, $executor, $fs));
         $dm->setDownloader('perforce', new Downloader\PerforceDownloader($io, $config));
-        $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
-        $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
-        $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $eventDispatcher, $cache, $rfs));
-        $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
-        $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $eventDispatcher, $cache, $executor, $rfs));
-        $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $eventDispatcher, $cache, $rfs));
-        $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $eventDispatcher, $cache, $rfs));
-        $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $eventDispatcher, $cache, $rfs));
+        $dm->setDownloader('zip', new Downloader\ZipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
+        $dm->setDownloader('rar', new Downloader\RarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
+        $dm->setDownloader('tar', new Downloader\TarDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
+        $dm->setDownloader('gzip', new Downloader\GzipDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
+        $dm->setDownloader('xz', new Downloader\XzDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $executor));
+        $dm->setDownloader('phar', new Downloader\PharDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
+        $dm->setDownloader('file', new Downloader\FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
+        $dm->setDownloader('path', new Downloader\PathDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache));
 
         return $dm;
     }
@@ -501,14 +501,8 @@ class Factory
      * @param  Downloader\DownloadManager $dm     Manager use to download sources
      * @return Archiver\ArchiveManager
      */
-    public function createArchiveManager(Config $config, Downloader\DownloadManager $dm = null)
+    public function createArchiveManager(Config $config, Downloader\DownloadManager $dm)
     {
-        if (null === $dm) {
-            $io = new IO\NullIO();
-            $io->loadConfiguration($config);
-            $dm = $this->createDownloadManager($io, $config);
-        }
-
         $am = new Archiver\ArchiveManager($dm);
         $am->addArchiver(new Archiver\ZipArchiver);
         $am->addArchiver(new Archiver\PharArchiver);

+ 1 - 2
src/Composer/Package/Loader/ArrayLoader.php

@@ -18,7 +18,6 @@ use Composer\Package\Link;
 use Composer\Package\RootAliasPackage;
 use Composer\Package\RootPackageInterface;
 use Composer\Package\Version\VersionParser;
-use Composer\Semver\VersionParser as SemverVersionParser;
 
 /**
  * @author Konstantin Kudryashiv <ever.zet@gmail.com>
@@ -29,7 +28,7 @@ class ArrayLoader implements LoaderInterface
     protected $versionParser;
     protected $loadOptions;
 
-    public function __construct(SemverVersionParser $parser = null, $loadOptions = false)
+    public function __construct(VersionParser $parser = null, $loadOptions = false)
     {
         if (!$parser) {
             $parser = new VersionParser;

+ 16 - 1
src/Composer/Repository/ComposerRepository.php

@@ -102,7 +102,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
         $this->versionParser = new VersionParser();
         $this->loader = new ArrayLoader($this->versionParser);
         if ($httpDownloader && $this->options) {
-            // TODO solve this somehow - should be sent a request time not on the instance
+            // TODO solve this somehow - should be sent at request time not on the instance
             $httpDownloader = clone $httpDownloader;
             $httpDownloader->setOptions($this->options);
         }
@@ -543,6 +543,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
                             $response = $contents;
                         }
 
+                        if (!isset($response['packages'][$name])) {
+                            return;
+                        }
+
                         $uniqKeys = array('version', 'version_normalized', 'source', 'dist', 'time');
                         foreach ($response['packages'][$name] as $version) {
                             if (isset($version['versions'])) {
@@ -566,6 +570,7 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
                     }, function ($e) {
                         // TODO use ->done() above instead with react/promise 2.0
                         var_dump('Uncaught Ex', $e->getMessage());
+                        throw $e;
                     });
             }
         }
@@ -644,6 +649,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
             $this->hasProviders = true;
         }
 
+        // TODO this is for testing only, remove once packagist reports v2 protocol support
+        if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url)) {
+            $this->repoConfig['force-lazy-providers'] = true;
+        }
+
         // force values for packagist
         if (preg_match('{^https?://repo\.packagist\.org/?$}i', $this->url) && !empty($this->repoConfig['force-lazy-providers'])) {
             $this->url = 'https://repo.packagist.org';
@@ -927,6 +937,11 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
         $degradedMode =& $this->degradedMode;
 
         $accept = function ($response) use ($io, $url, $cache, $cacheKey) {
+            // package not found is acceptable for a v2 protocol repository
+            if ($response->getStatusCode() === 404) {
+                return array('packages' => array());
+            }
+
             $json = $response->getBody();
             if ($json === '' && $response->getStatusCode() === 304) {
                 return true;

+ 10 - 6
src/Composer/Repository/Pear/BaseChannelReader.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Repository\Pear;
 
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
 
 /**
  * Base PEAR Channel reader.
@@ -33,12 +33,12 @@ abstract class BaseChannelReader
     const ALL_RELEASES_NS = 'http://pear.php.net/dtd/rest.allreleases';
     const PACKAGE_INFO_NS = 'http://pear.php.net/dtd/rest.package';
 
-    /** @var RemoteFilesystem */
-    private $rfs;
+    /** @var HttpDownloader */
+    private $httpDownloader;
 
-    protected function __construct(RemoteFilesystem $rfs)
+    protected function __construct(HttpDownloader $httpDownloader)
     {
-        $this->rfs = $rfs;
+        $this->httpDownloader = $httpDownloader;
     }
 
     /**
@@ -52,7 +52,11 @@ abstract class BaseChannelReader
     protected function requestContent($origin, $path)
     {
         $url = rtrim($origin, '/') . '/' . ltrim($path, '/');
-        $content = $this->rfs->getContents($origin, $url, false);
+        try {
+            $content = $this->httpDownloader->get($url)->getBody();
+        } catch (\Exception $e) {
+            throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.', 0, $e);
+        }
         if (!$content) {
             throw new \UnexpectedValueException('The PEAR channel at ' . $url . ' did not respond.');
         }

+ 5 - 5
src/Composer/Repository/Pear/ChannelReader.php

@@ -12,7 +12,7 @@
 
 namespace Composer\Repository\Pear;
 
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
 
 /**
  * PEAR Channel package reader.
@@ -26,12 +26,12 @@ class ChannelReader extends BaseChannelReader
     /** @var array of ('xpath test' => 'rest implementation') */
     private $readerMap;
 
-    public function __construct(RemoteFilesystem $rfs)
+    public function __construct(HttpDownloader $httpDownloader)
     {
-        parent::__construct($rfs);
+        parent::__construct($httpDownloader);
 
-        $rest10reader = new ChannelRest10Reader($rfs);
-        $rest11reader = new ChannelRest11Reader($rfs);
+        $rest10reader = new ChannelRest10Reader($httpDownloader);
+        $rest11reader = new ChannelRest11Reader($httpDownloader);
 
         $this->readerMap = array(
             'REST1.3' => $rest11reader,

+ 3 - 2
src/Composer/Repository/Pear/ChannelRest10Reader.php

@@ -13,6 +13,7 @@
 namespace Composer\Repository\Pear;
 
 use Composer\Downloader\TransportException;
+use Composer\Util\HttpDownloader;
 
 /**
  * Read PEAR packages using REST 1.0 interface
@@ -29,9 +30,9 @@ class ChannelRest10Reader extends BaseChannelReader
 {
     private $dependencyReader;
 
-    public function __construct($rfs)
+    public function __construct(HttpDownloader $httpDownloader)
     {
-        parent::__construct($rfs);
+        parent::__construct($httpDownloader);
 
         $this->dependencyReader = new PackageDependencyParser();
     }

+ 4 - 2
src/Composer/Repository/Pear/ChannelRest11Reader.php

@@ -12,6 +12,8 @@
 
 namespace Composer\Repository\Pear;
 
+use Composer\Util\HttpDownloader;
+
 /**
  * Read PEAR packages using REST 1.1 interface
  *
@@ -25,9 +27,9 @@ class ChannelRest11Reader extends BaseChannelReader
 {
     private $dependencyReader;
 
-    public function __construct($rfs)
+    public function __construct(HttpDownloader $httpDownloader)
     {
-        parent::__construct($rfs);
+        parent::__construct($httpDownloader);
 
         $this->dependencyReader = new PackageDependencyParser();
     }

+ 5 - 5
src/Composer/Repository/PearRepository.php

@@ -21,7 +21,7 @@ use Composer\Repository\Pear\ChannelInfo;
 use Composer\EventDispatcher\EventDispatcher;
 use Composer\Package\Link;
 use Composer\Semver\Constraint\Constraint;
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
 use Composer\Config;
 use Composer\Factory;
 
@@ -38,7 +38,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
 {
     private $url;
     private $io;
-    private $rfs;
+    private $httpDownloader;
     private $versionParser;
     private $repoConfig;
 
@@ -47,7 +47,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
      */
     private $vendorAlias;
 
-    public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher = null, RemoteFilesystem $rfs = null)
+    public function __construct(array $repoConfig, IOInterface $io, Config $config, EventDispatcher $dispatcher, HttpDownloader $httpDownloader)
     {
         parent::__construct();
         if (!preg_match('{^https?://}', $repoConfig['url'])) {
@@ -61,7 +61,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
 
         $this->url = rtrim($repoConfig['url'], '/');
         $this->io = $io;
-        $this->rfs = $rfs ?: Factory::createRemoteFilesystem($this->io, $config);
+        $this->httpDownloader = $httpDownloader;
         $this->vendorAlias = isset($repoConfig['vendor-alias']) ? $repoConfig['vendor-alias'] : null;
         $this->versionParser = new VersionParser();
         $this->repoConfig = $repoConfig;
@@ -78,7 +78,7 @@ class PearRepository extends ArrayRepository implements ConfigurableRepositoryIn
 
         $this->io->writeError('Initializing PEAR repository '.$this->url);
 
-        $reader = new ChannelReader($this->rfs);
+        $reader = new ChannelReader($this->httpDownloader);
         try {
             $channelInfo = $reader->read($this->url);
         } catch (\Exception $e) {

+ 3 - 3
src/Composer/Repository/RepositoryFactory.php

@@ -108,12 +108,12 @@ class RepositoryFactory
      * @param  IOInterface       $io
      * @param  Config            $config
      * @param  EventDispatcher   $eventDispatcher
-     * @param  HttpDownloader  $rfs
+     * @param  HttpDownloader    $httpDownloader
      * @return RepositoryManager
      */
-    public static function manager(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null)
+    public static function manager(IOInterface $io, Config $config, HttpDownloader $httpDownloader, EventDispatcher $eventDispatcher = null)
     {
-        $rm = new RepositoryManager($io, $config, $eventDispatcher, $rfs);
+        $rm = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader);
         $rm->setRepositoryClass('composer', 'Composer\Repository\ComposerRepository');
         $rm->setRepositoryClass('vcs', 'Composer\Repository\VcsRepository');
         $rm->setRepositoryClass('package', 'Composer\Repository\PackageRepository');

+ 4 - 4
src/Composer/Repository/RepositoryManager.php

@@ -33,14 +33,14 @@ class RepositoryManager
     private $io;
     private $config;
     private $eventDispatcher;
-    private $rfs;
+    private $httpDownloader;
 
-    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher = null, HttpDownloader $rfs = null)
+    public function __construct(IOInterface $io, Config $config, EventDispatcher $eventDispatcher, HttpDownloader $httpDownloader)
     {
         $this->io = $io;
         $this->config = $config;
         $this->eventDispatcher = $eventDispatcher;
-        $this->rfs = $rfs;
+        $this->httpDownloader = $httpDownloader;
     }
 
     /**
@@ -128,7 +128,7 @@ class RepositoryManager
         $reflMethod = new \ReflectionMethod($class, '__construct');
         $params = $reflMethod->getParameters();
         if (isset($params[4]) && $params[4]->getClass() && $params[4]->getClass()->getName() === 'Composer\Util\HttpDownloader') {
-            return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->rfs);
+            return new $class($config, $this->io, $this->config, $this->eventDispatcher, $this->httpDownloader);
         }
 
         return new $class($config, $this->io, $this->config, $this->eventDispatcher);

+ 15 - 10
src/Composer/Repository/Vcs/BitbucketDriver.php

@@ -16,6 +16,7 @@ use Composer\Cache;
 use Composer\Downloader\TransportException;
 use Composer\Json\JsonFile;
 use Composer\Util\Bitbucket;
+use Composer\Util\Http\Response;
 
 abstract class BitbucketDriver extends VcsDriver
 {
@@ -92,7 +93,7 @@ abstract class BitbucketDriver extends VcsDriver
             )
         );
 
-        $repoData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource, true), $resource);
+        $repoData = $this->fetchWithOAuthCredentials($resource, true)->decodeJson();
         if ($this->fallbackDriver) {
             return false;
         }
@@ -204,7 +205,7 @@ abstract class BitbucketDriver extends VcsDriver
             $file
         );
 
-        return $this->getContentsWithOAuthCredentials($resource);
+        return $this->fetchWithOAuthCredentials($resource)->getBody();
     }
 
     /**
@@ -222,7 +223,7 @@ abstract class BitbucketDriver extends VcsDriver
             $this->repository,
             $identifier
         );
-        $commit = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
+        $commit = $this->fetchWithOAuthCredentials($resource)->decodeJson();
 
         return new \DateTime($commit['date']);
     }
@@ -284,7 +285,7 @@ abstract class BitbucketDriver extends VcsDriver
             );
             $hasNext = true;
             while ($hasNext) {
-                $tagsData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
+                $tagsData = $this->fetchWithOAuthCredentials($resource)->decodeJson();
                 foreach ($tagsData['values'] as $data) {
                     $this->tags[$data['name']] = $data['target']['hash'];
                 }
@@ -328,7 +329,7 @@ abstract class BitbucketDriver extends VcsDriver
             );
             $hasNext = true;
             while ($hasNext) {
-                $branchData = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
+                $branchData = $this->fetchWithOAuthCredentials($resource)->decodeJson();
                 foreach ($branchData['values'] as $data) {
                     // skip headless branches which seem to be deleted branches that bitbucket nevertheless returns in the API
                     if ($this->vcsType === 'hg' && empty($data['heads'])) {
@@ -354,14 +355,14 @@ abstract class BitbucketDriver extends VcsDriver
      * @param string $url              The URL of content
      * @param bool   $fetchingRepoData
      *
-     * @return mixed The result
+     * @return Response The result
      */
-    protected function getContentsWithOAuthCredentials($url, $fetchingRepoData = false)
+    protected function fetchWithOAuthCredentials($url, $fetchingRepoData = false)
     {
         try {
             return parent::getContents($url);
         } catch (TransportException $e) {
-            $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->remoteFilesystem);
+            $bitbucketUtil = new Bitbucket($this->io, $this->config, $this->process, $this->httpDownloader);
 
             if (403 === $e->getCode() || (401 === $e->getCode() && strpos($e->getMessage(), 'Could not authenticate against') === 0)) {
                 if (!$this->io->hasAuthentication($this->originUrl)
@@ -371,7 +372,9 @@ abstract class BitbucketDriver extends VcsDriver
                 }
 
                 if (!$this->io->isInteractive() && $fetchingRepoData) {
-                    return $this->attemptCloneFallback();
+                    if ($this->attemptCloneFallback()) {
+                        return new Response(array('url' => 'dummy'), 200, array(), 'null');
+                    }
                 }
             }
 
@@ -390,6 +393,8 @@ abstract class BitbucketDriver extends VcsDriver
     {
         try {
             $this->setupFallbackDriver($this->generateSshUrl());
+
+            return true;
         } catch (\RuntimeException $e) {
             $this->fallbackDriver = null;
 
@@ -433,7 +438,7 @@ abstract class BitbucketDriver extends VcsDriver
             $this->repository
         );
 
-        $data = JsonFile::parseJson($this->getContentsWithOAuthCredentials($resource), $resource);
+        $data = $this->fetchWithOAuthCredentials($resource)->decodeJson();
         if (isset($data['mainbranch'])) {
             return $data['mainbranch'];
         }

+ 1 - 1
src/Composer/Repository/Vcs/GitBitbucketDriver.php

@@ -76,7 +76,7 @@ class GitBitbucketDriver extends BitbucketDriver
             $this->io,
             $this->config,
             $this->process,
-            $this->remoteFilesystem
+            $this->httpDownloader
         );
         $this->fallbackDriver->initialize();
     }

+ 29 - 24
src/Composer/Repository/Vcs/GitHubDriver.php

@@ -18,6 +18,8 @@ use Composer\Json\JsonFile;
 use Composer\Cache;
 use Composer\IO\IOInterface;
 use Composer\Util\GitHub;
+use Composer\Util\Http\Response;
+use Composer\Util\RemoteFilesystem;
 
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
@@ -184,7 +186,7 @@ class GitHubDriver extends VcsDriver
         }
 
         $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/contents/' . $file . '?ref='.urlencode($identifier);
-        $resource = JsonFile::parseJson($this->getContents($resource));
+        $resource = $this->getContents($resource)->decodeJson();
         if (empty($resource['content']) || $resource['encoding'] !== 'base64' || !($content = base64_decode($resource['content']))) {
             throw new \RuntimeException('Could not retrieve ' . $file . ' for '.$identifier);
         }
@@ -202,7 +204,7 @@ class GitHubDriver extends VcsDriver
         }
 
         $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/commits/'.urlencode($identifier);
-        $commit = JsonFile::parseJson($this->getContents($resource), $resource);
+        $commit = $this->getContents($resource)->decodeJson();
 
         return new \DateTime($commit['commit']['committer']['date']);
     }
@@ -220,12 +222,13 @@ class GitHubDriver extends VcsDriver
             $resource = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository.'/tags?per_page=100';
 
             do {
-                $tagsData = JsonFile::parseJson($this->getContents($resource), $resource);
+                $response = $this->getContents($resource);
+                $tagsData = $response->decodeJson();
                 foreach ($tagsData as $tag) {
                     $this->tags[$tag['name']] = $tag['commit']['sha'];
                 }
 
-                $resource = $this->getNextPage();
+                $resource = $this->getNextPage($response);
             } while ($resource);
         }
 
@@ -247,7 +250,8 @@ class GitHubDriver extends VcsDriver
             $branchBlacklist = array('gh-pages');
 
             do {
-                $branchData = JsonFile::parseJson($this->getContents($resource), $resource);
+                $response = $this->getContents($resource);
+                $branchData = $response->decodeJson();
                 foreach ($branchData as $branch) {
                     $name = substr($branch['ref'], 11);
                     if (!in_array($name, $branchBlacklist)) {
@@ -255,7 +259,7 @@ class GitHubDriver extends VcsDriver
                     }
                 }
 
-                $resource = $this->getNextPage();
+                $resource = $this->getNextPage($response);
             } while ($resource);
         }
 
@@ -315,7 +319,7 @@ class GitHubDriver extends VcsDriver
         try {
             return parent::getContents($url);
         } catch (TransportException $e) {
-            $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->remoteFilesystem);
+            $gitHubUtil = new GitHub($this->io, $this->config, $this->process, $this->httpDownloader);
 
             switch ($e->getCode()) {
                 case 401:
@@ -330,16 +334,18 @@ class GitHubDriver extends VcsDriver
                     }
 
                     if (!$this->io->isInteractive()) {
-                        return $this->attemptCloneFallback();
+                        if ($this->attemptCloneFallback()) {
+                            return new Response(array('url' => 'dummy'), 200, array(), 'null');
+                        }
                     }
 
                     $scopesIssued = array();
                     $scopesNeeded = array();
                     if ($headers = $e->getHeaders()) {
-                        if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-OAuth-Scopes')) {
+                        if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-OAuth-Scopes')) {
                             $scopesIssued = explode(' ', $scopes);
                         }
-                        if ($scopes = $this->remoteFilesystem->findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
+                        if ($scopes = RemoteFilesystem::findHeaderValue($headers, 'X-Accepted-OAuth-Scopes')) {
                             $scopesNeeded = explode(' ', $scopes);
                         }
                     }
@@ -358,7 +364,9 @@ class GitHubDriver extends VcsDriver
                     }
 
                     if (!$this->io->isInteractive() && $fetchingRepoData) {
-                        return $this->attemptCloneFallback();
+                        if ($this->attemptCloneFallback()) {
+                            return new Response(array('url' => 'dummy'), 200, array(), 'null');
+                        }
                     }
 
                     $rateLimited = $gitHubUtil->isRateLimited($e->getHeaders());
@@ -404,7 +412,7 @@ class GitHubDriver extends VcsDriver
 
         $repoDataUrl = $this->getApiUrl() . '/repos/'.$this->owner.'/'.$this->repository;
 
-        $this->repoData = JsonFile::parseJson($this->getContents($repoDataUrl, true), $repoDataUrl);
+        $this->repoData = $this->getContents($repoDataUrl, true)->decodeJson();
         if (null === $this->repoData && null !== $this->gitDriver) {
             return;
         }
@@ -434,7 +442,7 @@ class GitHubDriver extends VcsDriver
             // are not interactive) then we fallback to GitDriver.
             $this->setupGitDriver($this->generateSshUrl());
 
-            return;
+            return true;
         } catch (\RuntimeException $e) {
             $this->gitDriver = null;
 
@@ -450,22 +458,19 @@ class GitHubDriver extends VcsDriver
             $this->io,
             $this->config,
             $this->process,
-            $this->remoteFilesystem
+            $this->httpDownloader
         );
         $this->gitDriver->initialize();
     }
 
-    protected function getNextPage()
+    protected function getNextPage(Response $response)
     {
-        $headers = $this->remoteFilesystem->getLastHeaders();
-        foreach ($headers as $header) {
-            if (preg_match('{^link:\s*(.+?)\s*$}i', $header, $match)) {
-                $links = explode(',', $match[1]);
-                foreach ($links as $link) {
-                    if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
-                        return $match[1];
-                    }
-                }
+        $header = $response->getHeader('link');
+
+        $links = explode(',', $header);
+        foreach ($links as $link) {
+            if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
+                return $match[1];
             }
         }
     }

+ 29 - 26
src/Composer/Repository/Vcs/GitLabDriver.php

@@ -17,8 +17,9 @@ use Composer\Cache;
 use Composer\IO\IOInterface;
 use Composer\Json\JsonFile;
 use Composer\Downloader\TransportException;
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
 use Composer\Util\GitLab;
+use Composer\Util\Http\Response;
 
 /**
  * Driver for GitLab API, use the Git driver for local checkouts.
@@ -110,14 +111,14 @@ class GitLabDriver extends VcsDriver
     }
 
     /**
-     * Updates the RemoteFilesystem instance.
+     * Updates the HttpDownloader instance.
      * Mainly useful for tests.
      *
      * @internal
      */
-    public function setRemoteFilesystem(RemoteFilesystem $remoteFilesystem)
+    public function setHttpDownloader(HttpDownloader $httpDownloader)
     {
-        $this->remoteFilesystem = $remoteFilesystem;
+        $this->httpDownloader = $httpDownloader;
     }
 
     /**
@@ -140,7 +141,7 @@ class GitLabDriver extends VcsDriver
         $resource = $this->getApiUrl().'/repository/files/'.$this->urlEncodeAll($file).'/raw?ref='.$identifier;
 
         try {
-            $content = $this->getContents($resource);
+            $content = $this->getContents($resource)->getBody();
         } catch (TransportException $e) {
             if ($e->getCode() !== 404) {
                 throw $e;
@@ -297,7 +298,8 @@ class GitLabDriver extends VcsDriver
 
         $references = array();
         do {
-            $data = JsonFile::parseJson($this->getContents($resource), $resource);
+            $response = $this->getContents($resource);
+            $data = $response->decodeJson();
 
             foreach ($data as $datum) {
                 $references[$datum['name']] = $datum['commit']['id'];
@@ -308,7 +310,7 @@ class GitLabDriver extends VcsDriver
             }
 
             if (count($data) >= $perPage) {
-                $resource = $this->getNextPage();
+                $resource = $this->getNextPage($response);
             } else {
                 $resource = false;
             }
@@ -321,7 +323,7 @@ class GitLabDriver extends VcsDriver
     {
         // we need to fetch the default branch from the api
         $resource = $this->getApiUrl();
-        $this->project = JsonFile::parseJson($this->getContents($resource, true), $resource);
+        $this->project = $this->getContents($resource, true)->decodeJson();
         if (isset($this->project['visibility'])) {
             $this->isPrivate = $this->project['visibility'] !== 'public';
         } else {
@@ -344,7 +346,7 @@ class GitLabDriver extends VcsDriver
             // are not interactive) then we fallback to GitDriver.
             $this->setupGitDriver($url);
 
-            return;
+            return true;
         } catch (\RuntimeException $e) {
             $this->gitDriver = null;
 
@@ -375,7 +377,7 @@ class GitLabDriver extends VcsDriver
             $this->io,
             $this->config,
             $this->process,
-            $this->remoteFilesystem
+            $this->httpDownloader
         );
         $this->gitDriver->initialize();
     }
@@ -386,10 +388,10 @@ class GitLabDriver extends VcsDriver
     protected function getContents($url, $fetchingRepoData = false)
     {
         try {
-            $res = parent::getContents($url);
+            $response = parent::getContents($url);
 
             if ($fetchingRepoData) {
-                $json = JsonFile::parseJson($res, $url);
+                $json = $response->decodeJson();
 
                 // force auth as the unauthenticated version of the API is broken
                 if (!isset($json['default_branch'])) {
@@ -401,9 +403,9 @@ class GitLabDriver extends VcsDriver
                 }
             }
 
-            return $res;
+            return $response;
         } catch (TransportException $e) {
-            $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->remoteFilesystem);
+            $gitLabUtil = new GitLab($this->io, $this->config, $this->process, $this->httpDownloader);
 
             switch ($e->getCode()) {
                 case 401:
@@ -418,7 +420,9 @@ class GitLabDriver extends VcsDriver
                     }
 
                     if (!$this->io->isInteractive()) {
-                        return $this->attemptCloneFallback();
+                        if ($this->attemptCloneFallback()) {
+                            return new Response(array('url' => 'dummy'), 200, array(), 'null');
+                        }
                     }
                     $this->io->writeError('<warning>Failed to download ' . $this->namespace . '/' . $this->repository . ':' . $e->getMessage() . '</warning>');
                     $gitLabUtil->authorizeOAuthInteractively($this->scheme, $this->originUrl, 'Your credentials are required to fetch private repository metadata (<info>'.$this->url.'</info>)');
@@ -431,7 +435,9 @@ class GitLabDriver extends VcsDriver
                     }
 
                     if (!$this->io->isInteractive() && $fetchingRepoData) {
-                        return $this->attemptCloneFallback();
+                        if ($this->attemptCloneFallback()) {
+                            return new Response(array('url' => 'dummy'), 200, array(), 'null');
+                        }
                     }
 
                     throw $e;
@@ -471,17 +477,14 @@ class GitLabDriver extends VcsDriver
         return true;
     }
 
-    private function getNextPage()
+    protected function getNextPage(Response $response)
     {
-        $headers = $this->remoteFilesystem->getLastHeaders();
-        foreach ($headers as $header) {
-            if (preg_match('{^link:\s*(.+?)\s*$}i', $header, $match)) {
-                $links = explode(',', $match[1]);
-                foreach ($links as $link) {
-                    if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
-                        return $match[1];
-                    }
-                }
+        $header = $response->getHeader('link');
+
+        $links = explode(',', $header);
+        foreach ($links as $link) {
+            if (preg_match('{<(.+?)>; *rel="next"}', $link, $match)) {
+                return $match[1];
             }
         }
     }

+ 1 - 1
src/Composer/Repository/Vcs/HgBitbucketDriver.php

@@ -76,7 +76,7 @@ class HgBitbucketDriver extends BitbucketDriver
             $this->io,
             $this->config,
             $this->process,
-            $this->remoteFilesystem
+            $this->httpDownloader
         );
         $this->fallbackDriver->initialize();
     }

+ 9 - 8
src/Composer/Repository/Vcs/VcsDriver.php

@@ -19,8 +19,9 @@ use Composer\Factory;
 use Composer\IO\IOInterface;
 use Composer\Json\JsonFile;
 use Composer\Util\ProcessExecutor;
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
 use Composer\Util\Filesystem;
+use Composer\Util\Http\Response;
 
 /**
  * A driver implementation for driver with authentication interaction.
@@ -41,8 +42,8 @@ abstract class VcsDriver implements VcsDriverInterface
     protected $config;
     /** @var ProcessExecutor */
     protected $process;
-    /** @var RemoteFilesystem */
-    protected $remoteFilesystem;
+    /** @var HttpDownloader */
+    protected $httpDownloader;
     /** @var array */
     protected $infoCache = array();
     /** @var Cache */
@@ -55,9 +56,9 @@ abstract class VcsDriver implements VcsDriverInterface
      * @param IOInterface      $io               The IO instance
      * @param Config           $config           The composer configuration
      * @param ProcessExecutor  $process          Process instance, injectable for mocking
-     * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking
+     * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
      */
-    final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
+    final public function __construct(array $repoConfig, IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
     {
         if (Filesystem::isLocalPath($repoConfig['url'])) {
             $repoConfig['url'] = Filesystem::getPlatformPath($repoConfig['url']);
@@ -69,7 +70,7 @@ abstract class VcsDriver implements VcsDriverInterface
         $this->io = $io;
         $this->config = $config;
         $this->process = $process ?: new ProcessExecutor($io);
-        $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
+        $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
     }
 
     /**
@@ -156,13 +157,13 @@ abstract class VcsDriver implements VcsDriverInterface
      *
      * @param string $url The URL of content
      *
-     * @return mixed The result
+     * @return Response
      */
     protected function getContents($url)
     {
         $options = isset($this->repoConfig['options']) ? $this->repoConfig['options'] : array();
 
-        return $this->remoteFilesystem->getContents($this->originUrl, $url, false, $options);
+        return $this->httpDownloader->get($url, $options);
     }
 
     /**

+ 6 - 6
src/Composer/Util/Bitbucket.php

@@ -25,7 +25,7 @@ class Bitbucket
     private $io;
     private $config;
     private $process;
-    private $remoteFilesystem;
+    private $httpDownloader;
     private $token = array();
     private $time;
 
@@ -37,15 +37,15 @@ class Bitbucket
      * @param IOInterface      $io               The IO instance
      * @param Config           $config           The composer configuration
      * @param ProcessExecutor  $process          Process instance, injectable for mocking
-     * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking
+     * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
      * @param int              $time             Timestamp, injectable for mocking
      */
-    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null, $time = null)
+    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null, $time = null)
     {
         $this->io = $io;
         $this->config = $config;
         $this->process = $process ?: new ProcessExecutor($io);
-        $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
+        $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
         $this->time = $time;
     }
 
@@ -90,7 +90,7 @@ class Bitbucket
     private function requestAccessToken($originUrl)
     {
         try {
-            $json = $this->remoteFilesystem->getContents($originUrl, self::OAUTH2_ACCESS_TOKEN_URL, false, array(
+            $response = $this->httpDownloader->get(self::OAUTH2_ACCESS_TOKEN_URL, array(
                 'retry-auth-failure' => false,
                 'http' => array(
                     'method' => 'POST',
@@ -98,7 +98,7 @@ class Bitbucket
                 ),
             ));
 
-            $this->token = json_decode($json, true);
+            $this->token = $response->decodeJson();
         } catch (TransportException $e) {
             if ($e->getCode() === 400) {
                 $this->io->writeError('<error>Invalid OAuth consumer provided.</error>');

+ 5 - 5
src/Composer/Util/GitHub.php

@@ -25,7 +25,7 @@ class GitHub
     protected $io;
     protected $config;
     protected $process;
-    protected $remoteFilesystem;
+    protected $httpDownloader;
 
     /**
      * Constructor.
@@ -33,14 +33,14 @@ class GitHub
      * @param IOInterface      $io               The IO instance
      * @param Config           $config           The composer configuration
      * @param ProcessExecutor  $process          Process instance, injectable for mocking
-     * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking
+     * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
      */
-    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
+    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
     {
         $this->io = $io;
         $this->config = $config;
         $this->process = $process ?: new ProcessExecutor($io);
-        $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
+        $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
     }
 
     /**
@@ -104,7 +104,7 @@ class GitHub
         try {
             $apiUrl = ('github.com' === $originUrl) ? 'api.github.com/' : $originUrl . '/api/v3/';
 
-            $this->remoteFilesystem->getContents($originUrl, 'https://'. $apiUrl, false, array(
+            $this->httpDownloader->get('https://'. $apiUrl, array(
                 'retry-auth-failure' => false,
             ));
         } catch (TransportException $e) {

+ 6 - 6
src/Composer/Util/GitLab.php

@@ -26,7 +26,7 @@ class GitLab
     protected $io;
     protected $config;
     protected $process;
-    protected $remoteFilesystem;
+    protected $httpDownloader;
 
     /**
      * Constructor.
@@ -34,14 +34,14 @@ class GitLab
      * @param IOInterface      $io               The IO instance
      * @param Config           $config           The composer configuration
      * @param ProcessExecutor  $process          Process instance, injectable for mocking
-     * @param RemoteFilesystem $remoteFilesystem Remote Filesystem, injectable for mocking
+     * @param HttpDownloader $httpDownloader Remote Filesystem, injectable for mocking
      */
-    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, RemoteFilesystem $remoteFilesystem = null)
+    public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, HttpDownloader $httpDownloader = null)
     {
         $this->io = $io;
         $this->config = $config;
         $this->process = $process ?: new ProcessExecutor($io);
-        $this->remoteFilesystem = $remoteFilesystem ?: Factory::createRemoteFilesystem($this->io, $config);
+        $this->httpDownloader = $httpDownloader ?: Factory::createHttpDownloader($this->io, $config);
     }
 
     /**
@@ -154,10 +154,10 @@ class GitLab
             ),
         );
 
-        $json = $this->remoteFilesystem->getContents($originUrl, $scheme.'://'.$apiUrl.'/oauth/token', false, $options);
+        $token = $this->httpDownloader->get($scheme.'://'.$apiUrl.'/oauth/token', $options)->decodeJson();
 
         $this->io->writeError('Token successfully created');
 
-        return JsonFile::parseJson($json);
+        return $token;
     }
 }

+ 3 - 0
src/Composer/Util/Http/Response.php

@@ -23,6 +23,9 @@ class Response
 
     public function __construct(array $request, $code, array $headers, $body)
     {
+        if (!isset($request['url'])) {
+            throw new \LogicException('url key missing from request array');
+        }
         $this->request = $request;
         $this->code = $code;
         $this->headers = $headers;

+ 3 - 7
src/Composer/Util/HttpDownloader.php

@@ -117,8 +117,8 @@ class HttpDownloader
 
         $origin = $this->getOrigin($job['request']['url']);
 
-        // TODO only send http/https through curl
-        if ($curl) {
+        // TODO experiment with allowing file:// through curl too
+        if ($curl && preg_match('{^https?://}i', $job['request']['url'])) {
             $resolver = function ($resolve, $reject) use (&$job, $curl, $origin) {
                 // start job
                 $url = $job['request']['url'];
@@ -141,11 +141,7 @@ class HttpDownloader
                 $job['status'] = HttpDownloader::STATUS_STARTED;
 
                 if ($job['request']['copyTo']) {
-                    if ($curl) {
-                        $result = $curl->download($origin, $url, $options, $job['request']['copyTo']);
-                    } else {
-                        $result = $rfs->copy($origin, $url, $job['request']['copyTo'], false /* TODO progress */, $options);
-                    }
+                    $result = $rfs->copy($origin, $url, $job['request']['copyTo'], false /* TODO progress */, $options);
 
                     $resolve($result);
                 } else {

+ 2 - 2
src/Composer/Util/RemoteFilesystem.php

@@ -147,7 +147,7 @@ class RemoteFilesystem
      * @param  string      $name    header name (case insensitive)
      * @return string|null
      */
-    public function findHeaderValue(array $headers, $name)
+    public static function findHeaderValue(array $headers, $name)
     {
         $value = null;
         foreach ($headers as $header) {
@@ -167,7 +167,7 @@ class RemoteFilesystem
      * @param  array    $headers array of returned headers like from getLastHeaders()
      * @return int|null
      */
-    public function findStatusCode(array $headers)
+    public static function findStatusCode(array $headers)
     {
         $value = null;
         foreach ($headers as $header) {

+ 5 - 1
tests/Composer/Test/Downloader/ArchiveDownloaderTest.php

@@ -156,7 +156,11 @@ class ArchiveDownloaderTest extends TestCase
     {
         return $this->getMockForAbstractClass(
             'Composer\Downloader\ArchiveDownloader',
-            array($this->getMockBuilder('Composer\IO\IOInterface')->getMock(), $this->getMockBuilder('Composer\Config')->getMock())
+            array(
+                $io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
+                $config = $this->getMockBuilder('Composer\Config')->getMock(),
+                new \Composer\Util\HttpDownloader($io, $config),
+            )
         );
     }
 }

+ 3 - 3
tests/Composer/Test/Downloader/FileDownloaderTest.php

@@ -18,13 +18,13 @@ use Composer\Util\Filesystem;
 
 class FileDownloaderTest extends TestCase
 {
-    protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $rfs = null, $filesystem = null)
+    protected function getDownloader($io = null, $config = null, $eventDispatcher = null, $cache = null, $httpDownloader = null, $filesystem = null)
     {
         $io = $io ?: $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
         $config = $config ?: $this->getMockBuilder('Composer\Config')->getMock();
-        $rfs = $rfs ?: $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock();
+        $httpDownloader = $httpDownloader ?: $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
 
-        return new FileDownloader($io, $config, $eventDispatcher, $cache, $rfs, $filesystem);
+        return new FileDownloader($io, $config, $httpDownloader, $eventDispatcher, $cache, $filesystem);
     }
 
     /**

+ 2 - 2
tests/Composer/Test/Downloader/XzDownloaderTest.php

@@ -16,7 +16,7 @@ use Composer\Downloader\XzDownloader;
 use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Composer\Util\Platform;
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
 
 class XzDownloaderTest extends TestCase
 {
@@ -66,7 +66,7 @@ class XzDownloaderTest extends TestCase
             ->method('get')
             ->with('vendor-dir')
             ->will($this->returnValue($this->testDir));
-        $downloader = new XzDownloader($io, $config, null, null, null, new RemoteFilesystem($io));
+        $downloader = new XzDownloader($io, $config, new HttpDownloader($io, $this->getMockBuilder('Composer\Config')->getMock()), null, null, null);
 
         try {
             $downloader->download($packageMock, $this->getUniqueTmpDirectory());

+ 13 - 25
tests/Composer/Test/Downloader/ZipDownloaderTest.php

@@ -16,6 +16,7 @@ use Composer\Downloader\ZipDownloader;
 use Composer\Package\PackageInterface;
 use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
+use Composer\Util\HttpDownloader;
 
 class ZipDownloaderTest extends TestCase
 {
@@ -32,6 +33,8 @@ class ZipDownloaderTest extends TestCase
         $this->testDir = $this->getUniqueTmpDirectory();
         $this->io = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
         $this->config = $this->getMockBuilder('Composer\Config')->getMock();
+        $dlConfig = $this->getMockBuilder('Composer\Config')->getMock();
+        $this->httpDownloader = new HttpDownloader($this->io, $dlConfig);
     }
 
     public function tearDown()
@@ -64,18 +67,6 @@ class ZipDownloaderTest extends TestCase
         }
 
         $this->config->expects($this->at(0))
-            ->method('get')
-            ->with('disable-tls')
-            ->will($this->returnValue(false));
-        $this->config->expects($this->at(1))
-            ->method('get')
-            ->with('cafile')
-            ->will($this->returnValue(null));
-        $this->config->expects($this->at(2))
-            ->method('get')
-            ->with('capath')
-            ->will($this->returnValue(null));
-        $this->config->expects($this->at(3))
             ->method('get')
             ->with('vendor-dir')
             ->will($this->returnValue($this->testDir));
@@ -94,7 +85,7 @@ class ZipDownloaderTest extends TestCase
             ->will($this->returnValue(array()))
         ;
 
-        $downloader = new ZipDownloader($this->io, $this->config);
+        $downloader = new ZipDownloader($this->io, $this->config, $this->httpDownloader);
 
         $this->setPrivateProperty('hasSystemUnzip', false);
 
@@ -118,8 +109,7 @@ class ZipDownloaderTest extends TestCase
 
         $this->setPrivateProperty('hasSystemUnzip', false);
         $this->setPrivateProperty('hasZipArchive', true);
-        $downloader = new MockedZipDownloader($this->io, $this->config);
-
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
         $zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
         $zipArchive->expects($this->at(0))
             ->method('open')
@@ -144,8 +134,7 @@ class ZipDownloaderTest extends TestCase
 
         $this->setPrivateProperty('hasSystemUnzip', false);
         $this->setPrivateProperty('hasZipArchive', true);
-        $downloader = new MockedZipDownloader($this->io, $this->config);
-
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
         $zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
         $zipArchive->expects($this->at(0))
             ->method('open')
@@ -169,8 +158,7 @@ class ZipDownloaderTest extends TestCase
 
         $this->setPrivateProperty('hasSystemUnzip', false);
         $this->setPrivateProperty('hasZipArchive', true);
-        $downloader = new MockedZipDownloader($this->io, $this->config);
-
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader);
         $zipArchive = $this->getMockBuilder('ZipArchive')->getMock();
         $zipArchive->expects($this->at(0))
             ->method('open')
@@ -200,7 +188,7 @@ class ZipDownloaderTest extends TestCase
             ->method('execute')
             ->will($this->returnValue(1));
 
-        $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor);
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
         $downloader->extract('testfile.zip', 'vendor/dir');
     }
 
@@ -217,7 +205,7 @@ class ZipDownloaderTest extends TestCase
             ->method('execute')
             ->will($this->returnValue(0));
 
-        $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor);
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
         $downloader->extract('testfile.zip', 'vendor/dir');
     }
 
@@ -244,7 +232,7 @@ class ZipDownloaderTest extends TestCase
             ->method('extractTo')
             ->will($this->returnValue(true));
 
-        $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor);
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
         $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
         $downloader->extract('testfile.zip', 'vendor/dir');
     }
@@ -276,7 +264,7 @@ class ZipDownloaderTest extends TestCase
           ->method('extractTo')
           ->will($this->returnValue(false));
 
-        $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor);
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
         $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
         $downloader->extract('testfile.zip', 'vendor/dir');
     }
@@ -304,7 +292,7 @@ class ZipDownloaderTest extends TestCase
             ->method('extractTo')
             ->will($this->returnValue(false));
 
-        $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor);
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
         $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
         $downloader->extract('testfile.zip', 'vendor/dir');
     }
@@ -336,7 +324,7 @@ class ZipDownloaderTest extends TestCase
           ->method('extractTo')
           ->will($this->returnValue(false));
 
-        $downloader = new MockedZipDownloader($this->io, $this->config, null, null, $processExecutor);
+        $downloader = new MockedZipDownloader($this->io, $this->config, $this->httpDownloader, null, null, $processExecutor);
         $this->setPrivateProperty('zipArchiveObject', $zipArchive, $downloader);
         $downloader->extract('testfile.zip', 'vendor/dir');
     }

+ 3 - 2
tests/Composer/Test/InstallerTest.php

@@ -63,7 +63,9 @@ class InstallerTest extends TestCase
             ->getMock();
         $config = $this->getMockBuilder('Composer\Config')->getMock();
 
-        $repositoryManager = new RepositoryManager($io, $config);
+        $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock();
+        $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
+        $repositoryManager = new RepositoryManager($io, $config, $eventDispatcher, $httpDownloader);
         $repositoryManager->setLocalRepository(new InstalledArrayRepository());
 
         if (!is_array($repositories)) {
@@ -76,7 +78,6 @@ class InstallerTest extends TestCase
         $locker = $this->getMockBuilder('Composer\Package\Locker')->disableOriginalConstructor()->getMock();
         $installationManager = new InstallationManagerMock();
 
-        $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock();
         $autoloadGenerator = $this->getMockBuilder('Composer\Autoload\AutoloadGenerator')->disableOriginalConstructor()->getMock();
 
         $installer = new Installer($io, $config, clone $rootPackage, $downloadManager, $repositoryManager, $locker, $installationManager, $eventDispatcher, $autoloadGenerator);

+ 5 - 7
tests/Composer/Test/Mock/RemoteFilesystemMock.php → tests/Composer/Test/Mock/HttpDownloaderMock.php

@@ -12,13 +12,11 @@
 
 namespace Composer\Test\Mock;
 
-use Composer\Util\RemoteFilesystem;
+use Composer\Util\HttpDownloader;
+use Composer\Util\Http\Response;
 use Composer\Downloader\TransportException;
 
-/**
- * Remote filesystem mock
- */
-class RemoteFilesystemMock extends RemoteFilesystem
+class HttpDownloaderMock extends HttpDownloader
 {
     protected $contentMap;
 
@@ -30,10 +28,10 @@ class RemoteFilesystemMock extends RemoteFilesystem
         $this->contentMap = $contentMap;
     }
 
-    public function getContents($originUrl, $fileUrl, $progress = true, $options = array())
+    public function get($fileUrl, $options = array())
     {
         if (!empty($this->contentMap[$fileUrl])) {
-            return $this->contentMap[$fileUrl];
+            return new Response(array('url' => $fileUrl), 200, array(), $this->contentMap[$fileUrl]);
         }
 
         throw new TransportException('The "'.$fileUrl.'" file could not be downloaded (NOT FOUND)', 404);

+ 8 - 1
tests/Composer/Test/Package/Archiver/ArchiveManagerTest.php

@@ -12,9 +12,11 @@
 
 namespace Composer\Test\Package\Archiver;
 
+use Composer\IO\NullIO;
 use Composer\Factory;
 use Composer\Package\Archiver\ArchiveManager;
 use Composer\Package\PackageInterface;
+use Composer\Test\Mock\FactoryMock;
 
 class ArchiveManagerTest extends ArchiverTest
 {
@@ -30,7 +32,12 @@ class ArchiveManagerTest extends ArchiverTest
         parent::setUp();
 
         $factory = new Factory();
-        $this->manager = $factory->createArchiveManager($factory->createConfig());
+        $dm = $factory->createDownloadManager(
+            $io = new NullIO,
+            $config = FactoryMock::createConfig(),
+            $factory->createHttpDownloader($io, $config)
+        );
+        $this->manager = $factory->createArchiveManager($factory->createConfig(), $dm);
         $this->targetDir = $this->testDir.'/composer_archiver_tests';
     }
 

+ 21 - 11
tests/Composer/Test/Repository/ComposerRepositoryTest.php

@@ -18,7 +18,7 @@ use Composer\Repository\RepositoryInterface;
 use Composer\Test\Mock\FactoryMock;
 use Composer\Test\TestCase;
 use Composer\Package\Loader\ArrayLoader;
-use Composer\Semver\VersionParser;
+use Composer\Package\Version\VersionParser;
 
 class ComposerRepositoryTest extends TestCase
 {
@@ -37,6 +37,8 @@ class ComposerRepositoryTest extends TestCase
                 $repoConfig,
                 new NullIO,
                 FactoryMock::createConfig(),
+                $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(),
+                $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock()
             ))
             ->getMock();
 
@@ -179,21 +181,29 @@ class ComposerRepositoryTest extends TestCase
             ),
         );
 
-        $rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
+        $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
             ->disableOriginalConstructor()
             ->getMock();
+        $eventDispatcher = $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $httpDownloader->expects($this->at(0))
+            ->method('get')
+            ->with($url = 'http://example.org/packages.json')
+            ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array('search' => '/search.json?q=%query%&type=%type%'))));
 
-        $rfs->expects($this->at(0))
-            ->method('getContents')
-            ->with('example.org', 'http://example.org/packages.json', false)
-            ->willReturn(json_encode(array('search' => '/search.json?q=%query%&type=%type%')));
+        $httpDownloader->expects($this->at(1))
+            ->method('get')
+            ->with($url = 'http://example.org/search.json?q=foo&type=composer-plugin')
+            ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode($result)));
 
-        $rfs->expects($this->at(1))
-            ->method('getContents')
-            ->with('example.org', 'http://example.org/search.json?q=foo&type=composer-plugin', false)
-            ->willReturn(json_encode($result));
+        $httpDownloader->expects($this->at(2))
+            ->method('get')
+            ->with($url = 'http://example.org/search.json?q=foo&type=library')
+            ->willReturn(new \Composer\Util\Http\Response(array('url' => $url), 200, array(), json_encode(array())));
 
-        $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), null, $rfs);
+        $repository = new ComposerRepository($repoConfig, new NullIO, FactoryMock::createConfig(), $eventDispatcher, $httpDownloader);
 
         $this->assertSame(
             array(array('name' => 'foo', 'description' => null)),

+ 1 - 1
tests/Composer/Test/Repository/PathRepositoryTest.php

@@ -14,8 +14,8 @@ namespace Composer\Test\Repository;
 
 use Composer\Package\Loader\ArrayLoader;
 use Composer\Repository\PathRepository;
-use Composer\Semver\VersionParser;
 use Composer\Test\TestCase;
+use Composer\Package\Version\VersionParser;
 
 class PathRepositoryTest extends TestCase
 {

+ 7 - 3
tests/Composer/Test/Repository/Pear/ChannelReaderTest.php

@@ -22,13 +22,13 @@ use Composer\Semver\VersionParser;
 use Composer\Semver\Constraint\Constraint;
 use Composer\Package\Link;
 use Composer\Package\CompletePackage;
-use Composer\Test\Mock\RemoteFilesystemMock;
+use Composer\Test\Mock\HttpDownloaderMock;
 
 class ChannelReaderTest extends TestCase
 {
     public function testShouldBuildPackagesFromPearSchema()
     {
-        $rfs = new RemoteFilesystemMock(array(
+        $rfs = new HttpDownloaderMock(array(
             'http://pear.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'),
             'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'),
             'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'),
@@ -50,11 +50,15 @@ class ChannelReaderTest extends TestCase
 
     public function testShouldSelectCorrectReader()
     {
-        $rfs = new RemoteFilesystemMock(array(
+        $rfs = new HttpDownloaderMock(array(
             'http://pear.1.0.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.0.xml'),
             'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'),
             'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'),
+            'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'),
+            'http://test.loc/rest10/r/http_client/deps.1.2.1.txt' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_deps.1.2.1.txt'),
             'http://test.loc/rest10/p/http_request/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_info.xml'),
+            'http://test.loc/rest10/r/http_request/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_allreleases.xml'),
+            'http://test.loc/rest10/r/http_request/deps.1.4.0.txt' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_request_deps.1.4.0.txt'),
             'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'),
             'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'),
             'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'),

+ 2 - 2
tests/Composer/Test/Repository/Pear/ChannelRest10ReaderTest.php

@@ -13,13 +13,13 @@
 namespace Composer\Test\Repository\Pear;
 
 use Composer\Test\TestCase;
-use Composer\Test\Mock\RemoteFilesystemMock;
+use Composer\Test\Mock\HttpDownloaderMock;
 
 class ChannelRest10ReaderTest extends TestCase
 {
     public function testShouldBuildPackagesFromPearSchema()
     {
-        $rfs = new RemoteFilesystemMock(array(
+        $rfs = new HttpDownloaderMock(array(
             'http://test.loc/rest10/p/packages.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/packages.xml'),
             'http://test.loc/rest10/p/http_client/info.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_info.xml'),
             'http://test.loc/rest10/r/http_client/allreleases.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.0/http_client_allreleases.xml'),

+ 2 - 2
tests/Composer/Test/Repository/Pear/ChannelRest11ReaderTest.php

@@ -13,13 +13,13 @@
 namespace Composer\Test\Repository\Pear;
 
 use Composer\Test\TestCase;
-use Composer\Test\Mock\RemoteFilesystemMock;
+use Composer\Test\Mock\HttpDownloaderMock;
 
 class ChannelRest11ReaderTest extends TestCase
 {
     public function testShouldBuildPackagesFromPearSchema()
     {
-        $rfs = new RemoteFilesystemMock(array(
+        $rfs = new HttpDownloaderMock(array(
             'http://pear.1.1.net/channel.xml' => file_get_contents(__DIR__ . '/Fixtures/channel.1.1.xml'),
             'http://test.loc/rest11/c/categories.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/categories.xml'),
             'http://test.loc/rest11/c/Default/packagesinfo.xml' => file_get_contents(__DIR__ . '/Fixtures/Rest1.1/packagesinfo.xml'),

+ 2 - 2
tests/Composer/Test/Repository/PearRepositoryTest.php

@@ -133,7 +133,7 @@ class PearRepositoryTest extends TestCase
 
         $config = new \Composer\Config();
 
-        $this->remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
+        $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
             ->disableOriginalConstructor()
             ->getMock();
 
@@ -143,6 +143,6 @@ class PearRepositoryTest extends TestCase
     protected function tearDown()
     {
         $this->repository = null;
-        $this->remoteFilesystem = null;
+        $this->httpDownloader = null;
     }
 }

+ 3 - 1
tests/Composer/Test/Repository/RepositoryFactoryTest.php

@@ -21,7 +21,9 @@ class RepositoryFactoryTest extends TestCase
     {
         $manager = RepositoryFactory::manager(
             $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
-            $this->getMockBuilder('Composer\Config')->getMock()
+            $this->getMockBuilder('Composer\Config')->getMock(),
+            $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock(),
+            $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock()
         );
 
         $ref = new \ReflectionProperty($manager, 'repositoryClasses');

+ 4 - 2
tests/Composer/Test/Repository/RepositoryManagerTest.php

@@ -38,7 +38,8 @@ class RepositoryManagerTest extends TestCase
         $rm = new RepositoryManager(
             $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
             $this->getMockBuilder('Composer\Config')->getMock(),
-            $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock()
+            $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(),
+            $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock()
         );
 
         $repository1 = $this->getMockBuilder('Composer\Repository\RepositoryInterface')->getMock();
@@ -61,7 +62,8 @@ class RepositoryManagerTest extends TestCase
         $rm = new RepositoryManager(
             $this->getMockBuilder('Composer\IO\IOInterface')->getMock(),
             $config = $this->getMockBuilder('Composer\Config')->setMethods(array('get'))->getMock(),
-            $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock()
+            $this->getMockBuilder('Composer\EventDispatcher\EventDispatcher')->disableOriginalConstructor()->getMock(),
+            $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock()
         );
 
         $tmpdir = $this->tmpdir;

+ 32 - 36
tests/Composer/Test/Repository/Vcs/GitBitbucketDriverTest.php

@@ -16,6 +16,7 @@ use Composer\Config;
 use Composer\Repository\Vcs\GitBitbucketDriver;
 use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
+use Composer\Util\Http\Response;
 
 /**
  * @group bitbucket
@@ -26,8 +27,8 @@ class GitBitbucketDriverTest extends TestCase
     private $io;
     /** @type \Composer\Config */
     private $config;
-    /** @type \Composer\Util\RemoteFilesystem|\PHPUnit_Framework_MockObject_MockObject */
-    private $rfs;
+    /** @type \Composer\Util\HttpDownloader|\PHPUnit_Framework_MockObject_MockObject */
+    private $httpDownloader;
     /** @type string */
     private $home;
     /** @type string */
@@ -46,7 +47,7 @@ class GitBitbucketDriverTest extends TestCase
             ),
         ));
 
-        $this->rfs = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
+        $this->httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
             ->disableOriginalConstructor()
             ->getMock();
     }
@@ -68,7 +69,7 @@ class GitBitbucketDriverTest extends TestCase
             $this->io,
             $this->config,
             null,
-            $this->rfs
+            $this->httpDownloader
         );
 
         $driver->initialize();
@@ -83,15 +84,14 @@ class GitBitbucketDriverTest extends TestCase
             'https://bitbucket.org/user/repo.git does not appear to be a git repository, use https://bitbucket.org/user/repo if this is a mercurial bitbucket repository'
         );
 
-        $this->rfs->expects($this->once())
-            ->method('getContents')
+        $this->httpDownloader->expects($this->once())
+            ->method('get')
             ->with(
-                $this->originUrl,
-                'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
-                false
+                $url = 'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
+                array()
             )
             ->willReturn(
-                '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'
+                new Response(array('url' => $url), 200, array(), '{"scm":"hg","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo","name":"https"},{"href":"ssh:\/\/hg@bitbucket.org\/user\/repo","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}')
             );
 
         $driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git'));
@@ -103,47 +103,43 @@ class GitBitbucketDriverTest extends TestCase
     {
         $driver = $this->getDriver(array('url' => 'https://bitbucket.org/user/repo.git'));
 
-        $this->rfs->expects($this->any())
-            ->method('getContents')
+        $urls = array(
+            'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
+            'https://api.bitbucket.org/2.0/repositories/user/repo?fields=mainbranch',
+            'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date',
+            'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date',
+            'https://api.bitbucket.org/2.0/repositories/user/repo/src/master/composer.json',
+            'https://api.bitbucket.org/2.0/repositories/user/repo/commit/master?fields=date',
+        );
+        $this->httpDownloader->expects($this->any())
+            ->method('get')
             ->withConsecutive(
                 array(
-                    $this->originUrl,
-                    'https://api.bitbucket.org/2.0/repositories/user/repo?fields=-project%2C-owner',
-                    false,
+                    $urls[0], array()
                 ),
                 array(
-                    $this->originUrl,
-                    'https://api.bitbucket.org/2.0/repositories/user/repo?fields=mainbranch',
-                    false,
+                    $urls[1], array()
                 ),
                 array(
-                    $this->originUrl,
-                    'https://api.bitbucket.org/2.0/repositories/user/repo/refs/tags?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cnext&sort=-target.date',
-                    false,
+                    $urls[2], array()
                 ),
                 array(
-                    $this->originUrl,
-                    'https://api.bitbucket.org/2.0/repositories/user/repo/refs/branches?pagelen=100&fields=values.name%2Cvalues.target.hash%2Cvalues.heads%2Cnext&sort=-target.date',
-                    false,
+                    $urls[3], array()
                 ),
                 array(
-                    $this->originUrl,
-                    'https://api.bitbucket.org/2.0/repositories/user/repo/src/master/composer.json',
-                    false,
+                    $urls[4], array()
                 ),
                 array(
-                    $this->originUrl,
-                    'https://api.bitbucket.org/2.0/repositories/user/repo/commit/master?fields=date',
-                    false,
+                    $urls[5], array()
                 )
             )
             ->willReturnOnConsecutiveCalls(
-                '{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}',
-                '{"mainbranch": {"name": "master"}}',
-                '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}',
-                '{"values":[{"name":"master","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}',
-                '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}',
-                '{"date": "2016-05-17T13:19:52+00:00"}'
+                new Response(array('url' => $urls[0]), 200, array(), '{"scm":"git","website":"","has_wiki":false,"name":"repo","links":{"branches":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/branches"},"tags":{"href":"https:\/\/api.bitbucket.org\/2.0\/repositories\/user\/repo\/refs\/tags"},"clone":[{"href":"https:\/\/user@bitbucket.org\/user\/repo.git","name":"https"},{"href":"ssh:\/\/git@bitbucket.org\/user\/repo.git","name":"ssh"}],"html":{"href":"https:\/\/bitbucket.org\/user\/repo"}},"language":"php","created_on":"2015-02-18T16:22:24.688+00:00","updated_on":"2016-05-17T13:20:21.993+00:00","is_private":true,"has_issues":false}'),
+                new Response(array('url' => $urls[1]), 200, array(), '{"mainbranch": {"name": "master"}}'),
+                new Response(array('url' => $urls[2]), 200, array(), '{"values":[{"name":"1.0.1","target":{"hash":"9b78a3932143497c519e49b8241083838c8ff8a1"}},{"name":"1.0.0","target":{"hash":"d3393d514318a9267d2f8ebbf463a9aaa389f8eb"}}]}'),
+                new Response(array('url' => $urls[3]), 200, array(), '{"values":[{"name":"master","target":{"hash":"937992d19d72b5116c3e8c4a04f960e5fa270b22"}}]}'),
+                new Response(array('url' => $urls[4]), 200, array(), '{"name": "user/repo","description": "test repo","license": "GPL","authors": [{"name": "Name","email": "local@domain.tld"}],"require": {"creator/package": "^1.0"},"require-dev": {"phpunit/phpunit": "~4.8"}}'),
+                new Response(array('url' => $urls[5]), 200, array(), '{"date": "2016-05-17T13:19:52+00:00"}')
             );
 
         $this->assertEquals(

+ 43 - 42
tests/Composer/Test/Repository/Vcs/GitHubDriverTest.php

@@ -16,6 +16,7 @@ use Composer\Downloader\TransportException;
 use Composer\Repository\Vcs\GitHubDriver;
 use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
+use Composer\Util\Http\Response;
 use Composer\Config;
 
 class GitHubDriverTest extends TestCase
@@ -53,8 +54,8 @@ class GitHubDriverTest extends TestCase
             ->method('isInteractive')
             ->will($this->returnValue(true));
 
-        $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
-            ->setConstructorArgs(array($io))
+        $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
+            ->setConstructorArgs(array($io, $this->config))
             ->getMock();
 
         $process = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
@@ -62,9 +63,9 @@ class GitHubDriverTest extends TestCase
             ->method('execute')
             ->will($this->returnValue(1));
 
-        $remoteFilesystem->expects($this->at(0))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false))
+        $httpDownloader->expects($this->at(0))
+            ->method('get')
+            ->with($this->equalTo($repoApiUrl))
             ->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404)));
 
         $io->expects($this->once())
@@ -76,15 +77,15 @@ class GitHubDriverTest extends TestCase
             ->method('setAuthentication')
             ->with($this->equalTo('github.com'), $this->matchesRegularExpression('{sometoken}'), $this->matchesRegularExpression('{x-oauth-basic}'));
 
-        $remoteFilesystem->expects($this->at(1))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/'), $this->equalTo(false))
-            ->will($this->returnValue('{}'));
+        $httpDownloader->expects($this->at(1))
+            ->method('get')
+            ->with($this->equalTo($url = 'https://api.github.com/'))
+            ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{}')));
 
-        $remoteFilesystem->expects($this->at(2))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false))
-            ->will($this->returnValue('{"master_branch": "test_master", "private": true, "owner": {"login": "composer"}, "name": "packagist"}'));
+        $httpDownloader->expects($this->at(2))
+            ->method('get')
+            ->with($this->equalTo($url = $repoApiUrl))
+            ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"master_branch": "test_master", "private": true, "owner": {"login": "composer"}, "name": "packagist"}')));
 
         $configSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock();
         $authConfigSource = $this->getMockBuilder('Composer\Config\ConfigSourceInterface')->getMock();
@@ -95,7 +96,7 @@ class GitHubDriverTest extends TestCase
             'url' => $repoUrl,
         );
 
-        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $remoteFilesystem);
+        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader);
         $gitHubDriver->initialize();
         $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
 
@@ -124,21 +125,21 @@ class GitHubDriverTest extends TestCase
             ->method('isInteractive')
             ->will($this->returnValue(true));
 
-        $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
-            ->setConstructorArgs(array($io))
+        $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
+            ->setConstructorArgs(array($io, $this->config))
             ->getMock();
 
-        $remoteFilesystem->expects($this->at(0))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false))
-            ->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}'));
+        $httpDownloader->expects($this->at(0))
+            ->method('get')
+            ->with($this->equalTo($repoApiUrl))
+            ->will($this->returnValue(new Response(array('url' => $repoApiUrl), 200, array(), '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')));
 
         $repoConfig = array(
             'url' => $repoUrl,
         );
         $repoUrl = 'https://github.com/composer/packagist.git';
 
-        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
+        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader);
         $gitHubDriver->initialize();
         $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
 
@@ -167,31 +168,31 @@ class GitHubDriverTest extends TestCase
             ->method('isInteractive')
             ->will($this->returnValue(true));
 
-        $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
-            ->setConstructorArgs(array($io))
+        $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
+            ->setConstructorArgs(array($io, $this->config))
             ->getMock();
 
-        $remoteFilesystem->expects($this->at(0))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false))
-            ->will($this->returnValue('{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}'));
+        $httpDownloader->expects($this->at(0))
+            ->method('get')
+            ->with($this->equalTo($url = $repoApiUrl))
+            ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"master_branch": "test_master", "owner": {"login": "composer"}, "name": "packagist"}')));
 
-        $remoteFilesystem->expects($this->at(1))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo'), $this->equalTo(false))
-            ->will($this->returnValue('{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}'));
+        $httpDownloader->expects($this->at(1))
+            ->method('get')
+            ->with($this->equalTo($url = 'https://api.github.com/repos/composer/packagist/contents/composer.json?ref=feature%2F3.2-foo'))
+            ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"encoding":"base64","content":"'.base64_encode('{"support": {"source": "'.$repoUrl.'" }}').'"}')));
 
-        $remoteFilesystem->expects($this->at(2))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo('https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo'), $this->equalTo(false))
-            ->will($this->returnValue('{"commit": {"committer":{ "date": "2012-09-10"}}}'));
+        $httpDownloader->expects($this->at(2))
+            ->method('get')
+            ->with($this->equalTo($url = 'https://api.github.com/repos/composer/packagist/commits/feature%2F3.2-foo'))
+            ->will($this->returnValue(new Response(array('url' => $url), 200, array(), '{"commit": {"committer":{ "date": "2012-09-10"}}}')));
 
         $repoConfig = array(
             'url' => $repoUrl,
         );
         $repoUrl = 'https://github.com/composer/packagist.git';
 
-        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $remoteFilesystem);
+        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, null, $httpDownloader);
         $gitHubDriver->initialize();
         $this->setAttribute($gitHubDriver, 'tags', array($identifier => $sha));
 
@@ -227,13 +228,13 @@ class GitHubDriverTest extends TestCase
             ->method('isInteractive')
             ->will($this->returnValue(false));
 
-        $remoteFilesystem = $this->getMockBuilder('Composer\Util\RemoteFilesystem')
-            ->setConstructorArgs(array($io))
+        $httpDownloader = $this->getMockBuilder('Composer\Util\HttpDownloader')
+            ->setConstructorArgs(array($io, $this->config))
             ->getMock();
 
-        $remoteFilesystem->expects($this->at(0))
-            ->method('getContents')
-            ->with($this->equalTo('github.com'), $this->equalTo($repoApiUrl), $this->equalTo(false))
+        $httpDownloader->expects($this->at(0))
+            ->method('get')
+            ->with($this->equalTo($repoApiUrl))
             ->will($this->throwException(new TransportException('HTTP/1.1 404 Not Found', 404)));
 
         // clean local clone if present
@@ -278,7 +279,7 @@ class GitHubDriverTest extends TestCase
             'url' => $repoUrl,
         );
 
-        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $remoteFilesystem);
+        $gitHubDriver = new GitHubDriver($repoConfig, $io, $this->config, $process, $httpDownloader);
         $gitHubDriver->initialize();
 
         $this->assertEquals('test_master', $gitHubDriver->getRootIdentifier());

+ 42 - 64
tests/Composer/Test/Repository/Vcs/GitLabDriverTest.php

@@ -17,6 +17,7 @@ use Composer\Config;
 use Composer\Test\TestCase;
 use Composer\Util\Filesystem;
 use Prophecy\Argument;
+use Composer\Util\Http\Response;
 
 /**
  * @author Jérôme Tamarelle <jerome@tamarelle.net>
@@ -27,7 +28,7 @@ class GitLabDriverTest extends TestCase
     private $config;
     private $io;
     private $process;
-    private $remoteFilesystem;
+    private $httpDownloader;
 
     public function setUp()
     {
@@ -47,7 +48,7 @@ class GitLabDriverTest extends TestCase
 
         $this->io = $this->prophesize('Composer\IO\IOInterface');
         $this->process = $this->prophesize('Composer\Util\ProcessExecutor');
-        $this->remoteFilesystem = $this->prophesize('Composer\Util\RemoteFilesystem');
+        $this->httpDownloader = $this->prophesize('Composer\Util\HttpDownloader');
     }
 
     public function tearDown()
@@ -87,13 +88,11 @@ class GitLabDriverTest extends TestCase
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($projectData)
+        $this->mockResponse($apiUrl, array(), $projectData)
             ->shouldBeCalledTimes(1)
         ;
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -126,13 +125,11 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($projectData)
+        $this->mockResponse($apiUrl, array(), $projectData)
             ->shouldBeCalledTimes(1)
         ;
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -164,13 +161,11 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($projectData)
+        $this->mockResponse($apiUrl, array(), $projectData)
             ->shouldBeCalledTimes(1)
         ;
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -206,12 +201,10 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents($domain, $apiUrl, false, array())
-            ->willReturn(sprintf($projectData, $domain, $port, $namespace))
+        $this->mockResponse($apiUrl, array(), sprintf($projectData, $domain, $port, $namespace))
             ->shouldBeCalledTimes(1);
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -289,15 +282,11 @@ JSON;
 ]
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($tagData)
+        $this->mockResponse($apiUrl, array(), $tagData)
             ->shouldBeCalledTimes(1)
         ;
-        $this->remoteFilesystem->getLastHeaders()
-            ->willReturn(array());
 
-        $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
+        $driver->setHttpDownloader($this->httpDownloader->reveal());
 
         $expected = array(
             'v1.0.0' => '092ed2c762bbae331e3f51d4a17f67310bf99a81',
@@ -344,26 +333,20 @@ JSON;
 
         $branchData = json_encode($branchData);
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($branchData)
-            ->shouldBeCalledTimes(1)
-        ;
-
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20", false, array())
-            ->willReturn($branchData)
-            ->shouldBeCalledTimes(1)
-        ;
+        $headers = array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="next", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"');
+        $this->httpDownloader
+            ->get($apiUrl, array())
+            ->willReturn(new Response(array('url' => $apiUrl), 200, $headers, $branchData))
+            ->shouldBeCalledTimes(1);
 
-        $this->remoteFilesystem->getLastHeaders()
-            ->willReturn(
-                array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="next", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"'),
-                array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="prev", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"')
-            )
-            ->shouldBeCalledTimes(2);
+        $apiUrl = "http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20";
+        $headers = array('Link: <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=2&per_page=20>; rel="prev", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=1&per_page=20>; rel="first", <http://gitlab.com/api/v4/projects/mygroup%2Fmyproject/repository/tags?id=mygroup%2Fmyproject&page=3&per_page=20>; rel="last"');
+        $this->httpDownloader
+            ->get($apiUrl, array())
+            ->willReturn(new Response(array('url' => $apiUrl), 200, $headers, $branchData))
+            ->shouldBeCalledTimes(1);
 
-        $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
+        $driver->setHttpDownloader($this->httpDownloader->reveal());
 
         $expected = array(
             'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e',
@@ -401,15 +384,11 @@ JSON;
 ]
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($branchData)
+        $this->mockResponse($apiUrl, array(), $branchData)
             ->shouldBeCalledTimes(1)
         ;
-        $this->remoteFilesystem->getLastHeaders()
-            ->willReturn(array());
 
-        $driver->setRemoteFilesystem($this->remoteFilesystem->reveal());
+        $driver->setHttpDownloader($this->httpDownloader->reveal());
 
         $expected = array(
             'mymaster' => '97eda36b5c1dd953a3792865c222d4e85e5f302e',
@@ -474,13 +453,11 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('mycompany.com/gitlab', $apiUrl, false, array())
-            ->willReturn($projectData)
+        $this->mockResponse($apiUrl, array(), $projectData)
             ->shouldBeCalledTimes(1)
         ;
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -507,13 +484,11 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('gitlab.com', $apiUrl, false, array())
-            ->willReturn($projectData)
+        $this->mockResponse($apiUrl, array(), $projectData)
             ->shouldBeCalledTimes(1)
         ;
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -540,13 +515,11 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents('mycompany.com/gitlab', $apiUrl, false, array())
-            ->willReturn($projectData)
+        $this->mockResponse($apiUrl, array(), $projectData)
             ->shouldBeCalledTimes(1)
         ;
 
-        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->remoteFilesystem->reveal());
+        $driver = new GitLabDriver(array('url' => $url), $this->io->reveal(), $this->config, $this->process->reveal(), $this->httpDownloader->reveal());
         $driver->initialize();
 
         $this->assertEquals($apiUrl, $driver->getApiUrl(), 'API URL is derived from the repository URL');
@@ -575,9 +548,7 @@ JSON;
 }
 JSON;
 
-        $this->remoteFilesystem
-            ->getContents(Argument::cetera(), $options)
-            ->willReturn($projectData)
+        $this->mockResponse(Argument::cetera(), $options, $projectData)
             ->shouldBeCalled();
 
         $driver = new GitLabDriver(
@@ -585,8 +556,15 @@ JSON;
             $this->io->reveal(),
             $this->config,
             $this->process->reveal(),
-            $this->remoteFilesystem->reveal()
+            $this->httpDownloader->reveal()
         );
         $driver->initialize();
     }
+
+    private function mockResponse($url, $options, $return)
+    {
+        return $this->httpDownloader
+            ->get($url, $options)
+            ->willReturn(new Response(array('url' => $url), 200, array(), $return));
+    }
 }

+ 7 - 7
tests/Composer/Test/Repository/Vcs/PerforceDriverTest.php

@@ -26,7 +26,7 @@ class PerforceDriverTest extends TestCase
     protected $config;
     protected $io;
     protected $process;
-    protected $remoteFileSystem;
+    protected $httpDownloader;
     protected $testPath;
     protected $driver;
     protected $repoConfig;
@@ -43,9 +43,9 @@ class PerforceDriverTest extends TestCase
         $this->repoConfig = $this->getTestRepoConfig();
         $this->io = $this->getMockIOInterface();
         $this->process = $this->getMockProcessExecutor();
-        $this->remoteFileSystem = $this->getMockRemoteFilesystem();
+        $this->httpDownloader = $this->getMockHttpDownloader();
         $this->perforce = $this->getMockPerforce();
-        $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
+        $this->driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader);
         $this->overrideDriverInternalPerforce($this->perforce);
     }
 
@@ -56,7 +56,7 @@ class PerforceDriverTest extends TestCase
         $fs->removeDirectory($this->testPath);
         $this->driver = null;
         $this->perforce = null;
-        $this->remoteFileSystem = null;
+        $this->httpDownloader = null;
         $this->process = null;
         $this->io = null;
         $this->repoConfig = null;
@@ -99,9 +99,9 @@ class PerforceDriverTest extends TestCase
         return $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
     }
 
-    protected function getMockRemoteFilesystem()
+    protected function getMockHttpDownloader()
     {
-        return $this->getMockBuilder('Composer\Util\RemoteFilesystem')->disableOriginalConstructor()->getMock();
+        return $this->getMockBuilder('Composer\Util\HttpDownloader')->disableOriginalConstructor()->getMock();
     }
 
     protected function getMockPerforce()
@@ -113,7 +113,7 @@ class PerforceDriverTest extends TestCase
 
     public function testInitializeCapturesVariablesFromRepoConfig()
     {
-        $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->remoteFileSystem);
+        $driver = new PerforceDriver($this->repoConfig, $this->io, $this->config, $this->process, $this->httpDownloader);
         $driver->initialize();
         $this->assertEquals(self::TEST_URL, $driver->getUrl());
         $this->assertEquals(self::TEST_DEPOT, $driver->getDepot());

+ 40 - 32
tests/Composer/Test/Util/BitbucketTest.php

@@ -13,6 +13,7 @@
 namespace Composer\Test\Util;
 
 use Composer\Util\Bitbucket;
+use Composer\Util\Http\Response;
 use PHPUnit\Framework\TestCase;
 
 /**
@@ -30,8 +31,8 @@ class BitbucketTest extends TestCase
 
     /** @type \Composer\IO\ConsoleIO|\PHPUnit_Framework_MockObject_MockObject */
     private $io;
-    /** @type \Composer\Util\RemoteFilesystem|\PHPUnit_Framework_MockObject_MockObject */
-    private $rfs;
+    /** @type \Composer\Util\HttpDownloader|\PHPUnit_Framework_MockObject_MockObject */
+    private $httpDownloader;
     /** @type \Composer\Config|\PHPUnit_Framework_MockObject_MockObject */
     private $config;
     /** @type Bitbucket */
@@ -47,8 +48,8 @@ class BitbucketTest extends TestCase
             ->getMock()
         ;
 
-        $this->rfs = $this
-            ->getMockBuilder('Composer\Util\RemoteFilesystem')
+        $this->httpDownloader = $this
+            ->getMockBuilder('Composer\Util\HttpDownloader')
             ->disableOriginalConstructor()
             ->getMock()
         ;
@@ -57,7 +58,7 @@ class BitbucketTest extends TestCase
 
         $this->time = time();
 
-        $this->bitbucket = new Bitbucket($this->io, $this->config, null, $this->rfs, $this->time);
+        $this->bitbucket = new Bitbucket($this->io, $this->config, null, $this->httpDownloader, $this->time);
     }
 
     public function testRequestAccessTokenWithValidOAuthConsumer()
@@ -66,12 +67,10 @@ class BitbucketTest extends TestCase
             ->method('setAuthentication')
             ->with($this->origin, $this->consumer_key, $this->consumer_secret);
 
-        $this->rfs->expects($this->once())
-            ->method('getContents')
+        $this->httpDownloader->expects($this->once())
+            ->method('get')
             ->with(
-                $this->origin,
                 Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
-                false,
                 array(
                     'retry-auth-failure' => false,
                     'http' => array(
@@ -81,9 +80,14 @@ class BitbucketTest extends TestCase
                 )
             )
             ->willReturn(
-                sprintf(
-                    '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}',
-                    $this->token
+                new Response(
+                    array('url' => Bitbucket::OAUTH2_ACCESS_TOKEN_URL),
+                    200,
+                    array(),
+                    sprintf(
+                        '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}',
+                        $this->token
+                    )
                 )
             );
 
@@ -142,12 +146,10 @@ class BitbucketTest extends TestCase
             ->method('setAuthentication')
             ->with($this->origin, $this->consumer_key, $this->consumer_secret);
 
-        $this->rfs->expects($this->once())
-            ->method('getContents')
+        $this->httpDownloader->expects($this->once())
+            ->method('get')
             ->with(
-                $this->origin,
                 Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
-                false,
                 array(
                     'retry-auth-failure' => false,
                     'http' => array(
@@ -157,9 +159,14 @@ class BitbucketTest extends TestCase
                 )
             )
             ->willReturn(
-                sprintf(
-                    '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}',
-                    $this->token
+                new Response(
+                    array('url' => Bitbucket::OAUTH2_ACCESS_TOKEN_URL),
+                    200,
+                    array(),
+                    sprintf(
+                        '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refreshtoken", "token_type": "bearer"}',
+                        $this->token
+                    )
                 )
             );
 
@@ -186,12 +193,10 @@ class BitbucketTest extends TestCase
                 array('2. You are using an OAuth consumer, but didn\'t configure a (dummy) callback url')
             );
 
-        $this->rfs->expects($this->once())
-            ->method('getContents')
+        $this->httpDownloader->expects($this->once())
+            ->method('get')
             ->with(
-                $this->origin,
                 Bitbucket::OAUTH2_ACCESS_TOKEN_URL,
-                false,
                 array(
                     'retry-auth-failure' => false,
                     'http' => array(
@@ -234,21 +239,24 @@ class BitbucketTest extends TestCase
             )
             ->willReturnOnConsecutiveCalls($this->consumer_key, $this->consumer_secret);
 
-        $this->rfs
+        $this->httpDownloader
             ->expects($this->once())
-            ->method('getContents')
+            ->method('get')
             ->with(
-                $this->equalTo($this->origin),
-                $this->equalTo(sprintf('https://%s/site/oauth2/access_token', $this->origin)),
-                $this->isFalse(),
+                $this->equalTo($url = sprintf('https://%s/site/oauth2/access_token', $this->origin)),
                 $this->anything()
             )
             ->willReturn(
-                sprintf(
-                    '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refresh_token", "token_type": "bearer"}',
-                    $this->token
+                new Response(
+                    array('url' => $url),
+                    200,
+                    array(),
+                    sprintf(
+                        '{"access_token": "%s", "scopes": "repository", "expires_in": 3600, "refresh_token": "refresh_token", "token_type": "bearer"}',
+                        $this->token
+                    )
                 )
-            )
+            );
         ;
 
         $this->setExpectationsForStoringAccessToken(true);

+ 15 - 16
tests/Composer/Test/Util/GitHubTest.php

@@ -14,6 +14,7 @@ namespace Composer\Test\Util;
 
 use Composer\Downloader\TransportException;
 use Composer\Util\GitHub;
+use Composer\Util\Http\Response;
 use PHPUnit\Framework\TestCase;
 use RecursiveArrayIterator;
 use RecursiveIteratorIterator;
@@ -45,17 +46,15 @@ class GitHubTest extends TestCase
             ->willReturn($this->password)
         ;
 
-        $rfs = $this->getRemoteFilesystemMock();
-        $rfs
+        $httpDownloader = $this->getHttpDownloaderMock();
+        $httpDownloader
             ->expects($this->once())
-            ->method('getContents')
+            ->method('get')
             ->with(
-                $this->equalTo($this->origin),
-                $this->equalTo(sprintf('https://api.%s/', $this->origin)),
-                $this->isFalse(),
+                $this->equalTo($url = sprintf('https://api.%s/', $this->origin)),
                 $this->anything()
             )
-            ->willReturn('{}')
+            ->willReturn(new Response(array('url' => $url), 200, array(), '{}'));
         ;
 
         $config = $this->getConfigMock();
@@ -70,7 +69,7 @@ class GitHubTest extends TestCase
             ->willReturn($this->getConfJsonMock())
         ;
 
-        $github = new GitHub($io, $config, null, $rfs);
+        $github = new GitHub($io, $config, null, $httpDownloader);
 
         $this->assertTrue($github->authorizeOAuthInteractively($this->origin, $this->message));
     }
@@ -85,10 +84,10 @@ class GitHubTest extends TestCase
             ->willReturn($this->password)
         ;
 
-        $rfs = $this->getRemoteFilesystemMock();
-        $rfs
+        $httpDownloader = $this->getHttpDownloaderMock();
+        $httpDownloader
             ->expects($this->exactly(1))
-            ->method('getContents')
+            ->method('get')
             ->will($this->throwException(new TransportException('', 401)))
         ;
 
@@ -99,7 +98,7 @@ class GitHubTest extends TestCase
             ->willReturn($this->getAuthJsonMock())
         ;
 
-        $github = new GitHub($io, $config, null, $rfs);
+        $github = new GitHub($io, $config, null, $httpDownloader);
 
         $this->assertFalse($github->authorizeOAuthInteractively($this->origin));
     }
@@ -120,15 +119,15 @@ class GitHubTest extends TestCase
         return $this->getMockBuilder('Composer\Config')->getMock();
     }
 
-    private function getRemoteFilesystemMock()
+    private function getHttpDownloaderMock()
     {
-        $rfs = $this
-            ->getMockBuilder('Composer\Util\RemoteFilesystem')
+        $httpDownloader = $this
+            ->getMockBuilder('Composer\Util\HttpDownloader')
             ->disableOriginalConstructor()
             ->getMock()
         ;
 
-        return $rfs;
+        return $httpDownloader;
     }
 
     private function getAuthJsonMock()

+ 15 - 16
tests/Composer/Test/Util/GitLabTest.php

@@ -14,6 +14,7 @@ namespace Composer\Test\Util;
 
 use Composer\Downloader\TransportException;
 use Composer\Util\GitLab;
+use Composer\Util\Http\Response;
 use PHPUnit\Framework\TestCase;
 
 /**
@@ -49,17 +50,15 @@ class GitLabTest extends TestCase
             ->willReturn($this->password)
         ;
 
-        $rfs = $this->getRemoteFilesystemMock();
-        $rfs
+        $httpDownloader = $this->getHttpDownloaderMock();
+        $httpDownloader
             ->expects($this->once())
-            ->method('getContents')
+            ->method('get')
             ->with(
-                $this->equalTo($this->origin),
-                $this->equalTo(sprintf('http://%s/oauth/token', $this->origin)),
-                $this->isFalse(),
+                $this->equalTo($url = sprintf('http://%s/oauth/token', $this->origin)),
                 $this->anything()
             )
-            ->willReturn(sprintf('{"access_token": "%s", "token_type": "bearer", "expires_in": 7200}', $this->token))
+            ->willReturn(new Response(array('url' => $url), 200, array(), sprintf('{"access_token": "%s", "token_type": "bearer", "expires_in": 7200}', $this->token)));
         ;
 
         $config = $this->getConfigMock();
@@ -69,7 +68,7 @@ class GitLabTest extends TestCase
             ->willReturn($this->getAuthJsonMock())
         ;
 
-        $gitLab = new GitLab($io, $config, null, $rfs);
+        $gitLab = new GitLab($io, $config, null, $httpDownloader);
 
         $this->assertTrue($gitLab->authorizeOAuthInteractively('http', $this->origin, $this->message));
     }
@@ -94,10 +93,10 @@ class GitLabTest extends TestCase
             ->willReturn($this->password)
         ;
 
-        $rfs = $this->getRemoteFilesystemMock();
-        $rfs
+        $httpDownloader = $this->getHttpDownloaderMock();
+        $httpDownloader
             ->expects($this->exactly(5))
-            ->method('getContents')
+            ->method('get')
             ->will($this->throwException(new TransportException('', 401)))
         ;
 
@@ -108,7 +107,7 @@ class GitLabTest extends TestCase
             ->willReturn($this->getAuthJsonMock())
         ;
 
-        $gitLab = new GitLab($io, $config, null, $rfs);
+        $gitLab = new GitLab($io, $config, null, $httpDownloader);
 
         $gitLab->authorizeOAuthInteractively('https', $this->origin);
     }
@@ -129,15 +128,15 @@ class GitLabTest extends TestCase
         return $this->getMockBuilder('Composer\Config')->getMock();
     }
 
-    private function getRemoteFilesystemMock()
+    private function getHttpDownloaderMock()
     {
-        $rfs = $this
-            ->getMockBuilder('Composer\Util\RemoteFilesystem')
+        $httpDownloader = $this
+            ->getMockBuilder('Composer\Util\HttpDownloader')
             ->disableOriginalConstructor()
             ->getMock()
         ;
 
-        return $rfs;
+        return $httpDownloader;
     }
 
     private function getAuthJsonMock()