Skip to content

Commit 547f786

Browse files
Merge branch '5.1'
* 5.1: [HttpClient] fix using proxies with NativeHttpClient [4.4] Ignore more deprecations for Mockery mocks [Routing] fix using !important and defaults/reqs in inline route definitions [ErrorHandler][DebugClassLoader] Do not check Mockery mocks classes [HttpClient] Fix using https with proxies [TwigBundle] Only remove kernel exception listener if twig is used [DI] Fix changelog Remove CHANGELOG files for 4.x Adjust expired range check Fix redis connection error message [DI] fix dumping non-shared lazy services
2 parents 3d460a7 + e964c9a commit 547f786

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

NativeHttpClient.php

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,15 +215,18 @@ public function request(string $method, string $url, array $options = []): Respo
215215
$context = stream_context_create($context, ['notification' => $notification]);
216216

217217
$resolver = static function ($multi) use ($context, $options, $url, &$info, $onProgress) {
218-
[$host, $port, $url['authority']] = self::dnsResolve($url, $multi, $info, $onProgress);
218+
[$host, $port] = self::parseHostPort($url, $info);
219219

220220
if (!isset($options['normalized_headers']['host'])) {
221221
$options['headers'][] = 'Host: '.$host.$port;
222222
}
223223

224-
stream_context_set_option($context, 'ssl', 'peer_name', $host);
225224
$proxy = self::getProxy($options['proxy'], $url, $options['no_proxy']);
226-
self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy);
225+
226+
if (!self::configureHeadersAndProxy($context, $host, $options['headers'], $proxy, 'https:' === $url['scheme'])) {
227+
$ip = self::dnsResolve($host, $multi, $info, $onProgress);
228+
$url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host));
229+
}
227230

228231
return [self::createRedirectResolver($options, $host, $proxy, $info, $onProgress), implode('', $url)];
229232
};
@@ -269,9 +272,9 @@ private static function getBodyAsString($body): string
269272
}
270273

271274
/**
272-
* Resolves the IP of the host using the local DNS cache if possible.
275+
* Extracts the host and the port from the URL.
273276
*/
274-
private static function dnsResolve(array $url, NativeClientState $multi, array &$info, ?\Closure $onProgress): array
277+
private static function parseHostPort(array $url, array &$info): array
275278
{
276279
if ($port = parse_url($url['authority'], \PHP_URL_PORT) ?: '') {
277280
$info['primary_port'] = $port;
@@ -280,8 +283,14 @@ private static function dnsResolve(array $url, NativeClientState $multi, array &
280283
$info['primary_port'] = 'http:' === $url['scheme'] ? 80 : 443;
281284
}
282285

283-
$host = parse_url($url['authority'], \PHP_URL_HOST);
286+
return [parse_url($url['authority'], \PHP_URL_HOST), $port];
287+
}
284288

289+
/**
290+
* Resolves the IP of the host using the local DNS cache if possible.
291+
*/
292+
private static function dnsResolve($host, NativeClientState $multi, array &$info, ?\Closure $onProgress): string
293+
{
285294
if (null === $ip = $multi->dnsCache[$host] ?? null) {
286295
$info['debug'] .= "* Hostname was NOT found in DNS cache\n";
287296
$now = microtime(true);
@@ -304,7 +313,7 @@ private static function dnsResolve(array $url, NativeClientState $multi, array &
304313
$onProgress();
305314
}
306315

307-
return [$host, $port, substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host))];
316+
return $ip;
308317
}
309318

310319
/**
@@ -367,24 +376,33 @@ private static function createRedirectResolver(array $options, string $host, ?ar
367376
}
368377
}
369378

370-
[$host, $port, $url['authority']] = self::dnsResolve($url, $multi, $info, $onProgress);
371-
stream_context_set_option($context, 'ssl', 'peer_name', $host);
379+
[$host, $port] = self::parseHostPort($url, $info);
372380

373381
if (false !== (parse_url($location, \PHP_URL_HOST) ?? false)) {
374382
// Authorization and Cookie headers MUST NOT follow except for the initial host name
375383
$requestHeaders = $redirectHeaders['host'] === $host ? $redirectHeaders['with_auth'] : $redirectHeaders['no_auth'];
376384
$requestHeaders[] = 'Host: '.$host.$port;
377-
self::configureHeadersAndProxy($context, $host, $requestHeaders, $proxy);
385+
$dnsResolve = !self::configureHeadersAndProxy($context, $host, $requestHeaders, $proxy, 'https:' === $url['scheme']);
386+
} else {
387+
$dnsResolve = isset(stream_context_get_options($context)['ssl']['peer_name']);
388+
}
389+
390+
if ($dnsResolve) {
391+
$ip = self::dnsResolve($host, $multi, $info, $onProgress);
392+
$url['authority'] = substr_replace($url['authority'], $ip, -\strlen($host) - \strlen($port), \strlen($host));
378393
}
379394

380395
return implode('', $url);
381396
};
382397
}
383398

384-
private static function configureHeadersAndProxy($context, string $host, array $requestHeaders, ?array $proxy): bool
399+
private static function configureHeadersAndProxy($context, string $host, array $requestHeaders, ?array $proxy, bool $isSsl): bool
385400
{
386401
if (null === $proxy) {
387-
return stream_context_set_option($context, 'http', 'header', $requestHeaders);
402+
stream_context_set_option($context, 'http', 'header', $requestHeaders);
403+
stream_context_set_option($context, 'ssl', 'peer_name', $host);
404+
405+
return false;
388406
}
389407

390408
// Matching "no_proxy" should follow the behavior of curl
@@ -393,17 +411,24 @@ private static function configureHeadersAndProxy($context, string $host, array $
393411
$dotRule = '.'.ltrim($rule, '.');
394412

395413
if ('*' === $rule || $host === $rule || substr($host, -\strlen($dotRule)) === $dotRule) {
396-
return stream_context_set_option($context, 'http', 'header', $requestHeaders);
414+
stream_context_set_option($context, 'http', 'proxy', null);
415+
stream_context_set_option($context, 'http', 'request_fulluri', false);
416+
stream_context_set_option($context, 'http', 'header', $requestHeaders);
417+
stream_context_set_option($context, 'ssl', 'peer_name', $host);
418+
419+
return false;
397420
}
398421
}
399422

400-
stream_context_set_option($context, 'http', 'proxy', $proxy['url']);
401-
stream_context_set_option($context, 'http', 'request_fulluri', true);
402-
403423
if (null !== $proxy['auth']) {
404424
$requestHeaders[] = 'Proxy-Authorization: '.$proxy['auth'];
405425
}
406426

407-
return stream_context_set_option($context, 'http', 'header', $requestHeaders);
427+
stream_context_set_option($context, 'http', 'proxy', $proxy['url']);
428+
stream_context_set_option($context, 'http', 'request_fulluri', !$isSsl);
429+
stream_context_set_option($context, 'http', 'header', $requestHeaders);
430+
stream_context_set_option($context, 'ssl', 'peer_name', null);
431+
432+
return true;
408433
}
409434
}

0 commit comments

Comments
 (0)