Add suppor for https_proxy, fixes #3204
parent
4a3bc58adf
commit
4a6503fe36
|
@ -43,6 +43,19 @@ final class StreamContextFactory
|
||||||
$proxy = parse_url(!empty($_SERVER['http_proxy']) ? $_SERVER['http_proxy'] : $_SERVER['HTTP_PROXY']);
|
$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)) {
|
if (!empty($proxy)) {
|
||||||
$proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
|
$proxyURL = isset($proxy['scheme']) ? $proxy['scheme'] . '://' : '';
|
||||||
$proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
|
$proxyURL .= isset($proxy['host']) ? $proxy['host'] : '';
|
||||||
|
@ -64,48 +77,38 @@ final class StreamContextFactory
|
||||||
|
|
||||||
$options['http']['proxy'] = $proxyURL;
|
$options['http']['proxy'] = $proxyURL;
|
||||||
|
|
||||||
// Handle no_proxy directive
|
// enabled request_fulluri unless it is explicitly disabled
|
||||||
if (!empty($_SERVER['no_proxy']) && parse_url($url, PHP_URL_HOST)) {
|
switch (parse_url($url, PHP_URL_SCHEME)) {
|
||||||
$pattern = new NoProxyPattern($_SERVER['no_proxy']);
|
case 'http': // default request_fulluri to true
|
||||||
if ($pattern->test($url)) {
|
$reqFullUriEnv = getenv('HTTP_PROXY_REQUEST_FULLURI');
|
||||||
unset($options['http']['proxy']);
|
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 request_fulluri and authentication if we still have a proxy to connect to
|
// handle proxy auth if present
|
||||||
if (!empty($options['http']['proxy'])) {
|
if (isset($proxy['user'])) {
|
||||||
// enabled request_fulluri unless it is explicitly disabled
|
$auth = urldecode($proxy['user']);
|
||||||
switch (parse_url($url, PHP_URL_SCHEME)) {
|
if (isset($proxy['pass'])) {
|
||||||
case 'http': // default request_fulluri to true
|
$auth .= ':' . urldecode($proxy['pass']);
|
||||||
$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;
|
|
||||||
}
|
}
|
||||||
|
$auth = base64_encode($auth);
|
||||||
|
|
||||||
if (isset($proxy['user'])) {
|
// Preserve headers if already set in default options
|
||||||
$auth = urldecode($proxy['user']);
|
if (isset($defaultOptions['http']['header'])) {
|
||||||
if (isset($proxy['pass'])) {
|
if (is_string($defaultOptions['http']['header'])) {
|
||||||
$auth .= ':' . urldecode($proxy['pass']);
|
$defaultOptions['http']['header'] = array($defaultOptions['http']['header']);
|
||||||
}
|
|
||||||
$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}");
|
|
||||||
}
|
}
|
||||||
|
$defaultOptions['http']['header'][] = "Proxy-Authorization: Basic {$auth}";
|
||||||
|
} else {
|
||||||
|
$options['http']['header'] = array("Proxy-Authorization: Basic {$auth}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
unset($_SERVER['HTTP_PROXY']);
|
unset($_SERVER['HTTP_PROXY']);
|
||||||
unset($_SERVER['http_proxy']);
|
unset($_SERVER['http_proxy']);
|
||||||
|
unset($_SERVER['HTTPS_PROXY']);
|
||||||
|
unset($_SERVER['https_proxy']);
|
||||||
unset($_SERVER['no_proxy']);
|
unset($_SERVER['no_proxy']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +29,8 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
unset($_SERVER['HTTP_PROXY']);
|
unset($_SERVER['HTTP_PROXY']);
|
||||||
unset($_SERVER['http_proxy']);
|
unset($_SERVER['http_proxy']);
|
||||||
|
unset($_SERVER['HTTPS_PROXY']);
|
||||||
|
unset($_SERVER['https_proxy']);
|
||||||
unset($_SERVER['no_proxy']);
|
unset($_SERVER['no_proxy']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +130,7 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net';
|
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net';
|
||||||
|
|
||||||
$context = StreamContextFactory::getContext('http://example.org', array('http' => array('method' => 'GET')));
|
$context = StreamContextFactory::getContext('https://example.org', array('http' => array('method' => 'GET')));
|
||||||
$options = stream_context_get_options($context);
|
$options = stream_context_get_options($context);
|
||||||
|
|
||||||
$this->assertEquals(array('http' => array(
|
$this->assertEquals(array('http' => array(
|
||||||
|
@ -139,6 +143,23 @@ class StreamContextFactoryTest extends \PHPUnit_Framework_TestCase
|
||||||
)), $options);
|
)), $options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testHttpsProxyOverride()
|
||||||
|
{
|
||||||
|
$_SERVER['http_proxy'] = 'http://username:password@proxyserver.net';
|
||||||
|
$_SERVER['http_proxy'] = 'https://woopproxy.net';
|
||||||
|
|
||||||
|
$context = StreamContextFactory::getContext('https://example.org', array('http' => array('method' => 'GET')));
|
||||||
|
$options = stream_context_get_options($context);
|
||||||
|
|
||||||
|
$this->assertEquals(array('http' => array(
|
||||||
|
'proxy' => 'ssl://woopproxy.net:443',
|
||||||
|
'request_fulluri' => true,
|
||||||
|
'method' => 'GET',
|
||||||
|
'max_redirects' => 20,
|
||||||
|
'follow_location' => 1,
|
||||||
|
)), $options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @dataProvider dataSSLProxy
|
* @dataProvider dataSSLProxy
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue