[HttpClient] fix race condition when reading response with informational status

This commit is contained in:
Nicolas Grekas 2019-09-24 19:56:24 +02:00
parent 1ccc970469
commit 450c3c4998
4 changed files with 13 additions and 5 deletions

View File

@ -355,7 +355,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface
*/ */
private static function acceptPushForRequest(string $method, array $options, PushedResponse $pushedResponse): bool private static function acceptPushForRequest(string $method, array $options, PushedResponse $pushedResponse): bool
{ {
if ($options['body'] || $method !== $pushedResponse->requestHeaders[':method'][0]) { if ('' !== $options['body'] || $method !== $pushedResponse->requestHeaders[':method'][0]) {
return false; return false;
} }

View File

@ -121,15 +121,17 @@ final class CurlResponse implements ResponseInterface
if (\in_array($waitFor, ['headers', 'destruct'], true)) { if (\in_array($waitFor, ['headers', 'destruct'], true)) {
try { try {
self::stream([$response])->current(); foreach (self::stream([$response]) as $chunk) {
if ($chunk->isFirst()) {
break;
}
}
} catch (\Throwable $e) { } catch (\Throwable $e) {
// Persist timeouts thrown during initialization // Persist timeouts thrown during initialization
$response->info['error'] = $e->getMessage(); $response->info['error'] = $e->getMessage();
$response->close(); $response->close();
throw $e; throw $e;
} }
} elseif ('content' === $waitFor && ($response->multi->handlesActivity[$response->id][0] ?? null) instanceof FirstChunk) {
self::stream([$response])->current();
} }
curl_setopt($ch, CURLOPT_HEADERFUNCTION, null); curl_setopt($ch, CURLOPT_HEADERFUNCTION, null);

View File

@ -65,7 +65,11 @@ final class NativeResponse implements ResponseInterface
} }
if (null === $response->remaining) { if (null === $response->remaining) {
self::stream([$response])->current(); foreach (self::stream([$response]) as $chunk) {
if ($chunk->isFirst()) {
break;
}
}
} }
}; };
} }

View File

@ -45,6 +45,8 @@ switch ($vars['REQUEST_URI']) {
header('HTTP/1.1 103 Early Hints'); header('HTTP/1.1 103 Early Hints');
header('Link: </style.css>; rel=preload; as=style', false); header('Link: </style.css>; rel=preload; as=style', false);
header('Link: </script.js>; rel=preload; as=script', false); header('Link: </script.js>; rel=preload; as=script', false);
flush();
usleep(1000);
echo "HTTP/1.1 200 OK\r\n"; echo "HTTP/1.1 200 OK\r\n";
echo "Date: Fri, 26 May 2017 10:02:11 GMT\r\n"; echo "Date: Fri, 26 May 2017 10:02:11 GMT\r\n";
echo "Content-Length: 13\r\n"; echo "Content-Length: 13\r\n";