Skip to content

Commit 8272de5

Browse files
Merge branch '5.4' into 6.0
* 5.4: (22 commits) Fix composer on appveyor fix bootstrap_3_layout ChoiceType's expanded label_html [PropertyAccess] Fix typo in PropertyAccessor::readProperty() DocBlock [PropertyInfo] PhpStanExtractor namespace missmatch issue [VarExporter] Fix exporting objects with readonly properties [ExpressionLanguage] Fix matches when the regexp is not valid [Messenger] Add mysql indexes back and work around deadlocks using soft-delete Add BC layer to handle old objects already present in cache [RateLimiter] Always store SlidingWindows with an expiration set [Validator] Fix File constraint invalid max size exception message [Console] Fix exit status on uncaught exception with negative code [Validator] fix #43345 @Assert\DivisibleBy [HttpClient] fix 303 after PUT and sending chunked requests [HttpClient] always send Content-Type when a body is passed [HttpClient] always send Content-Length when a body is passed [HttpClient] fix sending Content-Length/Type for POST Fix merge [HttpClient] fix sending PUT requests with curl Fix locales format in CrowdinProvider Fix intersect in TranslatorBag ...
2 parents 0a6d049 + af736b7 commit 8272de5

File tree

7 files changed

+57
-7
lines changed

7 files changed

+57
-7
lines changed

AmpHttpClient.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public function request(string $method, string $url, array $options = []): Respo
9191
}
9292
}
9393

94-
if ('' !== $options['body'] && 'POST' === $method && !isset($options['normalized_headers']['content-type'])) {
94+
if (('' !== $options['body'] || 'POST' === $method || isset($options['normalized_headers']['content-length'])) && !isset($options['normalized_headers']['content-type'])) {
9595
$options['headers'][] = 'Content-Type: application/x-www-form-urlencoded';
9696
}
9797

CurlHttpClient.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,12 @@ public function request(string $method, string $url, array $options = []): Respo
240240

241241
if ('POST' !== $method) {
242242
$curlopts[\CURLOPT_UPLOAD] = true;
243+
244+
if (!isset($options['normalized_headers']['content-type'])) {
245+
$curlopts[\CURLOPT_HTTPHEADER][] = 'Content-Type: application/x-www-form-urlencoded';
246+
}
243247
}
244-
} elseif ('' !== $body || 'POST' === $method) {
248+
} elseif ('' !== $body || 'POST' === $method || $hasContentLength) {
245249
$curlopts[\CURLOPT_POSTFIELDS] = $body;
246250
}
247251

HttpClientTrait.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,13 @@ private static function prepareRequest(?string $method, ?string $url, array $opt
101101

102102
if (\is_string($options['body'])
103103
&& (string) \strlen($options['body']) !== substr($h = $options['normalized_headers']['content-length'][0] ?? '', 16)
104-
&& ('' !== $h || ('' !== $options['body'] && !isset($options['normalized_headers']['transfer-encoding'])))
104+
&& ('' !== $h || '' !== $options['body'])
105105
) {
106+
if (isset($options['normalized_headers']['transfer-encoding'])) {
107+
unset($options['normalized_headers']['transfer-encoding']);
108+
$options['body'] = self::dechunk($options['body']);
109+
}
110+
106111
$options['normalized_headers']['content-length'] = [substr_replace($h ?: 'Content-Length: ', \strlen($options['body']), 16)];
107112
}
108113
}
@@ -365,6 +370,22 @@ private static function normalizeBody($body)
365370
return $body;
366371
}
367372

373+
private static function dechunk(string $body): string
374+
{
375+
$h = fopen('php://temp', 'w+');
376+
stream_filter_append($h, 'dechunk', \STREAM_FILTER_WRITE);
377+
fwrite($h, $body);
378+
$body = stream_get_contents($h, -1, 0);
379+
rewind($h);
380+
ftruncate($h, 0);
381+
382+
if (fwrite($h, '-') && '' !== stream_get_contents($h, -1, 0)) {
383+
throw new TransportException('Request body has broken chunked encoding.');
384+
}
385+
386+
return $body;
387+
}
388+
368389
/**
369390
* @throws InvalidArgumentException When an invalid fingerprint is passed
370391
*/

NativeHttpClient.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,20 @@ public function request(string $method, string $url, array $options = []): Respo
8080
}
8181
}
8282

83+
$hasContentLength = isset($options['normalized_headers']['content-length']);
84+
$hasBody = '' !== $options['body'] || 'POST' === $method || $hasContentLength;
85+
8386
$options['body'] = self::getBodyAsString($options['body']);
8487

85-
if ('' !== $options['body'] && 'POST' === $method && !isset($options['normalized_headers']['content-type'])) {
88+
if (isset($options['normalized_headers']['transfer-encoding'])) {
89+
unset($options['normalized_headers']['transfer-encoding']);
90+
$options['headers'] = array_merge(...array_values($options['normalized_headers']));
91+
$options['body'] = self::dechunk($options['body']);
92+
}
93+
if ('' === $options['body'] && $hasBody && !$hasContentLength) {
94+
$options['headers'][] = 'Content-Length: 0';
95+
}
96+
if ($hasBody && !isset($options['normalized_headers']['content-type'])) {
8697
$options['headers'][] = 'Content-Type: application/x-www-form-urlencoded';
8798
}
8899

Response/CurlResponse.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
406406
} elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) {
407407
$info['http_method'] = 'HEAD' === $info['http_method'] ? 'HEAD' : 'GET';
408408
curl_setopt($ch, \CURLOPT_POSTFIELDS, '');
409+
curl_setopt($ch, \CURLOPT_CUSTOMREQUEST, $info['http_method']);
409410
}
410411
}
411412

Tests/HttpClientTestCase.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,10 +402,23 @@ public function testRedirectAfterPost()
402402
$client = $this->getHttpClient(__FUNCTION__);
403403

404404
$response = $client->request('POST', 'http://localhost:8057/302/relative', [
405-
'body' => 'abc',
405+
'body' => '',
406406
]);
407407

408408
$this->assertSame(200, $response->getStatusCode());
409+
$this->assertStringContainsStringIgnoringCase("\r\nContent-Length: 0", $response->getInfo('debug'));
410+
}
411+
412+
public function testEmptyPut()
413+
{
414+
$client = $this->getHttpClient(__FUNCTION__);
415+
416+
$response = $client->request('PUT', 'http://localhost:8057/post', [
417+
'headers' => ['Content-Length' => '0'],
418+
]);
419+
420+
$this->assertSame(200, $response->getStatusCode());
421+
$this->assertStringContainsString("\r\nContent-Length: ", $response->getInfo('debug'));
409422
}
410423

411424
public function testNullBody()

Tests/MockHttpClientTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,12 @@ public function testFixContentLength()
217217
$this->assertSame(['Content-Length: 7'], $requestOptions['normalized_headers']['content-length']);
218218

219219
$response = $client->request('POST', 'http://localhost:8057/post', [
220-
'body' => 'abc=def',
220+
'body' => "8\r\nSymfony \r\n5\r\nis aw\r\n6\r\nesome!\r\n0\r\n\r\n",
221221
'headers' => ['Transfer-Encoding: chunked'],
222222
]);
223223

224224
$requestOptions = $response->getRequestOptions();
225-
$this->assertFalse(isset($requestOptions['normalized_headers']['content-length']));
225+
$this->assertSame(['Content-Length: 19'], $requestOptions['normalized_headers']['content-length']);
226226

227227
$response = $client->request('POST', 'http://localhost:8057/post', [
228228
'body' => '',

0 commit comments

Comments
 (0)