diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index 372513331..dbbb2328a 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -95,10 +95,28 @@ class FileDownloader implements DownloaderInterface try { try { if (!$this->cache || !$this->cache->copyTo($this->getCacheKey($package), $fileName)) { - $this->rfs->copy($hostname, $processedUrl, $fileName, $this->outputProgress); if (!$this->outputProgress) { $this->io->write(' Downloading'); } + + // try to download 3 times then fail hard + $retries = 3; + while ($retries--) { + try { + $this->rfs->copy($hostname, $processedUrl, $fileName, $this->outputProgress); + break; + } catch (TransportException $e) { + // if we got an http response with a proper code, then requesting again will probably not help, abort + if (0 !== $e->getCode() || !$retries) { + throw $e; + } + if ($this->io->isVerbose()) { + $this->io->write(' Download failed, retrying...'); + } + usleep(500000); + } + } + if ($this->cache) { $this->cache->copyFrom($this->getCacheKey($package), $fileName); } @@ -172,7 +190,7 @@ class FileDownloader implements DownloaderInterface $this->io->write(" - Removing " . $package->getName() . " (" . VersionParser::formatVersion($package) . ")"); if (!$this->filesystem->removeDirectory($path)) { // retry after a bit on windows since it tends to be touchy with mass removals - if (!defined('PHP_WINDOWS_VERSION_BUILD') || (usleep(250) && !$this->filesystem->removeDirectory($path))) { + if (!defined('PHP_WINDOWS_VERSION_BUILD') || (usleep(250000) && !$this->filesystem->removeDirectory($path))) { throw new \RuntimeException('Could not completely delete '.$path.', aborting.'); } } diff --git a/src/Composer/Repository/ComposerRepository.php b/src/Composer/Repository/ComposerRepository.php index 1b205b00c..93badb1c2 100644 --- a/src/Composer/Repository/ComposerRepository.php +++ b/src/Composer/Repository/ComposerRepository.php @@ -539,7 +539,7 @@ class ComposerRepository extends ArrayRepository implements StreamableRepository $json = $this->rfs->getContents($filename, $filename, false); if ($sha256 && $sha256 !== hash('sha256', $json)) { if ($retries) { - usleep(100); + usleep(100000); continue; } @@ -553,7 +553,7 @@ class ComposerRepository extends ArrayRepository implements StreamableRepository break; } catch (\Exception $e) { if ($retries) { - usleep(100); + usleep(100000); continue; }