Url.php 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. /*
  3. * This file is part of Composer.
  4. *
  5. * (c) Nils Adermann <naderman@naderman.de>
  6. * Jordi Boggiano <j.boggiano@seld.be>
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. namespace Composer\Util;
  12. use Composer\Config;
  13. /**
  14. * @author Jordi Boggiano <j.boggiano@seld.be>
  15. */
  16. class Url
  17. {
  18. /**
  19. * @param Config $config
  20. * @param string $url
  21. * @param string $ref
  22. * @return string the updated URL
  23. */
  24. public static function updateDistReference(Config $config, $url, $ref)
  25. {
  26. $host = parse_url($url, PHP_URL_HOST);
  27. if ($host === 'api.github.com' || $host === 'github.com' || $host === 'www.github.com') {
  28. if (preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/(zip|tar)ball/(.+)$}i', $url, $match)) {
  29. // update legacy github archives to API calls with the proper reference
  30. $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
  31. } elseif (preg_match('{^https?://(?:www\.)?github\.com/([^/]+)/([^/]+)/archive/.+\.(zip|tar)(?:\.gz)?$}i', $url, $match)) {
  32. // update current github web archives to API calls with the proper reference
  33. $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
  34. } elseif (preg_match('{^https?://api\.github\.com/repos/([^/]+)/([^/]+)/(zip|tar)ball(?:/.+)?$}i', $url, $match)) {
  35. // update api archives to the proper reference
  36. $url = 'https://api.github.com/repos/' . $match[1] . '/'. $match[2] . '/' . $match[3] . 'ball/' . $ref;
  37. }
  38. } elseif ($host === 'bitbucket.org' || $host === 'www.bitbucket.org') {
  39. if (preg_match('{^https?://(?:www\.)?bitbucket\.org/([^/]+)/([^/]+)/get/(.+)\.(zip|tar\.gz|tar\.bz2)$}i', $url, $match)) {
  40. // update Bitbucket archives to the proper reference
  41. $url = 'https://bitbucket.org/' . $match[1] . '/'. $match[2] . '/get/' . $ref . '.' . $match[4];
  42. }
  43. } elseif ($host === 'gitlab.com' || $host === 'www.gitlab.com') {
  44. if (preg_match('{^https?://(?:www\.)?gitlab\.com/api/v[34]/projects/([^/]+)/repository/archive\.(zip|tar\.gz|tar\.bz2|tar)\?sha=.+$}i', $url, $match)) {
  45. // update Gitlab archives to the proper reference
  46. $url = 'https://gitlab.com/api/v4/projects/' . $match[1] . '/repository/archive.' . $match[2] . '?sha=' . $ref;
  47. }
  48. } elseif (in_array($host, $config->get('github-domains'), true)) {
  49. $url = preg_replace('{(/repos/[^/]+/[^/]+/(zip|tar)ball)(?:/.+)?$}i', '$1/'.$ref, $url);
  50. } elseif (in_array($host, $config->get('gitlab-domains'), true)) {
  51. $url = preg_replace('{(/api/v[34]/projects/[^/]+/repository/archive\.(?:zip|tar\.gz|tar\.bz2|tar)\?sha=).+$}i', '${1}'.$ref, $url);
  52. }
  53. return $url;
  54. }
  55. /**
  56. * @param string $url
  57. * @return string
  58. */
  59. public static function getOrigin(Config $config, $url)
  60. {
  61. if (0 === strpos($url, 'file://')) {
  62. return $url;
  63. }
  64. $origin = (string) parse_url($url, PHP_URL_HOST);
  65. if (strpos($origin, '.github.com') === (strlen($origin) - 11)) {
  66. return 'github.com';
  67. }
  68. if ($origin === 'repo.packagist.org') {
  69. return 'packagist.org';
  70. }
  71. if ($origin === '') {
  72. $origin = $url;
  73. }
  74. // Gitlab can be installed in a non-root context (i.e. gitlab.com/foo). When downloading archives the originUrl
  75. // is the host without the path, so we look for the registered gitlab-domains matching the host here
  76. if (
  77. is_array($config->get('gitlab-domains'))
  78. && false === strpos($origin, '/')
  79. && !in_array($origin, $config->get('gitlab-domains'))
  80. ) {
  81. foreach ($config->get('gitlab-domains') as $gitlabDomain) {
  82. if (0 === strpos($gitlabDomain, $origin)) {
  83. return $gitlabDomain;
  84. }
  85. }
  86. }
  87. return $origin;
  88. }
  89. }