|
12 | 12 | namespace Symfony\Component\HttpClient;
|
13 | 13 |
|
14 | 14 | use Symfony\Component\HttpClient\Exception\InvalidArgumentException;
|
| 15 | +use Symfony\Component\HttpClient\Exception\TransportException; |
15 | 16 |
|
16 | 17 | /**
|
17 | 18 | * Provides the common logic from writing HttpClientInterface implementations.
|
@@ -89,8 +90,13 @@ private static function prepareRequest(?string $method, ?string $url, array $opt
|
89 | 90 |
|
90 | 91 | if (\is_string($options['body'])
|
91 | 92 | && (string) \strlen($options['body']) !== substr($h = $options['normalized_headers']['content-length'][0] ?? '', 16)
|
92 |
| - && ('' !== $h || ('' !== $options['body'] && !isset($options['normalized_headers']['transfer-encoding']))) |
| 93 | + && ('' !== $h || '' !== $options['body']) |
93 | 94 | ) {
|
| 95 | + if (isset($options['normalized_headers']['transfer-encoding'])) { |
| 96 | + unset($options['normalized_headers']['transfer-encoding']); |
| 97 | + $options['body'] = self::dechunk($options['body']); |
| 98 | + } |
| 99 | + |
94 | 100 | $options['normalized_headers']['content-length'] = [substr_replace($h ?: 'Content-Length: ', \strlen($options['body']), 16)];
|
95 | 101 | }
|
96 | 102 | }
|
@@ -329,6 +335,22 @@ private static function normalizeBody($body)
|
329 | 335 | return $body;
|
330 | 336 | }
|
331 | 337 |
|
| 338 | + private static function dechunk(string $body): string |
| 339 | + { |
| 340 | + $h = fopen('php://temp', 'w+'); |
| 341 | + stream_filter_append($h, 'dechunk', \STREAM_FILTER_WRITE); |
| 342 | + fwrite($h, $body); |
| 343 | + $body = stream_get_contents($h, -1, 0); |
| 344 | + rewind($h); |
| 345 | + ftruncate($h, 0); |
| 346 | + |
| 347 | + if (fwrite($h, '-') && '' !== stream_get_contents($h, -1, 0)) { |
| 348 | + throw new TransportException('Request body has broken chunked encoding.'); |
| 349 | + } |
| 350 | + |
| 351 | + return $body; |
| 352 | + } |
| 353 | + |
332 | 354 | /**
|
333 | 355 | * @param string|string[] $fingerprint
|
334 | 356 | *
|
|
0 commit comments