From 03b7743ff54b784bd95795dc2efde4681de55a2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 26 Feb 2020 14:43:55 +0100 Subject: [PATCH] Optimize HttpClient when body is iterable --- .../Component/HttpClient/HttpClientTrait.php | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/HttpClient/HttpClientTrait.php b/src/Symfony/Component/HttpClient/HttpClientTrait.php index 3eeb52fdd5..b44e4f8dbb 100644 --- a/src/Symfony/Component/HttpClient/HttpClientTrait.php +++ b/src/Symfony/Component/HttpClient/HttpClientTrait.php @@ -271,8 +271,31 @@ trait HttpClientTrait return http_build_query($body, '', '&', PHP_QUERY_RFC1738); } + if (\is_string($body)) { + return $body; + } + + $generatorToCallable = static function (\Generator $body): \Closure { + return static function () use ($body) { + while ($body->valid()) { + $chunk = $body->current(); + $body->next(); + + if ('' !== $chunk) { + return $chunk; + } + } + + return ''; + }; + }; + + if ($body instanceof \Generator) { + return $generatorToCallable($body); + } + if ($body instanceof \Traversable) { - $body = function () use ($body) { yield from $body; }; + return $generatorToCallable((static function ($body) { yield from $body; })($body)); } if ($body instanceof \Closure) { @@ -281,24 +304,14 @@ trait HttpClientTrait if ($r->isGenerator()) { $body = $body(self::$CHUNK_SIZE); - $body = function () use ($body) { - while ($body->valid()) { - $chunk = $body->current(); - $body->next(); - if ('' !== $chunk) { - return $chunk; - } - } - - return ''; - }; + return $generatorToCallable($body); } return $body; } - if (!\is_string($body) && !\is_array(@stream_get_meta_data($body))) { + if (!\is_array(@stream_get_meta_data($body))) { throw new InvalidArgumentException(sprintf('Option "body" must be string, stream resource, iterable or callable, %s given.', \is_resource($body) ? get_resource_type($body) : \gettype($body))); }