[HttpClient] make pushed responses retry-able

This commit is contained in:
Nicolas Grekas 2019-12-16 23:02:54 +01:00
parent 2b0f9d6bd9
commit c2864f65ab
2 changed files with 26 additions and 21 deletions

View File

@ -116,23 +116,6 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
$options['normalized_headers']['user-agent'][] = $options['headers'][] = 'User-Agent: Symfony HttpClient/Curl';
}
if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) {
unset($this->multi->pushedResponses[$url]);
if (self::acceptPushForRequest($method, $options, $pushedResponse)) {
$this->logger && $this->logger->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url));
// Reinitialize the pushed response with request's options
$pushedResponse->response->__construct($this->multi, $url, $options, $this->logger);
return $pushedResponse->response;
}
$this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s".', $url));
}
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url));
$curlopts = [
CURLOPT_URL => $url,
CURLOPT_TCP_NODELAY => true,
@ -267,7 +250,26 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
$curlopts[file_exists($options['bindto']) ? CURLOPT_UNIX_SOCKET_PATH : CURLOPT_INTERFACE] = $options['bindto'];
}
$ch = curl_init();
if ($pushedResponse = $this->multi->pushedResponses[$url] ?? null) {
unset($this->multi->pushedResponses[$url]);
if (self::acceptPushForRequest($method, $options, $pushedResponse)) {
$this->logger && $this->logger->debug(sprintf('Accepting pushed response: "%s %s"', $method, $url));
// Reinitialize the pushed response with request's options
$ch = $pushedResponse->handle;
$pushedResponse = $pushedResponse->response;
$pushedResponse->__construct($this->multi, $url, $options, $this->logger);
} else {
$this->logger && $this->logger->debug(sprintf('Rejecting pushed response: "%s".', $url));
$pushedResponse = null;
}
}
if (!$pushedResponse) {
$ch = curl_init();
$this->logger && $this->logger->info(sprintf('Request: "%s %s"', $method, $url));
}
foreach ($curlopts as $opt => $value) {
if (null !== $value && !curl_setopt($ch, $opt, $value) && CURLOPT_CERTINFO !== $opt) {
@ -279,7 +281,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
}
}
return new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host));
return $pushedResponse ?? new CurlResponse($this->multi, $ch, $options, $this->logger, $method, self::createRedirectResolver($options, $host));
}
/**
@ -369,7 +371,7 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
$url .= $headers[':path'][0];
$logger && $logger->debug(sprintf('Queueing pushed response: "%s"', $url));
$multi->pushedResponses[$url] = new PushedResponse(new CurlResponse($multi, $pushed), $headers, $multi->openHandles[(int) $parent][1] ?? []);
$multi->pushedResponses[$url] = new PushedResponse(new CurlResponse($multi, $pushed), $headers, $multi->openHandles[(int) $parent][1] ?? [], $pushed);
return CURL_PUSH_OK;
}

View File

@ -29,10 +29,13 @@ final class PushedResponse
public $parentOptions = [];
public function __construct(CurlResponse $response, array $requestHeaders, array $parentOptions)
public $handle;
public function __construct(CurlResponse $response, array $requestHeaders, array $parentOptions, $handle)
{
$this->response = $response;
$this->requestHeaders = $requestHeaders;
$this->parentOptions = $parentOptions;
$this->handle = $handle;
}
}