Skip to content

Commit 412411d

Browse files
[HttpClient] fix dealing with 1xx informational responses
1 parent 0a1a885 commit 412411d

File tree

3 files changed

+37
-10
lines changed

3 files changed

+37
-10
lines changed

src/Symfony/Component/HttpClient/Response/CurlResponse.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,19 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
289289
// Regular header line: add it to the list
290290
self::addResponseHeaders([substr($data, 0, -2)], $info, $headers);
291291

292-
if (0 === strpos($data, 'HTTP') && 300 <= $info['http_code'] && $info['http_code'] < 400) {
292+
if (0 !== strpos($data, 'HTTP/')) {
293+
if (0 === stripos($data, 'Location:')) {
294+
$location = trim(substr($data, 9, -2));
295+
}
296+
297+
return \strlen($data);
298+
}
299+
300+
if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) {
301+
$info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert'));
302+
}
303+
304+
if (300 <= $info['http_code'] && $info['http_code'] < 400) {
293305
if (curl_getinfo($ch, CURLINFO_REDIRECT_COUNT) === $options['max_redirects']) {
294306
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
295307
} elseif (303 === $info['http_code'] || ('POST' === $info['http_method'] && \in_array($info['http_code'], [301, 302], true))) {
@@ -298,15 +310,14 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
298310
}
299311
}
300312

301-
if (0 === stripos($data, 'Location:')) {
302-
$location = trim(substr($data, 9, -2));
303-
}
304-
305313
return \strlen($data);
306314
}
307315

308316
// End of headers: handle redirects and add to the activity list
309-
$statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
317+
if (200 > $statusCode = curl_getinfo($ch, CURLINFO_RESPONSE_CODE)) {
318+
return \strlen($data);
319+
}
320+
310321
$info['redirect_url'] = null;
311322

312323
if (300 <= $statusCode && $statusCode < 400 && null !== $location) {
@@ -336,10 +347,6 @@ private static function parseHeaderLine($ch, string $data, array &$info, array &
336347
return 0;
337348
}
338349

339-
if (\function_exists('openssl_x509_read') && $certinfo = curl_getinfo($ch, CURLINFO_CERTINFO)) {
340-
$info['peer_certificate_chain'] = array_map('openssl_x509_read', array_column($certinfo, 'Cert'));
341-
}
342-
343350
curl_setopt($ch, CURLOPT_PRIVATE, 'content');
344351
} elseif (null !== $info['redirect_url'] && $logger) {
345352
$logger->info(sprintf('Redirecting: "%s %s"', $info['http_code'], $info['redirect_url']));

src/Symfony/Contracts/HttpClient/Test/Fixtures/web/index.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@
4141
ob_start('ob_gzhandler');
4242
break;
4343

44+
case '/103':
45+
header('HTTP/1.1 103 Early Hints');
46+
header('Link: </style.css>; rel=preload; as=style', false);
47+
header('Link: </script.js>; rel=preload; as=script', false);
48+
echo "HTTP/1.1 200 OK\r\n";
49+
echo "Date: Fri, 26 May 2017 10:02:11 GMT\r\n";
50+
echo "Content-Length: 13\r\n";
51+
echo "\r\n";
52+
echo 'Here the body';
53+
exit;
54+
4455
case '/404':
4556
header('Content-Type: application/json', true, 404);
4657
break;

src/Symfony/Contracts/HttpClient/Test/HttpClientTestCase.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,15 @@ public function testQuery()
721721
$this->assertSame('/?a=a&b=b', $body['REQUEST_URI']);
722722
}
723723

724+
public function testInformationalResponse()
725+
{
726+
$client = $this->getHttpClient(__FUNCTION__);
727+
$response = $client->request('GET', 'http://localhost:8057/103');
728+
729+
$this->assertSame('Here the body', $response->getContent());
730+
$this->assertSame(200, $response->getStatusCode());
731+
}
732+
724733
/**
725734
* @requires extension zlib
726735
*/

0 commit comments

Comments
 (0)