Skip to content

Commit d281c96

Browse files
Merge branch '6.4' into 7.2
* 6.4: [Process] Fix process status tracking [HttpClient] Fix buffering AsyncResponse with no passthru [HttpClient] Fix uploading files > 2GB [Mime] use isRendered method to avoid rendering an email twice
2 parents 8ddba18 + adb7c99 commit d281c96

File tree

3 files changed

+24
-14
lines changed

3 files changed

+24
-14
lines changed

CurlHttpClient.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ public function request(string $method, string $url, array $options = []): Respo
241241
}
242242

243243
if (\is_resource($body)) {
244-
$curlopts[\CURLOPT_INFILE] = $body;
244+
$curlopts[\CURLOPT_READDATA] = $body;
245245
} else {
246246
$curlopts[\CURLOPT_READFUNCTION] = static function ($ch, $fd, $length) use ($body) {
247247
static $eof = false;
@@ -320,6 +320,9 @@ public function request(string $method, string $url, array $options = []): Respo
320320
}
321321

322322
foreach ($curlopts as $opt => $value) {
323+
if (\CURLOPT_INFILESIZE === $opt && $value >= 1 << 31) {
324+
$opt = 115; // 115 === CURLOPT_INFILESIZE_LARGE, but it's not defined in PHP
325+
}
323326
if (null !== $value && !curl_setopt($ch, $opt, $value) && \CURLOPT_CERTINFO !== $opt && (!\defined('CURLOPT_HEADEROPT') || \CURLOPT_HEADEROPT !== $opt)) {
324327
$constantName = $this->findConstantName($opt);
325328
throw new TransportException(\sprintf('Curl option "%s" is not supported.', $constantName ?? $opt));
@@ -476,7 +479,7 @@ private function validateExtraCurlOptions(array $options): void
476479
\CURLOPT_RESOLVE => 'resolve',
477480
\CURLOPT_NOSIGNAL => 'timeout',
478481
\CURLOPT_HTTPHEADER => 'headers',
479-
\CURLOPT_INFILE => 'body',
482+
\CURLOPT_READDATA => 'body',
480483
\CURLOPT_READFUNCTION => 'body',
481484
\CURLOPT_INFILESIZE => 'body',
482485
\CURLOPT_POSTFIELDS => 'body',

Response/AsyncResponse.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\HttpClient\Response;
1313

1414
use Symfony\Component\HttpClient\Chunk\ErrorChunk;
15-
use Symfony\Component\HttpClient\Chunk\FirstChunk;
1615
use Symfony\Component\HttpClient\Chunk\LastChunk;
1716
use Symfony\Component\HttpClient\Exception\TransportException;
1817
use Symfony\Contracts\HttpClient\ChunkInterface;
@@ -245,7 +244,7 @@ public static function stream(iterable $responses, ?float $timeout = null, ?stri
245244
$wrappedResponses[] = $r->response;
246245

247246
if ($r->stream) {
248-
yield from self::passthruStream($response = $r->response, $r, new FirstChunk(), $asyncMap);
247+
yield from self::passthruStream($response = $r->response, $r, $asyncMap, new LastChunk());
249248

250249
if (!isset($asyncMap[$response])) {
251250
array_pop($wrappedResponses);
@@ -276,15 +275,9 @@ public static function stream(iterable $responses, ?float $timeout = null, ?stri
276275
}
277276

278277
if (!$r->passthru) {
279-
if (null !== $chunk->getError() || $chunk->isLast()) {
280-
unset($asyncMap[$response]);
281-
} elseif (null !== $r->content && '' !== ($content = $chunk->getContent()) && \strlen($content) !== fwrite($r->content, $content)) {
282-
$chunk = new ErrorChunk($r->offset, new TransportException(\sprintf('Failed writing %d bytes to the response buffer.', \strlen($content))));
283-
$r->info['error'] = $chunk->getError();
284-
$r->response->cancel();
285-
}
278+
$r->stream = (static fn () => yield $chunk)();
279+
yield from self::passthruStream($response, $r, $asyncMap);
286280

287-
yield $r => $chunk;
288281
continue;
289282
}
290283

@@ -347,13 +340,13 @@ private static function passthru(HttpClientInterface $client, self $r, ChunkInte
347340
}
348341
$r->stream = $stream;
349342

350-
yield from self::passthruStream($response, $r, null, $asyncMap);
343+
yield from self::passthruStream($response, $r, $asyncMap);
351344
}
352345

353346
/**
354347
* @param \SplObjectStorage<ResponseInterface, AsyncResponse>|null $asyncMap
355348
*/
356-
private static function passthruStream(ResponseInterface $response, self $r, ?ChunkInterface $chunk, ?\SplObjectStorage $asyncMap): \Generator
349+
private static function passthruStream(ResponseInterface $response, self $r, ?\SplObjectStorage $asyncMap, ?ChunkInterface $chunk = null): \Generator
357350
{
358351
while (true) {
359352
try {

Tests/AsyncDecoratorTraitTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,20 @@ public function testBufferPurePassthru()
231231

232232
$this->assertStringContainsString('SERVER_PROTOCOL', $response->getContent());
233233
$this->assertStringContainsString('HTTP_HOST', $response->getContent());
234+
235+
$client = new class(parent::getHttpClient(__FUNCTION__)) implements HttpClientInterface {
236+
use AsyncDecoratorTrait;
237+
238+
public function request(string $method, string $url, array $options = []): ResponseInterface
239+
{
240+
return new AsyncResponse($this->client, $method, $url, $options);
241+
}
242+
};
243+
244+
$response = $client->request('GET', 'http://localhost:8057/');
245+
246+
$this->assertStringContainsString('SERVER_PROTOCOL', $response->getContent());
247+
$this->assertStringContainsString('HTTP_HOST', $response->getContent());
234248
}
235249

236250
public function testRetryTimeout()

0 commit comments

Comments
 (0)