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;
}