8000 bug #44204 [HttpClient] fix closing curl multi handle when destructin… · symfony/symfony@c552709 · GitHub
[go: up one dir, main page]

Skip to content

Commit c552709

Browse files
bug #44204 [HttpClient] fix closing curl multi handle when destructing client (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [HttpClient] fix closing curl multi handle when destructing client | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #44198 | License | MIT | Doc PR | - Only 4.4 is affected, this borrows from 5.3. Commits ------- f1e258d [HttpClient] fix closing curl multi handle when destructing client
2 parents 5d8993a + f1e258d commit c552709

File tree

2 files changed

+53
-28
lines changed

2 files changed

+53
-28
lines changed

src/Symfony/Component/HttpClient/CurlHttpClient.php

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -336,33 +336,8 @@ public function stream($responses, float $timeout = null): ResponseStreamInterfa
336336

337337
public function reset()
338338
{
339-
if ($this->logger) {
340-
foreach ($this->multi->pushedResponses as $url => $response) {
341-
$this->logger->debug(sprintf('Unused pushed response: "%s"', $url));
342-
}
343-
}
344-
345-
$this->multi->pushedResponses = [];
346-
$this->multi->dnsCache->evictions = $this->multi->dnsCache->evictions ?: $this->multi->dnsCache->removals;
347-
$this->multi->dnsCache->removals = $this->multi->dnsCache->hostnames = [];
348-
349-
if (\is_resource($this->multi->handle) || $this->multi->handle instanceof \CurlMultiHandle) {
350-
if (\defined('CURLMOPT_PU 8000 SHFUNCTION')) {
351-
curl_multi_setopt($this->multi->handle, \CURLMOPT_PUSHFUNCTION, null);
352-
}
353-
354-
$active = 0;
355-
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active));
356-
}
357-
358-
foreach ($this->multi->openHandles as [$ch]) {
359-
if (\is_resource($ch) || $ch instanceof \CurlHandle) {
360-
curl_setopt($ch, \CURLOPT_VERBOSE, false);
361-
}
362-
}
363-
364-
curl_multi_close($this->multi->handle);
365-
$this->multi->handle = curl_multi_init();
339+
$this->multi->logger = $this->logger;
340+
$this->multi->reset();
366341
}
367342

368343
/**
@@ -380,7 +355,7 @@ public function __wakeup()
380355

381356
public function __destruct()
382357
{
383-
$this->reset();
358+
$this->multi->logger = $this->logger;
384359
}
385360

386361
private function handlePush($parent, $pushed, array $requestHeaders, int $maxPendingPushes): int

src/Symfony/Component/HttpClient/Internal/CurlClientState.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\HttpClient\Internal;
1313

14+
use Psr\Log\LoggerInterface;
15+
1416
/**
1517
* Internal representation of the cURL client's state.
1618
*
@@ -26,10 +28,58 @@ final class CurlClientState extends ClientState
2628
public $pushedResponses = [];
2729
/** @var DnsCache */
2830
public $dnsCache;
31+
/** @var LoggerInterface|null */
32+
public $logger;
2933

3034
public function __construct()
3135
{
3236
$this->handle = curl_multi_init();
3337
$this->dnsCache = new DnsCache();
3438
}
39+
40+
public function reset()
41+
{
42+
if ($this->logger) {
43+
foreach ($this->pushedResponses as $url => $response) {
44+
$this->logger->debug(sprintf('Unused pushed response: "%s"', $url));
45+
}
46+
}
47+
48+
$this->pushedResponses = [];
49+
$this->dnsCache->evictions = $this->dnsCache->evictions ?: $this->dnsCache->removals;
50+
$this->dnsCache->removals = $this->dnsCache->hostnames = [];
51+
52+
if (\is_resource($this->handle) || $this->handle instanceof \CurlMultiHandle) {
53+
if (\defined('CURLMOPT_PUSHFUNCTION')) {
54+
curl_multi_setopt($this->handle, \CURLMOPT_PUSHFUNCTION, null);
55+
}
56+
57+
$active = 0;
58+
while (\CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->handle, $active));
59+
}
60+
61+
foreach ($this->openHandles as [$ch]) {
62+
if (\is_resource($ch) || $ch instanceof \CurlHandle) {
63+
curl_setopt($ch, \CURLOPT_VERBOSE, false);
64+
}
65+
}
66+
67+
curl_multi_close($this->handle);
68+
$this->handle = curl_multi_init();
69+
}
70+
71+
public function __sleep(): array
72+
{
73+
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
74+
}
75+
76+
public function __wakeup()
77+
{
78+
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
79+
}
80+
81+
public function __destruct()
82+
{
83+
$this->reset();
84+
}
3585
}

0 commit comments

Comments
 (0)
0