StreamContextFactory.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. /**
  13. * Allows the creation of a basic context supporting http proxy
  14. *
  15. * @author Jordan Alliot <jordan.alliot@gmail.com>
  16. */
  17. final class StreamContextFactory
  18. {
  19. /**
  20. * Creates a context supporting HTTP proxies
  21. *
  22. * @param array $defaultOptions Options to merge with the default
  23. * @param array $defaultParams Parameters to specify on the context
  24. * @return resource Default context
  25. * @throws \RuntimeException if https proxy required and OpenSSL uninstalled
  26. */
  27. static public function getContext(array $defaultOptions = array(), array $defaultParams = array())
  28. {
  29. $options = array('http' => array());
  30. // Handle system proxy
  31. if (isset($_SERVER['HTTP_PROXY']) || isset($_SERVER['http_proxy'])) {
  32. // Some systems seem to rely on a lowercased version instead...
  33. $proxy = isset($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY'];
  34. $proxyURL = parse_url($proxy, PHP_URL_SCHEME) . "://";
  35. $proxyURL .= parse_url($proxy, PHP_URL_HOST);
  36. $proxyPort = parse_url($proxy, PHP_URL_PORT);
  37. if (isset($proxyPort)) {
  38. $proxyURL .= ":" . $proxyPort;
  39. } else if ('http://' == substr($proxyURL, 0, 7)) {
  40. $proxyURL .= ":80";
  41. } else if ('https://' == substr($proxyURL, 0, 8)) {
  42. $proxyURL .= ":443";
  43. }
  44. // http(s):// is not supported in proxy
  45. $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
  46. if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
  47. throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
  48. }
  49. $options['http'] = array(
  50. 'proxy' => $proxyURL,
  51. 'request_fulluri' => true,
  52. );
  53. // Extract authentication credentials from the proxy url
  54. $user = parse_url($proxy, PHP_URL_USER);
  55. $pass = parse_url($proxy, PHP_URL_PASS);
  56. if (isset($user)) {
  57. $auth = $user;
  58. if (isset($pass)) {
  59. $auth .= ":{$pass}";
  60. }
  61. $auth = base64_encode($auth);
  62. // Preserve headers if already set in default options
  63. if (isset($defaultOptions['http']['header'])) {
  64. $defaultOptions['http']['header'] .= "Proxy-Authorization: Basic {$auth}\r\n";
  65. } else {
  66. $options['http']['header'] = "Proxy-Authorization: Basic {$auth}\r\n";
  67. }
  68. }
  69. }
  70. $options = array_merge_recursive($options, $defaultOptions);
  71. return stream_context_create($options, $defaultParams);
  72. }
  73. }