Improve handling of non-standard ports for GitLab and GitHub installs, fixes #8173
parent
5ddc40e93c
commit
0261ce8092
|
@ -125,7 +125,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
|||
$fileName = $this->getFileName($package, $path);
|
||||
|
||||
$processedUrl = $this->processUrl($package, $url);
|
||||
$hostname = parse_url($processedUrl, PHP_URL_HOST);
|
||||
$origin = RemoteFilesystem::getOrigin($processedUrl);
|
||||
|
||||
$preFileDownloadEvent = new PreFileDownloadEvent(PluginEvents::PRE_FILE_DOWNLOAD, $this->rfs, $processedUrl);
|
||||
if ($this->eventDispatcher) {
|
||||
|
@ -150,7 +150,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
|||
$retries = 3;
|
||||
while ($retries--) {
|
||||
try {
|
||||
$rfs->copy($hostname, $processedUrl, $fileName, $this->outputProgress, $package->getTransportOptions());
|
||||
$rfs->copy($origin, $processedUrl, $fileName, $this->outputProgress, $package->getTransportOptions());
|
||||
break;
|
||||
} catch (TransportException $e) {
|
||||
// if we got an http response with a proper code, then requesting again will probably not help, abort
|
||||
|
|
|
@ -206,8 +206,8 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
|||
if ($this->searchUrl && $mode === self::SEARCH_FULLTEXT) {
|
||||
$url = str_replace(array('%query%', '%type%'), array($query, $type), $this->searchUrl);
|
||||
|
||||
$hostname = parse_url($url, PHP_URL_HOST) ?: $url;
|
||||
$json = $this->rfs->getContents($hostname, $url, false);
|
||||
$origin = RemoteFilesystem::getOrigin($url);
|
||||
$json = $this->rfs->getContents($origin, $url, false);
|
||||
$search = JsonFile::parseJson($json, $url);
|
||||
|
||||
if (empty($search['results'])) {
|
||||
|
@ -681,10 +681,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
|||
$this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
|
||||
}
|
||||
|
||||
$hostname = parse_url($filename, PHP_URL_HOST) ?: $filename;
|
||||
$origin = RemoteFilesystem::getOrigin($filename);
|
||||
$rfs = $preFileDownloadEvent->getRemoteFilesystem();
|
||||
|
||||
$json = $rfs->getContents($hostname, $filename, false);
|
||||
$json = $rfs->getContents($origin, $filename, false);
|
||||
if ($sha256 && $sha256 !== hash('sha256', $json)) {
|
||||
// undo downgrade before trying again if http seems to be hijacked or modifying content somehow
|
||||
if ($this->allowSslDowngrade) {
|
||||
|
@ -760,10 +760,10 @@ class ComposerRepository extends ArrayRepository implements ConfigurableReposito
|
|||
$this->eventDispatcher->dispatch($preFileDownloadEvent->getName(), $preFileDownloadEvent);
|
||||
}
|
||||
|
||||
$hostname = parse_url($filename, PHP_URL_HOST) ?: $filename;
|
||||
$origin = RemoteFilesystem::getOrigin($filename);
|
||||
$rfs = $preFileDownloadEvent->getRemoteFilesystem();
|
||||
$options = array('http' => array('header' => array('If-Modified-Since: '.$lastModifiedTime)));
|
||||
$json = $rfs->getContents($hostname, $filename, false, $options);
|
||||
$json = $rfs->getContents($origin, $filename, false, $options);
|
||||
if ($json === '' && $rfs->findStatusCode($rfs->getLastHeaders()) === 304) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -304,6 +304,10 @@ class GitHubDriver extends VcsDriver
|
|||
*/
|
||||
protected function generateSshUrl()
|
||||
{
|
||||
if (false !== strpos($this->originUrl, ':')) {
|
||||
return 'ssh://git@' . $this->originUrl . '/'.$this->owner.'/'.$this->repository.'.git';
|
||||
}
|
||||
|
||||
return 'git@' . $this->originUrl . ':'.$this->owner.'/'.$this->repository.'.git';
|
||||
}
|
||||
|
||||
|
|
|
@ -67,9 +67,9 @@ class GitLabDriver extends VcsDriver
|
|||
private $isPrivate = true;
|
||||
|
||||
/**
|
||||
* @var int port number
|
||||
* @var bool true if the origin has a port number or a path component in it
|
||||
*/
|
||||
protected $portNumber;
|
||||
private $hasNonstandardOrigin = false;
|
||||
|
||||
const URL_REGEX = '#^(?:(?P<scheme>https?)://(?P<domain>.+?)(?::(?P<port>[0-9]+))?/|git@(?P<domain2>[^:]+):)(?P<parts>.+)/(?P<repo>[^/]+?)(?:\.git|/)?$#';
|
||||
|
||||
|
@ -94,11 +94,10 @@ class GitLabDriver extends VcsDriver
|
|||
? $match['scheme']
|
||||
: (isset($this->repoConfig['secure-http']) && $this->repoConfig['secure-http'] === false ? 'http' : 'https')
|
||||
;
|
||||
$this->originUrl = $this->determineOrigin($configuredDomains, $guessedDomain, $urlParts);
|
||||
$this->originUrl = $this->determineOrigin($configuredDomains, $guessedDomain, $urlParts, $match['port']);
|
||||
|
||||
if (!empty($match['port']) && true === is_numeric($match['port'])) {
|
||||
// If it is an HTTP based URL, and it has a port
|
||||
$this->portNumber = (int) $match['port'];
|
||||
if (false !== strpos($this->originUrl, ':') || false !== strpos($this->originUrl, '/')) {
|
||||
$this->hasNonstandardOrigin = true;
|
||||
}
|
||||
|
||||
$this->namespace = implode('/', $urlParts);
|
||||
|
@ -259,10 +258,7 @@ class GitLabDriver extends VcsDriver
|
|||
*/
|
||||
public function getApiUrl()
|
||||
{
|
||||
$domainName = $this->originUrl;
|
||||
$portNumber = (true === is_numeric($this->portNumber)) ? sprintf(':%s', $this->portNumber) : '';
|
||||
|
||||
return $this->scheme.'://'.$domainName.$portNumber.'/api/v4/projects/'.$this->urlEncodeAll($this->namespace).'%2F'.$this->urlEncodeAll($this->repository);
|
||||
return $this->scheme.'://'.$this->originUrl.'/api/v4/projects/'.$this->urlEncodeAll($this->namespace).'%2F'.$this->urlEncodeAll($this->repository);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,6 +356,10 @@ class GitLabDriver extends VcsDriver
|
|||
*/
|
||||
protected function generateSshUrl()
|
||||
{
|
||||
if ($this->hasNonstandardOrigin) {
|
||||
return 'ssh://git@'.$this->originUrl.'/'.$this->namespace.'/'.$this->repository.'.git';
|
||||
}
|
||||
|
||||
return 'git@' . $this->originUrl . ':'.$this->namespace.'/'.$this->repository.'.git';
|
||||
}
|
||||
|
||||
|
@ -458,7 +458,7 @@ class GitLabDriver extends VcsDriver
|
|||
$guessedDomain = !empty($match['domain']) ? $match['domain'] : $match['domain2'];
|
||||
$urlParts = explode('/', $match['parts']);
|
||||
|
||||
if (false === self::determineOrigin((array) $config->get('gitlab-domains'), $guessedDomain, $urlParts)) {
|
||||
if (false === self::determineOrigin((array) $config->get('gitlab-domains'), $guessedDomain, $urlParts, $match['port'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -492,16 +492,16 @@ class GitLabDriver extends VcsDriver
|
|||
* @param array $urlParts
|
||||
* @return bool|string
|
||||
*/
|
||||
private static function determineOrigin(array $configuredDomains, $guessedDomain, array &$urlParts)
|
||||
private static function determineOrigin(array $configuredDomains, $guessedDomain, array &$urlParts, $portNumber)
|
||||
{
|
||||
if (in_array($guessedDomain, $configuredDomains)) {
|
||||
if (in_array($guessedDomain, $configuredDomains) || ($portNumber && in_array($guessedDomain.':'.$portNumber, $configuredDomains))) {
|
||||
return $guessedDomain;
|
||||
}
|
||||
|
||||
while (null !== ($part = array_shift($urlParts))) {
|
||||
$guessedDomain .= '/' . $part;
|
||||
|
||||
if (in_array($guessedDomain, $configuredDomains)) {
|
||||
if (in_array($guessedDomain, $configuredDomains) || ($portNumber && in_array(preg_replace('{/}', ':'.$portNumber.'/', $guessedDomain, 1), $configuredDomains))) {
|
||||
return $guessedDomain;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,10 @@ class GitLab
|
|||
*/
|
||||
public function authorizeOAuth($originUrl)
|
||||
{
|
||||
if (!in_array($originUrl, $this->config->get('gitlab-domains'), true)) {
|
||||
// before composer 1.9, origin URLs had no port number in them
|
||||
$bcOriginUrl = preg_replace('{:\d+}', '', $originUrl);
|
||||
|
||||
if (!in_array($originUrl, $this->config->get('gitlab-domains'), true) && !in_array($bcOriginUrl, $this->config->get('gitlab-domains'), true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -73,6 +76,12 @@ class GitLab
|
|||
return true;
|
||||
}
|
||||
|
||||
if (isset($authTokens[$bcOriginUrl])) {
|
||||
$this->io->setAuthentication($originUrl, $authTokens[$bcOriginUrl], 'private-token');
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1110,4 +1110,17 @@ class RemoteFilesystem
|
|||
$io->writeError('<'.$type.'>'.ucfirst($type).' from '.$url.': '.$data[$type].'</'.$type.'>');
|
||||
}
|
||||
}
|
||||
|
||||
public static function getOrigin($urlOrPath)
|
||||
{
|
||||
$hostPort = parse_url($urlOrPath, PHP_URL_HOST);
|
||||
if (!$hostPort) {
|
||||
return $urlOrPath;
|
||||
}
|
||||
if (parse_url($urlOrPath, PHP_URL_PORT)) {
|
||||
$hostPort .= ':'.parse_url($urlOrPath, PHP_URL_PORT);
|
||||
}
|
||||
|
||||
return $hostPort;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue