/**
  * Creates a context supporting HTTP proxies
  *
  * @param  string            $url            URL the context is to be used for
  * @param  array             $defaultOptions Options to merge with the default
  * @param  array             $defaultParams  Parameters to specify on the context
  * @return resource          Default context
  * @throws \RuntimeException if https proxy required and OpenSSL uninstalled
  */
 public static function getContext($url, array $defaultOptions = array(), array $defaultParams = array())
 {
     $options = array('http' => array('follow_location' => 1, 'max_redirects' => 20));
     // Handle system proxy
     if (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy'])) {
         // Some systems seem to rely on a lowercased version instead...
         $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
     }
     // Override with HTTPS proxy if present and URL is https
     if (preg_match('{^https://}i', $url) && (!empty($_SERVER['HTTPS_PROXY']) || !empty($_SERVER['https_proxy']))) {
         $proxy = parse_url(!empty($_SERVER['https_proxy']) ? $_SERVER['https_proxy'] : $_SERVER['HTTPS_PROXY']);
     }
     // Remove proxy if URL matches no_proxy directive
     if (!empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
         $pattern = new NoProxyPattern($_SERVER['no_proxy']);
         if ($pattern->test($url)) {
             unset($proxy);
         }
     }
     if (!empty($proxy)) {
         $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
         $proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
         if (isset($proxy['port'])) {
             $proxyURL .= ":" . $proxy['port'];
         } elseif ('http://' == substr($proxyURL, 0, 7)) {
             $proxyURL .= ":80";
         } elseif ('https://' == substr($proxyURL, 0, 8)) {
             $proxyURL .= ":443";
         }
         // http(s):// is not supported in proxy
         $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
         if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
             throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
         }
         $options['http']['proxy'] = $proxyURL;
         // enabled request_fulluri unless it is explicitly disabled
         switch (parse_url($url, PHP_URL_SCHEME)) {
             case 'http':
                 // default request_fulluri to true
                 $reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
                 if ($reqFullUriEnv === false || $reqFullUriEnv === '' || strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) {
                     $options['http']['request_fulluri'] = true;
                 }
                 break;
             case 'https':
                 // default request_fulluri to true
                 $reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI');
                 if ($reqFullUriEnv === false || $reqFullUriEnv === '' || strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) {
                     $options['http']['request_fulluri'] = true;
                 }
                 break;
         }
         // add SNI opts for https URLs
         if ('https' === parse_url($url, PHP_URL_SCHEME)) {
             $options['ssl']['SNI_enabled'] = true;
             if (version_compare(PHP_VERSION, '5.6.0', '<')) {
                 $options['ssl']['SNI_server_name'] = parse_url($url, PHP_URL_HOST);
             }
         }
         // handle proxy auth if present
         if (isset($proxy['user'])) {
             $auth = urldecode($proxy['user']);
             if (isset($proxy['pass'])) {
                 $auth .= ':' . urldecode($proxy['pass']);
             }
             $auth = base64_encode($auth);
             // Preserve headers if already set in default options
             if (isset($defaultOptions['http']['header'])) {
                 if (is_string($defaultOptions['http']['header'])) {
                     $defaultOptions['http']['header'] = array($defaultOptions['http']['header']);
                 }
                 $defaultOptions['http']['header'][] = "Proxy-Authorization: Basic {$auth}";
             } else {
                 $options['http']['header'] = array("Proxy-Authorization: Basic {$auth}");
             }
         }
     }
     $options = array_replace_recursive($options, $defaultOptions);
     if (isset($options['http']['header'])) {
         $options['http']['header'] = self::fixHttpHeaderField($options['http']['header']);
     }
     return stream_context_create($options, $defaultParams);
 }
 public static function getContext($url, array $defaultOptions = array(), array $defaultParams = array())
 {
     $options = array('http' => array('follow_location' => 1, 'max_redirects' => 20));
     if (!empty($_SERVER['HTTP_PROXY']) || !empty($_SERVER['http_proxy'])) {
         $proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
     }
     if (!empty($proxy)) {
         $proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
         $proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
         if (isset($proxy['port'])) {
             $proxyURL .= ":" . $proxy['port'];
         } elseif ('http://' == substr($proxyURL, 0, 7)) {
             $proxyURL .= ":80";
         } elseif ('https://' == substr($proxyURL, 0, 8)) {
             $proxyURL .= ":443";
         }
         $proxyURL = str_replace(array('http://', 'https://'), array('tcp://', 'ssl://'), $proxyURL);
         if (0 === strpos($proxyURL, 'ssl:') && !extension_loaded('openssl')) {
             throw new \RuntimeException('You must enable the openssl extension to use a proxy over https');
         }
         $options['http']['proxy'] = $proxyURL;
         if (!empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
             $pattern = new NoProxyPattern($_SERVER['no_proxy']);
             if ($pattern->test($url)) {
                 unset($options['http']['proxy']);
             }
         }
         if (!empty($options['http']['proxy'])) {
             switch (parse_url($url, PHP_URL_SCHEME)) {
                 case 'http':
                     $reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
                     if ($reqFullUriEnv === false || $reqFullUriEnv === '' || strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) {
                         $options['http']['request_fulluri'] = true;
                     }
                     break;
                 case 'https':
                     $reqFullUriEnv = getenv('HTTPS_PROXY_REQUEST_FULLURI');
                     if ($reqFullUriEnv === false || $reqFullUriEnv === '' || strtolower($reqFullUriEnv) !== 'false' && (bool) $reqFullUriEnv) {
                         $options['http']['request_fulluri'] = true;
                     }
                     break;
             }
             if (isset($proxy['user'])) {
                 $auth = urldecode($proxy['user']);
                 if (isset($proxy['pass'])) {
                     $auth .= ':' . urldecode($proxy['pass']);
                 }
                 $auth = base64_encode($auth);
                 if (isset($defaultOptions['http']['header'])) {
                     if (is_string($defaultOptions['http']['header'])) {
                         $defaultOptions['http']['header'] = array($defaultOptions['http']['header']);
                     }
                     $defaultOptions['http']['header'][] = "Proxy-Authorization: Basic {$auth}";
                 } else {
                     $options['http']['header'] = array("Proxy-Authorization: Basic {$auth}");
                 }
             }
         }
     }
     $options = array_replace_recursive($options, $defaultOptions);
     if (isset($options['http']['header'])) {
         $options['http']['header'] = self::fixHttpHeaderField($options['http']['header']);
     }
     return stream_context_create($options, $defaultParams);
 }