Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit c6fe585

Browse filesBrowse files
Merge branch '5.4' into 6.4
* 5.4: [VarDumper] Fix test suite with PHP 8.4 [DoctrineBridge] Add missing return type [Mailer] Fix sendmail transport not handling failure [HttpClient] Lazily initialize CurlClientState updating missing translations for Greek #53768 [Validator] Allow BICs’ first four characters to be digits [ErrorHandler] Fix exit code when an exception occurs and the exception handler has been unregistered [Validator] Review Arabic translations and add correct translations.
2 parents ded8034 + ef00caa commit c6fe585
Copy full SHA for c6fe585

File tree

Expand file treeCollapse file tree

2 files changed

+44
-21
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+44
-21
lines changed

‎CurlHttpClient.php

Copy file name to clipboardExpand all lines: CurlHttpClient.php
+42-19Lines changed: 42 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
5151

5252
private ?LoggerInterface $logger = null;
5353

54+
private int $maxHostConnections;
55+
private int $maxPendingPushes;
56+
5457
/**
5558
* An internal object to share state between the client and its responses.
5659
*/
@@ -69,25 +72,31 @@ public function __construct(array $defaultOptions = [], int $maxHostConnections
6972
throw new \LogicException('You cannot use the "Symfony\Component\HttpClient\CurlHttpClient" as the "curl" extension is not installed.');
7073
}
7174

75+
$this->maxHostConnections = $maxHostConnections;
76+
$this->maxPendingPushes = $maxPendingPushes;
77+
7278
$this->defaultOptions['buffer'] ??= self::shouldBuffer(...);
7379

7480
if ($defaultOptions) {
7581
[, $this->defaultOptions] = self::prepareRequest(null, null, $defaultOptions, $this->defaultOptions);
7682
}
77-
78-
$this->multi = new CurlClientState($maxHostConnections, $maxPendingPushes);
7983
}
8084

8185
public function setLogger(LoggerInterface $logger): void
8286
{
83-
$this->logger = $this->multi->logger = $logger;
87+
$this->logger = $logger;
88+
if (isset($this->multi)) {
89+
$this->multi->logger = $logger;
90+
}
8491
}
8592

8693
/**
8794
* @see HttpClientInterface::OPTIONS_DEFAULTS for available options
8895
*/
8996
public function request(string $method, string $url, array $options = []): ResponseInterface
9097
{
98+
$multi = $this->ensureState();
99+
91100
[$url, $options] = self::prepareRequest($method, $url, $options, $this->defaultOptions);
92101
$scheme = $url['scheme'];
93102
$authority = $url['authority'];
@@ -165,24 +174,24 @@ public function request(string $method, string $url, array $options = []): Respo
165174
}
166175

167176
// curl's resolve feature varies by host:port but ours varies by host only, let's handle this with our own DNS map
168-
if (isset($this->multi->dnsCache->hostnames[$host])) {
169-
$options['resolve'] += [$host => $this->multi->dnsCache->hostnames[$host]];
177+
if (isset($multi->dnsCache->hostnames[$host])) {
178+
$options['resolve'] += [$host => $multi->dnsCache->hostnames[$host]];
170179
}
171180

172-
if ($options['resolve'] || $this->multi->dnsCache->evictions) {
181+
if ($options['resolve'] || $multi->dnsCache->evictions) {
173182
// First reset any old DNS cache entries then add the new ones
174-
$resolve = $this->multi->dnsCache->evictions;
175-
$this->multi->dnsCache->evictions = [];
183+
$resolve = $multi->dnsCache->evictions;
184+
$multi->dnsCache->evictions = [];
176185

177186
if ($resolve && 0x072A00 > CurlClientState::$curlVersion['version_number']) {
178187
// DNS cache removals require curl 7.42 or higher
179-
$this->multi->reset();
188+
$multi->reset();
180189
}
181190

182191
foreach ($options['resolve'] as $host => $ip) {
183192
$resolve[] = null === $ip ? "-$host:$port" : "$host:$port:$ip";
184-
$this->multi->dnsCache->hostnames[$host] = $ip;
185-
$this->multi->dnsCache->removals["-$host:$port"] = "-$host:$port";
193+
$multi->dnsCache->hostnames[$host] = $ip;
194+
$multi->dnsCache->removals["-$host:$port"] = "-$host:$port";
186195
}
187196

188197
$curlopts[\CURLOPT_RESOLVE] = $resolve;
@@ -285,16 +294,16 @@ public function request(string $method, string $url, array $options = []): Respo
285294
$curlopts += $options['extra']['curl'];
286295
}
287296

288-
if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) {
289-
unset($this->multi->pushedResponses[$url]);
297+
if ($pushedResponse = $multi->pushedResponses[$url] ?? null) {
298+
unset($multi->pushedResponses[$url]);
290299

291300
if (self::acceptPushForRequest($method, $options, $pushedResponse)) {
292301
$this->logger?->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url));
293302

294303
// Reinitialize the pushed response with request's options
295304
$ch = $pushedResponse->handle;
296305
$pushedResponse = $pushedResponse->response;
297-
$pushedResponse->__construct($this->multi, $url, $options, $this->logger);
306+
$pushedResponse->__construct($multi, $url, $options, $this->logger);
298307
} else {
299308
$this->logger?->debug(sprintf('Rejecting pushed response: "%s"', $url));
300309
$pushedResponse = null;
@@ -304,7 +313,7 @@ public function request(string $method, string $url, array $options = []): Respo
304313
if (!$pushedResponse) {
305314
$ch = curl_init();
306315
$this->logger?->info(sprintf('Request: "%s %s"', $method, $url));
307-
$curlopts += [\CURLOPT_SHARE => $this->multi->share];
316+
$curlopts += [\CURLOPT_SHARE => $multi->share];
308317
}
309318

310319
foreach ($curlopts as $opt => $value) {
@@ -314,7 +323,7 @@ public function request(string $method, string $url, array $options = []): Respo
314323
}
315324
}
316325

317-
return $pushedResponse ?? new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host, $port), CurlClientState::$curlVersion['version_number'], $url);
326+
return $pushedResponse ?? new CurlResponse($multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host, $port), CurlClientState::$curlVersion['version_number'], $url);
318327
}
319328

320329
public function stream(ResponseInterface|iterable $responses, ?float $timeout = null): ResponseStreamInterface
@@ -323,9 +332,11 @@ public function stream(ResponseInterface|iterable $responses, ?float $timeout =
323332
$responses = [$responses];
324333
}
325334

326-
if ($this->multi->handle instanceof \CurlMultiHandle) {
335+
$multi = $this->ensureState();
336+
337+
if ($multi->handle instanceof \CurlMultiHandle) {
327338
$active = 0;
328-
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active)) {
339+
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($multi->handle, $active)) {
329340
}
330341
}
331342

@@ -334,7 +345,9 @@ public function stream(ResponseInterface|iterable $responses, ?float $timeout =
334345

335346
public function reset(): void
336347
{
337-
$this->multi->reset();
348+
if (isset($this->multi)) {
349+
$this->multi->reset();
350+
}
338351
}
339352

340353
/**
@@ -434,6 +447,16 @@ private static function createRedirectResolver(array $options, string $host, int
434447
};
435448
}
436449

450+
private function ensureState(): CurlClientState
451+
{
452+
if (!isset($this->multi)) {
453+
$this->multi = new CurlClientState($this->maxHostConnections, $this->maxPendingPushes);
454+
$this->multi->logger = $this->logger;
455+
}
456+
457+
return $this->multi;
458+
}
459+
437460
private function findConstantName(int $opt): ?string
438461
{
439462
$constants = array_filter(get_defined_constants(), static fn ($v, $k) => $v === $opt && 'C' === $k[0] && (str_starts_with($k, 'CURLOPT_') || str_starts_with($k, 'CURLINFO_')), \ARRAY_FILTER_USE_BOTH);

‎Tests/CurlHttpClientTest.php

Copy file name to clipboardExpand all lines: Tests/CurlHttpClientTest.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ public function testHandleIsReinitOnReset()
5858
{
5959
$httpClient = $this->getHttpClient(__FUNCTION__);
6060

61-
$r = new \ReflectionProperty($httpClient, 'multi');
62-
$clientState = $r->getValue($httpClient);
61+
$r = new \ReflectionMethod($httpClient, 'ensureState');
62+
$clientState = $r->invoke($httpClient);
6363
$initialShareId = $clientState->share;
6464
$httpClient->reset();
6565
self::assertNotSame($initialShareId, $clientState->share);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.