minor #22033 Minor cleanups in HttpCache, especially centralize Date header fixup (mpdude)
This PR was submitted for the 2.8 branch but it was merged into the 3.3-dev branch instead (closes #22033).
Discussion
----------
Minor cleanups in HttpCache, especially centralize Date header fixup
| Q | A
| ------------- | ---
| Branch? | 2.8
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |
I am trying to hunt some issues where the HTTP cache does not revalidate responses (or does not use a cached response?) in the edge case of having `s-maxage = 0` and possibly a backend that's slow to respond.
I don't see yet what exactly my problem is there, but it must somehow be related with the `Date` header handling and/or age calculations in the `HTTPCache`.
As a first step, I'd like to suggest this cleanup in `HTTPCache`. Especially, it would be helpful if we could make sure that there is just one place where we set the `Date` header if the backend does not send one (?). This makes sure we always have this header to base later age calculations on it.
Commits
-------
30639c6af6
Minor cleanups in HttpCache, especially centralize Date header fixup
This commit is contained in:
commit
05933f3749
@ -176,24 +176,25 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
}
|
||||
}
|
||||
|
||||
$path = $request->getPathInfo();
|
||||
if ($qs = $request->getQueryString()) {
|
||||
$path .= '?'.$qs;
|
||||
}
|
||||
$this->traces[$request->getMethod().' '.$path] = array();
|
||||
$this->traces[$this->getTraceKey($request)] = array();
|
||||
|
||||
if (!$request->isMethodSafe(false)) {
|
||||
$response = $this->invalidate($request, $catch);
|
||||
} elseif ($request->headers->has('expect') || !$request->isMethodCacheable()) {
|
||||
$response = $this->pass($request, $catch);
|
||||
} elseif ($this->options['allow_reload'] && $request->isNoCache()) {
|
||||
/*
|
||||
If allow_reload is configured and the client requests "Cache-Control: no-cache",
|
||||
reload the cache by fetching a fresh response and caching it (if possible).
|
||||
*/
|
||||
$this->record($request, 'reload');
|
||||
$response = $this->fetch($request, $catch);
|
||||
} else {
|
||||
$response = $this->lookup($request, $catch);
|
||||
}
|
||||
|
||||
$this->restoreResponseBody($request, $response);
|
||||
|
||||
$response->setDate(\DateTime::createFromFormat('U', time(), new \DateTimeZone('UTC')));
|
||||
|
||||
if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) {
|
||||
$response->headers->set('X-Symfony-Cache', $this->getLog());
|
||||
}
|
||||
@ -299,13 +300,6 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
*/
|
||||
protected function lookup(Request $request, $catch = false)
|
||||
{
|
||||
// if allow_reload and no-cache Cache-Control, allow a cache reload
|
||||
if ($this->options['allow_reload'] && $request->isNoCache()) {
|
||||
$this->record($request, 'reload');
|
||||
|
||||
return $this->fetch($request, $catch);
|
||||
}
|
||||
|
||||
try {
|
||||
$entry = $this->store->lookup($request);
|
||||
} catch (\Exception $e) {
|
||||
@ -403,9 +397,8 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards the Request to the backend and determines whether the response should be stored.
|
||||
*
|
||||
* This methods is triggered when the cache missed or a reload is required.
|
||||
* Unconditionally fetches a fresh response from the backend and
|
||||
* stores it in the cache if is cacheable.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param bool $catch whether to process exceptions
|
||||
@ -437,6 +430,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
/**
|
||||
* Forwards the Request to the backend and returns the Response.
|
||||
*
|
||||
* All backend requests (cache passes, fetches, cache validations)
|
||||
* run through this method.
|
||||
*
|
||||
* @param Request $request A Request instance
|
||||
* @param bool $catch Whether to catch exceptions or not
|
||||
* @param Response $entry A Response instance (the stale entry if present, null otherwise)
|
||||
@ -484,6 +480,17 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
RFC 7231 Sect. 7.1.1.2 says that a server that does not have a reasonably accurate
|
||||
clock MUST NOT send a "Date" header, although it MUST send one in most other cases
|
||||
except for 1xx or 5xx responses where it MAY do so.
|
||||
|
||||
Anyway, a client that received a message without a "Date" header MUST add it.
|
||||
*/
|
||||
if (!$response->headers->has('Date')) {
|
||||
$response->setDate(\DateTime::createFromFormat('U', time()));
|
||||
}
|
||||
|
||||
$this->processResponseBody($request, $response);
|
||||
|
||||
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
|
||||
@ -584,9 +591,6 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
*/
|
||||
protected function store(Request $request, Response $response)
|
||||
{
|
||||
if (!$response->headers->has('Date')) {
|
||||
$response->setDate(\DateTime::createFromFormat('U', time()));
|
||||
}
|
||||
try {
|
||||
$this->store->write($request, $response);
|
||||
|
||||
@ -683,11 +687,24 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
* @param string $event The event name
|
||||
*/
|
||||
private function record(Request $request, $event)
|
||||
{
|
||||
$this->traces[$this->getTraceKey($request)][] = $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the key we use in the "trace" array for a given request.
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTraceKey(Request $request)
|
||||
{
|
||||
$path = $request->getPathInfo();
|
||||
if ($qs = $request->getQueryString()) {
|
||||
$path .= '?'.$qs;
|
||||
}
|
||||
$this->traces[$request->getMethod().' '.$path][] = $event;
|
||||
|
||||
return $request->getMethod().' '.$path;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user