🔧
This commit is contained in:
2
vendor/symfony/http-kernel/HttpCache/Esi.php
vendored
2
vendor/symfony/http-kernel/HttpCache/Esi.php
vendored
@@ -42,7 +42,7 @@ class Esi extends AbstractSurrogate
|
||||
}
|
||||
}
|
||||
|
||||
public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string
|
||||
public function renderIncludeTag(string $uri, ?string $alt = null, bool $ignoreErrors = true, string $comment = ''): string
|
||||
{
|
||||
$html = sprintf('<esi:include src="%s"%s%s />',
|
||||
$uri,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpKernel\HttpCache;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
@@ -89,7 +90,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
* Unless your application needs to process events on cache hits, it is recommended
|
||||
* to set this to false to avoid having to bootstrap the Symfony framework on a cache hit.
|
||||
*/
|
||||
public function __construct(HttpKernelInterface $kernel, StoreInterface $store, SurrogateInterface $surrogate = null, array $options = [])
|
||||
public function __construct(HttpKernelInterface $kernel, StoreInterface $store, ?SurrogateInterface $surrogate = null, array $options = [])
|
||||
{
|
||||
$this->store = $store;
|
||||
$this->kernel = $kernel;
|
||||
@@ -237,7 +238,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
|
||||
$response->prepare($request);
|
||||
|
||||
$response->isNotModified($request);
|
||||
if (HttpKernelInterface::MAIN_REQUEST === $type) {
|
||||
$response->isNotModified($request);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
@@ -465,7 +468,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
protected function forward(Request $request, bool $catch = false, Response $entry = null)
|
||||
protected function forward(Request $request, bool $catch = false, ?Response $entry = null)
|
||||
{
|
||||
$this->surrogate?->addSurrogateCapability($request);
|
||||
|
||||
@@ -723,7 +726,11 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
|
||||
$path .= '?'.$qs;
|
||||
}
|
||||
|
||||
return $request->getMethod().' '.$path;
|
||||
try {
|
||||
return $request->getMethod().' '.$path;
|
||||
} catch (SuspiciousOperationException $e) {
|
||||
return '_BAD_METHOD_ '.$path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,7 +51,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
|
||||
private array $ageDirectives = [
|
||||
'max-age' => null,
|
||||
's-maxage' => null,
|
||||
'expires' => null,
|
||||
'expires' => false,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -82,15 +82,30 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
|
||||
return;
|
||||
}
|
||||
|
||||
$isHeuristicallyCacheable = $response->headers->hasCacheControlDirective('public');
|
||||
$maxAge = $response->headers->hasCacheControlDirective('max-age') ? (int) $response->headers->getCacheControlDirective('max-age') : null;
|
||||
$this->storeRelativeAgeDirective('max-age', $maxAge, $age, $isHeuristicallyCacheable);
|
||||
$sharedMaxAge = $response->headers->hasCacheControlDirective('s-maxage') ? (int) $response->headers->getCacheControlDirective('s-maxage') : $maxAge;
|
||||
$this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $age, $isHeuristicallyCacheable);
|
||||
|
||||
$expires = $response->getExpires();
|
||||
$expires = null !== $expires ? (int) $expires->format('U') - (int) $response->getDate()->format('U') : null;
|
||||
$this->storeRelativeAgeDirective('expires', $expires >= 0 ? $expires : null, 0, $isHeuristicallyCacheable);
|
||||
|
||||
// See https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2
|
||||
// If a response is "public" but does not have maximum lifetime, heuristics might be applied.
|
||||
// Do not store NULL values so the final response can have more limiting value from other responses.
|
||||
$isHeuristicallyCacheable = $response->headers->hasCacheControlDirective('public')
|
||||
&& null === $maxAge
|
||||
&& null === $sharedMaxAge
|
||||
&& null === $expires;
|
||||
|
||||
if (!$isHeuristicallyCacheable || null !== $maxAge || null !== $expires) {
|
||||
$this->storeRelativeAgeDirective('max-age', $maxAge, $expires, $age);
|
||||
}
|
||||
|
||||
if (!$isHeuristicallyCacheable || null !== $sharedMaxAge || null !== $expires) {
|
||||
$this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $expires, $age);
|
||||
}
|
||||
|
||||
if (null !== $expires) {
|
||||
$this->ageDirectives['expires'] = true;
|
||||
}
|
||||
|
||||
if (false !== $this->lastModified) {
|
||||
$lastModified = $response->getLastModified();
|
||||
@@ -152,9 +167,9 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
|
||||
}
|
||||
}
|
||||
|
||||
if (is_numeric($this->ageDirectives['expires'])) {
|
||||
if ($this->ageDirectives['expires'] && null !== $maxAge) {
|
||||
$date = clone $response->getDate();
|
||||
$date = $date->modify('+'.($this->ageDirectives['expires'] + $this->age).' seconds');
|
||||
$date = $date->modify('+'.$maxAge.' seconds');
|
||||
$response->setExpires($date);
|
||||
}
|
||||
}
|
||||
@@ -204,33 +219,16 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
|
||||
* we have to subtract the age so that the value is normalized for an age of 0.
|
||||
*
|
||||
* If the value is lower than the currently stored value, we update the value, to keep a rolling
|
||||
* minimal value of each instruction.
|
||||
*
|
||||
* If the value is NULL and the isHeuristicallyCacheable parameter is false, the directive will
|
||||
* not be set on the final response. In this case, not all responses had the directive set and no
|
||||
* value can be found that satisfies the requirements of all responses. The directive will be dropped
|
||||
* from the final response.
|
||||
*
|
||||
* If the isHeuristicallyCacheable parameter is true, however, the current response has been marked
|
||||
* as cacheable in a public (shared) cache, but did not provide an explicit lifetime that would serve
|
||||
* as an upper bound. In this case, we can proceed and possibly keep the directive on the final response.
|
||||
* minimal value of each instruction. If the value is NULL, the directive will not be set on the final response.
|
||||
*/
|
||||
private function storeRelativeAgeDirective(string $directive, ?int $value, int $age, bool $isHeuristicallyCacheable): void
|
||||
private function storeRelativeAgeDirective(string $directive, ?int $value, ?int $expires, int $age): void
|
||||
{
|
||||
if (null === $value) {
|
||||
if ($isHeuristicallyCacheable) {
|
||||
/*
|
||||
* See https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2
|
||||
* This particular response does not require maximum lifetime; heuristics might be applied.
|
||||
* Other responses, however, might have more stringent requirements on maximum lifetime.
|
||||
* So, return early here so that the final response can have the more limiting value set.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
if (null === $value && null === $expires) {
|
||||
$this->ageDirectives[$directive] = false;
|
||||
}
|
||||
|
||||
if (false !== $this->ageDirectives[$directive]) {
|
||||
$value = min($value ?? PHP_INT_MAX, $expires ?? PHP_INT_MAX);
|
||||
$value -= $age;
|
||||
$this->ageDirectives[$directive] = null !== $this->ageDirectives[$directive] ? min($this->ageDirectives[$directive], $value) : $value;
|
||||
}
|
||||
|
||||
2
vendor/symfony/http-kernel/HttpCache/Ssi.php
vendored
2
vendor/symfony/http-kernel/HttpCache/Ssi.php
vendored
@@ -36,7 +36,7 @@ class Ssi extends AbstractSurrogate
|
||||
}
|
||||
}
|
||||
|
||||
public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string
|
||||
public function renderIncludeTag(string $uri, ?string $alt = null, bool $ignoreErrors = true, string $comment = ''): string
|
||||
{
|
||||
return sprintf('<!--#include virtual="%s" -->', $uri);
|
||||
}
|
||||
|
||||
@@ -474,7 +474,7 @@ class Store implements StoreInterface
|
||||
/**
|
||||
* Restores a Response from the HTTP headers and body.
|
||||
*/
|
||||
private function restoreResponse(array $headers, string $path = null): ?Response
|
||||
private function restoreResponse(array $headers, ?string $path = null): ?Response
|
||||
{
|
||||
$status = $headers['X-Status'][0];
|
||||
unset($headers['X-Status']);
|
||||
|
||||
@@ -58,7 +58,7 @@ interface SurrogateInterface
|
||||
* @param string|null $alt An alternate URI
|
||||
* @param string $comment A comment to add as an esi:include tag
|
||||
*/
|
||||
public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string;
|
||||
public function renderIncludeTag(string $uri, ?string $alt = null, bool $ignoreErrors = true, string $comment = ''): string;
|
||||
|
||||
/**
|
||||
* Replaces a Response Surrogate tags with the included resource content.
|
||||
|
||||
Reference in New Issue
Block a user