bug #34287 [HttpClient] Fix a crash when calling CurlHttpClient::__destruct() (dunglas)

This PR was merged into the 4.3 branch.

Discussion
----------

[HttpClient] Fix a crash when calling CurlHttpClient::__destruct()

| Q             | A
| ------------- | ---
| Branch?       | 4.3
| Bug fix?      | yes
| New feature?  | no <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | n/a
| License       | MIT
| Doc PR        | n/a

I've not identified the exact issue, but when the profiler is enabled, an HttpClient instance is created and not used, then a crash occurs when `__destruct()` is called because `$this->mutli->handle` value is `0` has this point, while `curl_multi_setopt` expect a `resource`.

This PR fixes the issue, but it's maybe not the good approach.

Reproducer: symfony/mercure-bundle#14

curl version: 7.67.0

```
php -v
PHP 7.3.11 (cli) (built: Oct 24 2019 11:29:52) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.11, Copyright (c) 1999-2018, by Zend Technologies
    with blackfire v1.27.1~mac-x64-non_zts73, https://blackfire.io, by Blackfire
```

Commits
-------

d2c5ffda52 [HttpClient] Fix a crash when calling CurlHttpClient::__destruct()
This commit is contained in:
Nicolas Grekas 2019-11-08 09:24:00 +01:00
commit 201d17181a

View File

@ -301,15 +301,20 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface
public function __destruct()
{
$this->multi->pushedResponses = [];
if (\defined('CURLMOPT_PUSHFUNCTION')) {
curl_multi_setopt($this->multi->handle, CURLMOPT_PUSHFUNCTION, null);
if (\is_resource($this->multi->handle)) {
if (\defined('CURLMOPT_PUSHFUNCTION')) {
curl_multi_setopt($this->multi->handle, CURLMOPT_PUSHFUNCTION, null);
}
$active = 0;
while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active));
}
$active = 0;
while (CURLM_CALL_MULTI_PERFORM === curl_multi_exec($this->multi->handle, $active));
foreach ($this->multi->openHandles as [$ch]) {
curl_setopt($ch, CURLOPT_VERBOSE, false);
if (\is_resource($ch)) {
curl_setopt($ch, CURLOPT_VERBOSE, false);
}
}
}