parent
417516098e
commit
ff84b32097
|
@ -168,3 +168,25 @@ To enable the swap you can use for example:
|
|||
/sbin/mkswap /var/swap.1
|
||||
/sbin/swapon /var/swap.1
|
||||
```
|
||||
|
||||
## Degraded Mode
|
||||
|
||||
Due to some intermittent issues on Travis and other systems, we introduced a
|
||||
degraded network mode which helps Composer finish successfully but disables
|
||||
a few optimizations. This is enabled automatically when an issue is first
|
||||
detected.
|
||||
|
||||
If you have been pointed to this page, you want to check a few things:
|
||||
|
||||
- If you are using ESET antivirus, go in "Advanced Settings" and disable "HTTP-scanner"
|
||||
under "web access protection"
|
||||
- If you are using IPv6, try disabling it. If that solves your issues, get in touch
|
||||
with your ISP or server host, the problem is not at the Packagist level but in the
|
||||
routing rules between you and Packagist (i.e. the internet at large). The best way to get
|
||||
these fixed is raise awareness to the network engineers that have the power to fix it.
|
||||
|
||||
To disable IPv6 on Linux, try using this command which appends a
|
||||
rule prefering IPv4 over IPv6 to your config:
|
||||
|
||||
`sudo sh -c "echo 'precedence ::ffff:0:0/96 100' >> /etc/gai.conf"`
|
||||
- If none of the above helped, please report the error.
|
||||
|
|
|
@ -37,6 +37,7 @@ class RemoteFilesystem
|
|||
private $retryAuthFailure;
|
||||
private $lastHeaders;
|
||||
private $storeAuth;
|
||||
private $degradedMode = false;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -155,6 +156,10 @@ class RemoteFilesystem
|
|||
if (isset($options['http'])) {
|
||||
$options['http']['ignore_errors'] = true;
|
||||
}
|
||||
if ($this->degradedMode && substr($fileUrl, 0, 21) === 'http://packagist.org/') {
|
||||
// access packagist using the resolved IPv4 instead of the hostname to force IPv4 protocol
|
||||
$fileUrl = 'http://' . gethostbyname('packagist.org') . substr($fileUrl, 20);
|
||||
}
|
||||
$ctx = StreamContextFactory::getContext($fileUrl, $options, array('notification' => array($this, 'callbackGet')));
|
||||
|
||||
if ($this->progress) {
|
||||
|
@ -186,6 +191,16 @@ class RemoteFilesystem
|
|||
}
|
||||
restore_error_handler();
|
||||
if (isset($e) && !$this->retry) {
|
||||
if (false !== strpos($e->getMessage(), 'Operation timed out')) {
|
||||
$this->degradedMode = true;
|
||||
$this->io->writeError(array(
|
||||
'<error>'.$e->getMessage().'</error>',
|
||||
'<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>'
|
||||
));
|
||||
|
||||
return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
|
@ -201,36 +216,45 @@ class RemoteFilesystem
|
|||
$result = false;
|
||||
}
|
||||
|
||||
if ($this->progress && !$this->retry) {
|
||||
$this->io->overwriteError(" Downloading: <comment>100%</comment>");
|
||||
}
|
||||
|
||||
// decode gzip
|
||||
if ($result && extension_loaded('zlib') && substr($fileUrl, 0, 4) === 'http') {
|
||||
$decode = false;
|
||||
foreach ($http_response_header as $header) {
|
||||
if (preg_match('{^content-encoding: *gzip *$}i', $header)) {
|
||||
$decode = true;
|
||||
continue;
|
||||
} elseif (preg_match('{^HTTP/}i', $header)) {
|
||||
$decode = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($decode) {
|
||||
if (PHP_VERSION_ID >= 50400) {
|
||||
$result = zlib_decode($result);
|
||||
} else {
|
||||
// work around issue with gzuncompress & co that do not work with all gzip checksums
|
||||
$result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
|
||||
}
|
||||
try {
|
||||
if (PHP_VERSION_ID >= 50400) {
|
||||
$result = zlib_decode($result);
|
||||
} else {
|
||||
// work around issue with gzuncompress & co that do not work with all gzip checksums
|
||||
$result = file_get_contents('compress.zlib://data:application/octet-stream;base64,'.base64_encode($result));
|
||||
}
|
||||
|
||||
if (!$result) {
|
||||
throw new TransportException('Failed to decode zlib stream');
|
||||
if (!$result) {
|
||||
throw new TransportException('Failed to decode zlib stream');
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$this->degradedMode = true;
|
||||
$this->io->writeError(array(
|
||||
'<error>Failed to decode response: '.$e->getMessage().'</error>',
|
||||
'<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>'
|
||||
));
|
||||
|
||||
return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->progress && !$this->retry) {
|
||||
$this->io->overwriteError(" Downloading: <comment>100%</comment>");
|
||||
}
|
||||
|
||||
// handle copy command if download was successful
|
||||
if (false !== $result && null !== $fileName) {
|
||||
if ('' === $result) {
|
||||
|
@ -269,6 +293,16 @@ class RemoteFilesystem
|
|||
$e->setHeaders($http_response_header);
|
||||
}
|
||||
|
||||
if (false !== strpos($e->getMessage(), 'Operation timed out')) {
|
||||
$this->degradedMode = true;
|
||||
$this->io->writeError(array(
|
||||
'<error>'.$e->getMessage().'</error>',
|
||||
'<error>Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info</error>'
|
||||
));
|
||||
|
||||
return $this->get($this->originUrl, $this->fileUrl, $additionalOptions, $this->fileName, $this->progress);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
|
@ -404,8 +438,12 @@ class RemoteFilesystem
|
|||
}
|
||||
|
||||
$options = array_replace_recursive($this->options, $additionalOptions);
|
||||
$options['http']['protocol_version'] = 1.1;
|
||||
$headers[] = 'Connection: close';
|
||||
if (!$this->degradedMode) {
|
||||
// degraded mode disables HTTP/1.1 which causes issues with some bad
|
||||
// proxies/software due to the use of chunked encoding
|
||||
$options['http']['protocol_version'] = 1.1;
|
||||
$headers[] = 'Connection: close';
|
||||
}
|
||||
|
||||
if ($this->io->hasAuthentication($originUrl)) {
|
||||
$auth = $this->io->getAuthentication($originUrl);
|
||||
|
|
Loading…
Reference in New Issue