From 43b2800432098b2a5056628d01a1b79c50315972 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 1 Aug 2022 16:37:53 +0200 Subject: [PATCH 1/2] [HttpClient] Fix memory leak when using StreamWrapper --- Response/StreamWrapper.php | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Response/StreamWrapper.php b/Response/StreamWrapper.php index 644f2ee..6bb3168 100644 --- a/Response/StreamWrapper.php +++ b/Response/StreamWrapper.php @@ -53,20 +53,18 @@ public static function createResource(ResponseInterface $response, HttpClientInt throw new \InvalidArgumentException(sprintf('Providing a client to "%s()" is required when the response doesn\'t have any "stream()" method.', __CLASS__)); } - if (false === stream_wrapper_register('symfony', __CLASS__)) { + static $registered = false; + + if (!$registered = $registered || stream_wrapper_register(strtr(__CLASS__, '\\', '-'), __CLASS__)) { throw new \RuntimeException(error_get_last()['message'] ?? 'Registering the "symfony" stream wrapper failed.'); } - try { - $context = [ - 'client' => $client ?? $response, - 'response' => $response, - ]; - - return fopen('symfony://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context])) ?: null; - } finally { - stream_wrapper_unregister('symfony'); - } + $context = [ + 'client' => $client ?? $response, + 'response' => $response, + ]; + + return fopen(strtr(__CLASS__, '\\', '-').'://'.$response->getInfo('url'), 'r', false, stream_context_create(['symfony' => $context])); } public function getResponse(): ResponseInterface From 653dc41a26bd34f06bae25ab89532df938e8c9c5 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Mon, 1 Aug 2022 19:57:53 +0200 Subject: [PATCH 2/2] [HttpClient] Fix shared connections not being freed on PHP < 8 --- Internal/CurlClientState.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Internal/CurlClientState.php b/Internal/CurlClientState.php index 5821f67..904cc47 100644 --- a/Internal/CurlClientState.php +++ b/Internal/CurlClientState.php @@ -96,7 +96,7 @@ public function reset() curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_DNS); curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_SSL_SESSION); - if (\defined('CURL_LOCK_DATA_CONNECT')) { + if (\defined('CURL_LOCK_DATA_CONNECT') && \PHP_VERSION_ID >= 80000) { curl_share_setopt($this->share, \CURLSHOPT_SHARE, \CURL_LOCK_DATA_CONNECT); } }