"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/Symfony/Component/HttpClient/NativeHttpClient.php" between
symfony-4.4.14.tar.gz and symfony-4.4.15.tar.gz

About: Symfony is a web application framework for PHP projects. Source code (4.4 series).

NativeHttpClient.php  (symfony-4.4.14):NativeHttpClient.php  (symfony-4.4.15)
skipping to change at line 174 skipping to change at line 174
$onProgress($dlNow, $dlSize); $onProgress($dlNow, $dlSize);
} }
}; };
if ($options['resolve']) { if ($options['resolve']) {
$this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCach e; $this->multi->dnsCache = $options['resolve'] + $this->multi->dnsCach e;
} }
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method , implode('', $url))); $this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method , implode('', $url)));
[$host, $port, $url['authority']] = self::dnsResolve($url, $this->multi, $info, $onProgress); [$host, $port] = self::parseHostPort($url, $info);
if (!isset($options['normalized_headers']['host'])) { if (!isset($options['normalized_headers']['host'])) {
$options['headers'][] = 'Host: '.$host.$port; $options['headers'][] = 'Host: '.$host.$port;
} }
if (!isset($options['normalized_headers']['user-agent'])) { if (!isset($options['normalized_headers']['user-agent'])) {
$options['headers'][] = 'User-Agent: Symfony HttpClient/Native'; $options['headers'][] = 'User-Agent: Symfony HttpClient/Native';
} }
if (0 < $options['max_duration']) { if (0 < $options['max_duration']) {
skipping to change at line 201 skipping to change at line 201
'method' => $method, 'method' => $method,
'content' => $options['body'], 'content' => $options['body'],
'ignore_errors' => true, 'ignore_errors' => true,
'curl_verify_ssl_peer' => $options['verify_peer'], 'curl_verify_ssl_peer' => $options['verify_peer'],
'curl_verify_ssl_host' => $options['verify_host'], 'curl_verify_ssl_host' => $options['verify_host'],
'auto_decode' => false, // Disable dechunk filter, it's incompat ible with stream_select() 'auto_decode' => false, // Disable dechunk filter, it's incompat ible with stream_select()
'timeout' => $options['timeout'], 'timeout' => $options['timeout'],
'follow_location' => false, // We follow redirects ourselves - t he native logic is too limited 'follow_location' => false, // We follow redirects ourselves - t he native logic is too limited
], ],
'ssl' => array_filter([ 'ssl' => array_filter([
'peer_name' => $host,
'verify_peer' => $options['verify_peer'], 'verify_peer' => $options['verify_peer'],
'verify_peer_name' => $options['verify_host'], 'verify_peer_name' => $options['verify_host'],
'cafile' => $options['cafile'], 'cafile' => $options['cafile'],
'capath' => $options['capath'], 'capath' => $options['capath'],
'local_cert' => $options['local_cert'], 'local_cert' => $options['local_cert'],
'local_pk' => $options['local_pk'], 'local_pk' => $options['local_pk'],
'passphrase' => $options['passphrase'], 'passphrase' => $options['passphrase'],
'ciphers' => $options['ciphers'], 'ciphers' => $options['ciphers'],
'peer_fingerprint' => $options['peer_fingerprint'], 'peer_fingerprint' => $options['peer_fingerprint'],
'capture_peer_cert_chain' => $options['capture_peer_cert_chain'] , 'capture_peer_cert_chain' => $options['capture_peer_cert_chain'] ,
skipping to change at line 228 skipping to change at line 227
'tcp_nodelay' => true, 'tcp_nodelay' => true,
], ],
]; ];
$proxy = self::getProxy($options['proxy'], $url); $proxy = self::getProxy($options['proxy'], $url);
$noProxy = $options['no_proxy'] ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_ PROXY'] ?? ''; $noProxy = $options['no_proxy'] ?? $_SERVER['no_proxy'] ?? $_SERVER['NO_ PROXY'] ?? '';
$noProxy = $noProxy ? preg_split('/[\s,]+/', $noProxy) : []; $noProxy = $noProxy ? preg_split('/[\s,]+/', $noProxy) : [];
$resolveRedirect = self::createRedirectResolver($options, $host, $proxy, $noProxy, $info, $onProgress); $resolveRedirect = self::createRedirectResolver($options, $host, $proxy, $noProxy, $info, $onProgress);
$context = stream_context_create($context, ['notification' => $notificat ion]); $context = stream_context_create($context, ['notification' => $notificat ion]);
self::configureHeadersAndProxy($context, $host, $options['headers'], $pr
oxy, $noProxy); if (!self::configureHeadersAndProxy($context, $host, $options['headers']
, $proxy, $noProxy, 'https:' === $url['scheme'])) {
$ip = self::dnsResolve($host, $this->multi, $info, $onProgress);
$url['authority'] = substr_replace($url['authority'], $ip, -\strlen(
$host) - \strlen($port), \strlen($host));
}
return new NativeResponse($this->multi, $context, implode('', $url), $op tions, $info, $resolveRedirect, $onProgress, $this->logger); return new NativeResponse($this->multi, $context, implode('', $url), $op tions, $info, $resolveRedirect, $onProgress, $this->logger);
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function stream($responses, float $timeout = null): ResponseStreamInt erface public function stream($responses, float $timeout = null): ResponseStreamInt erface
{ {
if ($responses instanceof NativeResponse) { if ($responses instanceof NativeResponse) {
skipping to change at line 309 skipping to change at line 312
throw new TransportException(sprintf('Unsupported proxy scheme "%s": "http" or "https" expected.', $proxy['scheme'])); throw new TransportException(sprintf('Unsupported proxy scheme "%s": "http" or "https" expected.', $proxy['scheme']));
} }
return [ return [
'url' => $proxyUrl, 'url' => $proxyUrl,
'auth' => isset($proxy['user']) ? 'Basic '.base64_encode(rawurldecod e($proxy['user']).':'.rawurldecode($proxy['pass'] ?? '')) : null, 'auth' => isset($proxy['user']) ? 'Basic '.base64_encode(rawurldecod e($proxy['user']).':'.rawurldecode($proxy['pass'] ?? '')) : null,
]; ];
} }
/** /**
* Resolves the IP of the host using the local DNS cache if possible. * Extracts the host and the port from the URL.
*/ */
private static function dnsResolve(array $url, NativeClientState $multi, arr ay &$info, ?\Closure $onProgress): array private static function parseHostPort(array $url, array &$info): array
{ {
if ($port = parse_url($url['authority'], \PHP_URL_PORT) ?: '') { if ($port = parse_url($url['authority'], \PHP_URL_PORT) ?: '') {
$info['primary_port'] = $port; $info['primary_port'] = $port;
$port = ':'.$port; $port = ':'.$port;
} else { } else {
$info['primary_port'] = 'http:' === $url['scheme'] ? 80 : 443; $info['primary_port'] = 'http:' === $url['scheme'] ? 80 : 443;
} }
$host = parse_url($url['authority'], \PHP_URL_HOST); return [parse_url($url['authority'], \PHP_URL_HOST), $port];
}
/**
* Resolves the IP of the host using the local DNS cache if possible.
*/
private static function dnsResolve($host, NativeClientState $multi, array &$
info, ?\Closure $onProgress): string
{
if (null === $ip = $multi->dnsCache[$host] ?? null) { if (null === $ip = $multi->dnsCache[$host] ?? null) {
$info['debug'] .= "* Hostname was NOT found in DNS cache\n"; $info['debug'] .= "* Hostname was NOT found in DNS cache\n";
$now = microtime(true); $now = microtime(true);
if (!$ip = gethostbynamel($host)) { if (!$ip = gethostbynamel($host)) {
throw new TransportException(sprintf('Could not resolve host "%s ".', $host)); throw new TransportException(sprintf('Could not resolve host "%s ".', $host));
} }
$info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now); $info['namelookup_time'] = microtime(true) - ($info['start_time'] ?: $now);
$multi->dnsCache[$host] = $ip = $ip[0]; $multi->dnsCache[$host] = $ip = $ip[0];
skipping to change at line 344 skipping to change at line 353
$info['debug'] .= "* Hostname was found in DNS cache\n"; $info['debug'] .= "* Hostname was found in DNS cache\n";
} }
$info['primary_ip'] = $ip; $info['primary_ip'] = $ip;
if ($onProgress) { if ($onProgress) {
// Notify DNS resolution // Notify DNS resolution
$onProgress(); $onProgress();
} }
return [$host, $port, substr_replace($url['authority'], $ip, -\strlen($h ost) - \strlen($port), \strlen($host))]; return $ip;
} }
/** /**
* Handles redirects - the native logic is too buggy to be used. * Handles redirects - the native logic is too buggy to be used.
*/ */
private static function createRedirectResolver(array $options, string $host, ?array $proxy, array $noProxy, array &$info, ?\Closure $onProgress): \Closure private static function createRedirectResolver(array $options, string $host, ?array $proxy, array $noProxy, array &$info, ?\Closure $onProgress): \Closure
{ {
$redirectHeaders = []; $redirectHeaders = [];
if (0 < $maxRedirects = $options['max_redirects']) { if (0 < $maxRedirects = $options['max_redirects']) {
$redirectHeaders = ['host' => $host]; $redirectHeaders = ['host' => $host];
skipping to change at line 407 skipping to change at line 416
$info['http_method'] = $options['method'] = 'HEAD' === $opti ons['method'] ? 'HEAD' : 'GET'; $info['http_method'] = $options['method'] = 'HEAD' === $opti ons['method'] ? 'HEAD' : 'GET';
$options['content'] = ''; $options['content'] = '';
$options['header'] = array_filter($options['header'], static function ($h) { $options['header'] = array_filter($options['header'], static function ($h) {
return 0 !== stripos($h, 'Content-Length:') && 0 !== str ipos($h, 'Content-Type:'); return 0 !== stripos($h, 'Content-Length:') && 0 !== str ipos($h, 'Content-Type:');
}); });
stream_context_set_option($context, ['http' => $options]); stream_context_set_option($context, ['http' => $options]);
} }
} }
[$host, $port, $url['authority']] = self::dnsResolve($url, $multi, $ [$host, $port] = self::parseHostPort($url, $info);
info, $onProgress);
stream_context_set_option($context, 'ssl', 'peer_name', $host);
if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) { if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) {
// Authorization and Cookie headers MUST NOT follow except for t he initial host name // Authorization and Cookie headers MUST NOT follow except for t he initial host name
$requestHeaders = $redirectHeaders['host'] === $host ? $redirect Headers['with_auth'] : $redirectHeaders['no_auth']; $requestHeaders = $redirectHeaders['host'] === $host ? $redirect Headers['with_auth'] : $redirectHeaders['no_auth'];
$requestHeaders[] = 'Host: '.$host.$port; $requestHeaders[] = 'Host: '.$host.$port;
self::configureHeadersAndProxy($context, $host, $requestHeaders, $dnsResolve = !self::configureHeadersAndProxy($context, $host, $
$proxy, $noProxy); requestHeaders, $proxy, $noProxy, 'https:' === $url['scheme']);
} else {
$dnsResolve = isset(stream_context_get_options($context)['ssl'][
'peer_name']);
}
if ($dnsResolve) {
$ip = self::dnsResolve($host, $multi, $info, $onProgress);
$url['authority'] = substr_replace($url['authority'], $ip, -\str
len($host) - \strlen($port), \strlen($host));
} }
return implode('', $url); return implode('', $url);
}; };
} }
private static function configureHeadersAndProxy($context, string $host, arr ay $requestHeaders, ?array $proxy, array $noProxy) private static function configureHeadersAndProxy($context, string $host, arr ay $requestHeaders, ?array $proxy, array $noProxy, bool $isSsl): bool
{ {
if (null === $proxy) { if (null === $proxy) {
return stream_context_set_option($context, 'http', 'header', $reques stream_context_set_option($context, 'http', 'header', $requestHeader
tHeaders); s);
stream_context_set_option($context, 'ssl', 'peer_name', $host);
return false;
} }
// Matching "no_proxy" should follow the behavior of curl // Matching "no_proxy" should follow the behavior of curl
foreach ($noProxy as $rule) { foreach ($noProxy as $rule) {
$dotRule = '.'.ltrim($rule, '.'); $dotRule = '.'.ltrim($rule, '.');
if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotR ule)) === $dotRule) { if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotR ule)) === $dotRule) {
return stream_context_set_option($context, 'http', 'header', $re stream_context_set_option($context, 'http', 'proxy', null);
questHeaders); stream_context_set_option($context, 'http', 'request_fulluri', f
alse);
stream_context_set_option($context, 'http', 'header', $requestHe
aders);
stream_context_set_option($context, 'ssl', 'peer_name', $host);
return false;
} }
} }
stream_context_set_option($context, 'http', 'proxy', $proxy['url']);
stream_context_set_option($context, 'http', 'request_fulluri', true);
if (null !== $proxy['auth']) { if (null !== $proxy['auth']) {
$requestHeaders[] = 'Proxy-Authorization: '.$proxy['auth']; $requestHeaders[] = 'Proxy-Authorization: '.$proxy['auth'];
} }
return stream_context_set_option($context, 'http', 'header', $requestHea stream_context_set_option($context, 'http', 'proxy', $proxy['url']);
ders); stream_context_set_option($context, 'http', 'request_fulluri', !$isSsl);
stream_context_set_option($context, 'http', 'header', $requestHeaders);
stream_context_set_option($context, 'ssl', 'peer_name', null);
return true;
} }
} }
 End of changes. 15 change blocks. 
23 lines changed or deleted 51 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)