|
@@ -17,6 +17,7 @@ use Composer\IO\IOInterface;
|
|
use Composer\Downloader\TransportException;
|
|
use Composer\Downloader\TransportException;
|
|
use Composer\CaBundle\CaBundle;
|
|
use Composer\CaBundle\CaBundle;
|
|
use Composer\Util\HttpDownloader;
|
|
use Composer\Util\HttpDownloader;
|
|
|
|
+use Composer\Util\Response;
|
|
|
|
|
|
/**
|
|
/**
|
|
* @author François Pluchino <francois.pluchino@opendisplay.com>
|
|
* @author François Pluchino <francois.pluchino@opendisplay.com>
|
|
@@ -143,27 +144,6 @@ class RemoteFilesystem
|
|
return $this->lastHeaders;
|
|
return $this->lastHeaders;
|
|
}
|
|
}
|
|
|
|
|
|
- /**
|
|
|
|
- * @param array $headers array of returned headers like from getLastHeaders()
|
|
|
|
- * @param string $name header name (case insensitive)
|
|
|
|
- * @return string|null
|
|
|
|
- */
|
|
|
|
- public static function findHeaderValue(array $headers, $name)
|
|
|
|
- {
|
|
|
|
- $value = null;
|
|
|
|
- foreach ($headers as $header) {
|
|
|
|
- if (preg_match('{^'.$name.':\s*(.+?)\s*$}i', $header, $match)) {
|
|
|
|
- $value = $match[1];
|
|
|
|
- } elseif (preg_match('{^HTTP/}i', $header)) {
|
|
|
|
- // In case of redirects, http_response_headers contains the headers of all responses
|
|
|
|
- // so we reset the flag when a new response is being parsed as we are only interested in the last response
|
|
|
|
- $value = null;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return $value;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* @param array $headers array of returned headers like from getLastHeaders()
|
|
* @param array $headers array of returned headers like from getLastHeaders()
|
|
* @return int|null
|
|
* @return int|null
|
|
@@ -294,7 +274,7 @@ class RemoteFilesystem
|
|
|
|
|
|
if (!empty($http_response_header[0])) {
|
|
if (!empty($http_response_header[0])) {
|
|
$statusCode = $this->findStatusCode($http_response_header);
|
|
$statusCode = $this->findStatusCode($http_response_header);
|
|
- if ($statusCode >= 400 && $this->findHeaderValue($http_response_header, 'content-type') === 'application/json') {
|
|
|
|
|
|
+ if ($statusCode >= 400 && Response::findHeaderValue($http_response_header, 'content-type') === 'application/json') {
|
|
HttpDownloader::outputWarnings($this->io, $originUrl, json_decode($result, true));
|
|
HttpDownloader::outputWarnings($this->io, $originUrl, json_decode($result, true));
|
|
}
|
|
}
|
|
|
|
|
|
@@ -303,7 +283,7 @@ class RemoteFilesystem
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- $contentLength = !empty($http_response_header[0]) ? $this->findHeaderValue($http_response_header, 'content-length') : null;
|
|
|
|
|
|
+ $contentLength = !empty($http_response_header[0]) ? Response::findHeaderValue($http_response_header, 'content-length') : null;
|
|
if ($contentLength && Platform::strlen($result) < $contentLength) {
|
|
if ($contentLength && Platform::strlen($result) < $contentLength) {
|
|
// alas, this is not possible via the stream callback because STREAM_NOTIFY_COMPLETED is documented, but not implemented anywhere in PHP
|
|
// alas, this is not possible via the stream callback because STREAM_NOTIFY_COMPLETED is documented, but not implemented anywhere in PHP
|
|
$e = new TransportException('Content-Length mismatch, received '.Platform::strlen($result).' bytes out of the expected '.$contentLength);
|
|
$e = new TransportException('Content-Length mismatch, received '.Platform::strlen($result).' bytes out of the expected '.$contentLength);
|
|
@@ -360,8 +340,8 @@ class RemoteFilesystem
|
|
$locationHeader = null;
|
|
$locationHeader = null;
|
|
if (!empty($http_response_header[0])) {
|
|
if (!empty($http_response_header[0])) {
|
|
$statusCode = $this->findStatusCode($http_response_header);
|
|
$statusCode = $this->findStatusCode($http_response_header);
|
|
- $contentType = $this->findHeaderValue($http_response_header, 'content-type');
|
|
|
|
- $locationHeader = $this->findHeaderValue($http_response_header, 'location');
|
|
|
|
|
|
+ $contentType = Response::findHeaderValue($http_response_header, 'content-type');
|
|
|
|
+ $locationHeader = Response::findHeaderValue($http_response_header, 'location');
|
|
}
|
|
}
|
|
|
|
|
|
// check for bitbucket login page asking to authenticate
|
|
// check for bitbucket login page asking to authenticate
|
|
@@ -417,7 +397,7 @@ class RemoteFilesystem
|
|
|
|
|
|
// decode gzip
|
|
// decode gzip
|
|
if ($result && extension_loaded('zlib') && substr($fileUrl, 0, 4) === 'http' && !$hasFollowedRedirect) {
|
|
if ($result && extension_loaded('zlib') && substr($fileUrl, 0, 4) === 'http' && !$hasFollowedRedirect) {
|
|
- $contentEncoding = $this->findHeaderValue($http_response_header, 'content-encoding');
|
|
|
|
|
|
+ $contentEncoding = Response::findHeaderValue($http_response_header, 'content-encoding');
|
|
$decode = $contentEncoding && 'gzip' === strtolower($contentEncoding);
|
|
$decode = $contentEncoding && 'gzip' === strtolower($contentEncoding);
|
|
|
|
|
|
if ($decode) {
|
|
if ($decode) {
|
|
@@ -700,7 +680,7 @@ class RemoteFilesystem
|
|
|
|
|
|
private function handleRedirect(array $http_response_header, array $additionalOptions, $result)
|
|
private function handleRedirect(array $http_response_header, array $additionalOptions, $result)
|
|
{
|
|
{
|
|
- if ($locationHeader = $this->findHeaderValue($http_response_header, 'location')) {
|
|
|
|
|
|
+ if ($locationHeader = Response::findHeaderValue($http_response_header, 'location')) {
|
|
if (parse_url($locationHeader, PHP_URL_SCHEME)) {
|
|
if (parse_url($locationHeader, PHP_URL_SCHEME)) {
|
|
// Absolute URL; e.g. https://example.com/composer
|
|
// Absolute URL; e.g. https://example.com/composer
|
|
$targetUrl = $locationHeader;
|
|
$targetUrl = $locationHeader;
|