bug #35014 [HttpClient] make pushed responses retry-able (nicolas-grekas)
This PR was merged into the 4.3 branch.
Discussion
----------
[HttpClient] make pushed responses retry-able
| Q | A
| ------------- | ---
| Branch? | 4.3
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets | https://github.com/orgs/symfony/projects/1#card-30499375
| License | MIT
| Doc PR | -
This moves the PUSH matching logic down so that the curl handle of pushed responses can be properly configured. This should make pushed requests retry-able when they fail just after the push-promise frame.
Commits
-------
c2864f65ab
[HttpClient] make pushed responses retry-able
This commit is contained in:
commit
bbf7ed12b1
@ -116,23 +116,6 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
|||||||
$options['normalized_headers']['user-agent'][] = $options['headers'][] = 'User-Agent: Symfony HttpClient/Curl';
|
$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 = [
|
$curlopts = [
|
||||||
CURLOPT_URL => $url,
|
CURLOPT_URL => $url,
|
||||||
CURLOPT_TCP_NODELAY => true,
|
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'];
|
$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) {
|
foreach ($curlopts as $opt => $value) {
|
||||||
if (null !== $value && !curl_setopt($ch, $opt, $value) && CURLOPT_CERTINFO !== $opt) {
|
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];
|
$url .= $headers[':path'][0];
|
||||||
$logger && $logger->debug(sprintf('Queueing pushed response: "%s"', $url));
|
$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;
|
return CURL_PUSH_OK;
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,13 @@ final class PushedResponse
|
|||||||
|
|
||||||
public $parentOptions = [];
|
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->response = $response;
|
||||||
$this->requestHeaders = $requestHeaders;
|
$this->requestHeaders = $requestHeaders;
|
||||||
$this->parentOptions = $parentOptions;
|
$this->parentOptions = $parentOptions;
|
||||||
|
$this->handle = $handle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user