mirror of
https://github.com/linuxserver/Heimdall.git
synced 2025-12-03 13:40:00 +09:00
Update to laravel 7
This commit is contained in:
318
vendor/symfony/http-foundation/Response.php
vendored
318
vendor/symfony/http-foundation/Response.php
vendored
@@ -11,6 +11,9 @@
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
// Help opcache.preload discover always-needed symbols
|
||||
class_exists(ResponseHeaderBag::class);
|
||||
|
||||
/**
|
||||
* Response represents an HTTP response.
|
||||
*
|
||||
@@ -18,77 +21,90 @@ namespace Symfony\Component\HttpFoundation;
|
||||
*/
|
||||
class Response
|
||||
{
|
||||
const HTTP_CONTINUE = 100;
|
||||
const HTTP_SWITCHING_PROTOCOLS = 101;
|
||||
const HTTP_PROCESSING = 102; // RFC2518
|
||||
const HTTP_EARLY_HINTS = 103; // RFC8297
|
||||
const HTTP_OK = 200;
|
||||
const HTTP_CREATED = 201;
|
||||
const HTTP_ACCEPTED = 202;
|
||||
const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
const HTTP_NO_CONTENT = 204;
|
||||
const HTTP_RESET_CONTENT = 205;
|
||||
const HTTP_PARTIAL_CONTENT = 206;
|
||||
const HTTP_MULTI_STATUS = 207; // RFC4918
|
||||
const HTTP_ALREADY_REPORTED = 208; // RFC5842
|
||||
const HTTP_IM_USED = 226; // RFC3229
|
||||
const HTTP_MULTIPLE_CHOICES = 300;
|
||||
const HTTP_MOVED_PERMANENTLY = 301;
|
||||
const HTTP_FOUND = 302;
|
||||
const HTTP_SEE_OTHER = 303;
|
||||
const HTTP_NOT_MODIFIED = 304;
|
||||
const HTTP_USE_PROXY = 305;
|
||||
const HTTP_RESERVED = 306;
|
||||
const HTTP_TEMPORARY_REDIRECT = 307;
|
||||
const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238
|
||||
const HTTP_BAD_REQUEST = 400;
|
||||
const HTTP_UNAUTHORIZED = 401;
|
||||
const HTTP_PAYMENT_REQUIRED = 402;
|
||||
const HTTP_FORBIDDEN = 403;
|
||||
const HTTP_NOT_FOUND = 404;
|
||||
const HTTP_METHOD_NOT_ALLOWED = 405;
|
||||
const HTTP_NOT_ACCEPTABLE = 406;
|
||||
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
const HTTP_REQUEST_TIMEOUT = 408;
|
||||
const HTTP_CONFLICT = 409;
|
||||
const HTTP_GONE = 410;
|
||||
const HTTP_LENGTH_REQUIRED = 411;
|
||||
const HTTP_PRECONDITION_FAILED = 412;
|
||||
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
|
||||
const HTTP_REQUEST_URI_TOO_LONG = 414;
|
||||
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
const HTTP_EXPECTATION_FAILED = 417;
|
||||
const HTTP_I_AM_A_TEAPOT = 418; // RFC2324
|
||||
const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540
|
||||
const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
|
||||
const HTTP_LOCKED = 423; // RFC4918
|
||||
const HTTP_FAILED_DEPENDENCY = 424; // RFC4918
|
||||
public const HTTP_CONTINUE = 100;
|
||||
public const HTTP_SWITCHING_PROTOCOLS = 101;
|
||||
public const HTTP_PROCESSING = 102; // RFC2518
|
||||
public const HTTP_EARLY_HINTS = 103; // RFC8297
|
||||
public const HTTP_OK = 200;
|
||||
public const HTTP_CREATED = 201;
|
||||
public const HTTP_ACCEPTED = 202;
|
||||
public const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
|
||||
public const HTTP_NO_CONTENT = 204;
|
||||
public const HTTP_RESET_CONTENT = 205;
|
||||
public const HTTP_PARTIAL_CONTENT = 206;
|
||||
public const HTTP_MULTI_STATUS = 207; // RFC4918
|
||||
public const HTTP_ALREADY_REPORTED = 208; // RFC5842
|
||||
public const HTTP_IM_USED = 226; // RFC3229
|
||||
public const HTTP_MULTIPLE_CHOICES = 300;
|
||||
public const HTTP_MOVED_PERMANENTLY = 301;
|
||||
public const HTTP_FOUND = 302;
|
||||
public const HTTP_SEE_OTHER = 303;
|
||||
public const HTTP_NOT_MODIFIED = 304;
|
||||
public const HTTP_USE_PROXY = 305;
|
||||
public const HTTP_RESERVED = 306;
|
||||
public const HTTP_TEMPORARY_REDIRECT = 307;
|
||||
public const HTTP_PERMANENTLY_REDIRECT = 308; // RFC7238
|
||||
public const HTTP_BAD_REQUEST = 400;
|
||||
public const HTTP_UNAUTHORIZED = 401;
|
||||
public const HTTP_PAYMENT_REQUIRED = 402;
|
||||
public const HTTP_FORBIDDEN = 403;
|
||||
public const HTTP_NOT_FOUND = 404;
|
||||
public const HTTP_METHOD_NOT_ALLOWED = 405;
|
||||
public const HTTP_NOT_ACCEPTABLE = 406;
|
||||
public const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
|
||||
public const HTTP_REQUEST_TIMEOUT = 408;
|
||||
public const HTTP_CONFLICT = 409;
|
||||
public const HTTP_GONE = 410;
|
||||
public const HTTP_LENGTH_REQUIRED = 411;
|
||||
public const HTTP_PRECONDITION_FAILED = 412;
|
||||
public const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
|
||||
public const HTTP_REQUEST_URI_TOO_LONG = 414;
|
||||
public const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
|
||||
public const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
|
||||
public const HTTP_EXPECTATION_FAILED = 417;
|
||||
public const HTTP_I_AM_A_TEAPOT = 418; // RFC2324
|
||||
public const HTTP_MISDIRECTED_REQUEST = 421; // RFC7540
|
||||
public const HTTP_UNPROCESSABLE_ENTITY = 422; // RFC4918
|
||||
public const HTTP_LOCKED = 423; // RFC4918
|
||||
public const HTTP_FAILED_DEPENDENCY = 424; // RFC4918
|
||||
public const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04
|
||||
public const HTTP_UPGRADE_REQUIRED = 426; // RFC2817
|
||||
public const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
|
||||
public const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
|
||||
public const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
|
||||
public const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
public const HTTP_INTERNAL_SERVER_ERROR = 500;
|
||||
public const HTTP_NOT_IMPLEMENTED = 501;
|
||||
public const HTTP_BAD_GATEWAY = 502;
|
||||
public const HTTP_SERVICE_UNAVAILABLE = 503;
|
||||
public const HTTP_GATEWAY_TIMEOUT = 504;
|
||||
public const HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
public const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295
|
||||
public const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918
|
||||
public const HTTP_LOOP_DETECTED = 508; // RFC5842
|
||||
public const HTTP_NOT_EXTENDED = 510; // RFC2774
|
||||
public const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
|
||||
*/
|
||||
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817
|
||||
const HTTP_TOO_EARLY = 425; // RFC-ietf-httpbis-replay-04
|
||||
const HTTP_UPGRADE_REQUIRED = 426; // RFC2817
|
||||
const HTTP_PRECONDITION_REQUIRED = 428; // RFC6585
|
||||
const HTTP_TOO_MANY_REQUESTS = 429; // RFC6585
|
||||
const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431; // RFC6585
|
||||
const HTTP_UNAVAILABLE_FOR_LEGAL_REASONS = 451;
|
||||
const HTTP_INTERNAL_SERVER_ERROR = 500;
|
||||
const HTTP_NOT_IMPLEMENTED = 501;
|
||||
const HTTP_BAD_GATEWAY = 502;
|
||||
const HTTP_SERVICE_UNAVAILABLE = 503;
|
||||
const HTTP_GATEWAY_TIMEOUT = 504;
|
||||
const HTTP_VERSION_NOT_SUPPORTED = 505;
|
||||
const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506; // RFC2295
|
||||
const HTTP_INSUFFICIENT_STORAGE = 507; // RFC4918
|
||||
const HTTP_LOOP_DETECTED = 508; // RFC5842
|
||||
const HTTP_NOT_EXTENDED = 510; // RFC2774
|
||||
const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511; // RFC6585
|
||||
private const HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES = [
|
||||
'must_revalidate' => false,
|
||||
'no_cache' => false,
|
||||
'no_store' => false,
|
||||
'no_transform' => false,
|
||||
'public' => false,
|
||||
'private' => false,
|
||||
'proxy_revalidate' => false,
|
||||
'max_age' => true,
|
||||
's_maxage' => true,
|
||||
'immutable' => false,
|
||||
'last_modified' => true,
|
||||
'etag' => true,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var \Symfony\Component\HttpFoundation\ResponseHeaderBag
|
||||
* @var ResponseHeaderBag
|
||||
*/
|
||||
public $headers;
|
||||
|
||||
@@ -121,8 +137,8 @@ class Response
|
||||
* Status codes translation table.
|
||||
*
|
||||
* The list of codes is complete according to the
|
||||
* {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry}
|
||||
* (last updated 2016-03-01).
|
||||
* {@link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml Hypertext Transfer Protocol (HTTP) Status Code Registry}
|
||||
* (last updated 2021-10-01).
|
||||
*
|
||||
* Unless otherwise noted, the status code is defined in RFC2616.
|
||||
*
|
||||
@@ -164,14 +180,14 @@ class Response
|
||||
410 => 'Gone',
|
||||
411 => 'Length Required',
|
||||
412 => 'Precondition Failed',
|
||||
413 => 'Payload Too Large',
|
||||
413 => 'Content Too Large', // RFC-ietf-httpbis-semantics
|
||||
414 => 'URI Too Long',
|
||||
415 => 'Unsupported Media Type',
|
||||
416 => 'Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
418 => 'I\'m a teapot', // RFC2324
|
||||
421 => 'Misdirected Request', // RFC7540
|
||||
422 => 'Unprocessable Entity', // RFC4918
|
||||
422 => 'Unprocessable Content', // RFC-ietf-httpbis-semantics
|
||||
423 => 'Locked', // RFC4918
|
||||
424 => 'Failed Dependency', // RFC4918
|
||||
425 => 'Too Early', // RFC-ietf-httpbis-replay-04
|
||||
@@ -196,7 +212,7 @@ class Response
|
||||
/**
|
||||
* @throws \InvalidArgumentException When the HTTP status code is not valid
|
||||
*/
|
||||
public function __construct($content = '', int $status = 200, array $headers = [])
|
||||
public function __construct(?string $content = '', int $status = 200, array $headers = [])
|
||||
{
|
||||
$this->headers = new ResponseHeaderBag($headers);
|
||||
$this->setContent($content);
|
||||
@@ -212,14 +228,14 @@ class Response
|
||||
* return Response::create($body, 200)
|
||||
* ->setSharedMaxAge(300);
|
||||
*
|
||||
* @param mixed $content The response content, see setContent()
|
||||
* @param int $status The response status code
|
||||
* @param array $headers An array of response headers
|
||||
*
|
||||
* @return static
|
||||
*
|
||||
* @deprecated since Symfony 5.1, use __construct() instead.
|
||||
*/
|
||||
public static function create($content = '', $status = 200, $headers = [])
|
||||
public static function create(?string $content = '', int $status = 200, array $headers = [])
|
||||
{
|
||||
trigger_deprecation('symfony/http-foundation', '5.1', 'The "%s()" method is deprecated, use "new %s()" instead.', __METHOD__, static::class);
|
||||
|
||||
return new static($content, $status, $headers);
|
||||
}
|
||||
|
||||
@@ -230,7 +246,7 @@ class Response
|
||||
* one that will be sent to the client only if the prepare() method
|
||||
* has been called before.
|
||||
*
|
||||
* @return string The Response as an HTTP string
|
||||
* @return string
|
||||
*
|
||||
* @see prepare()
|
||||
*/
|
||||
@@ -267,10 +283,12 @@ class Response
|
||||
$this->setContent(null);
|
||||
$headers->remove('Content-Type');
|
||||
$headers->remove('Content-Length');
|
||||
// prevent PHP from sending the Content-Type header based on default_mimetype
|
||||
ini_set('default_mimetype', '');
|
||||
} else {
|
||||
// Content-type based on the Request
|
||||
if (!$headers->has('Content-Type')) {
|
||||
$format = $request->getRequestFormat();
|
||||
$format = $request->getRequestFormat(null);
|
||||
if (null !== $format && $mimeType = $request->getMimeType($format)) {
|
||||
$headers->set('Content-Type', $mimeType);
|
||||
}
|
||||
@@ -306,7 +324,7 @@ class Response
|
||||
}
|
||||
|
||||
// Check if we need to send extra expire info headers
|
||||
if ('1.0' == $this->getProtocolVersion() && false !== strpos($headers->get('Cache-Control'), 'no-cache')) {
|
||||
if ('1.0' == $this->getProtocolVersion() && str_contains($headers->get('Cache-Control', ''), 'no-cache')) {
|
||||
$headers->set('pragma', 'no-cache');
|
||||
$headers->set('expires', -1);
|
||||
}
|
||||
@@ -344,7 +362,7 @@ class Response
|
||||
|
||||
// cookies
|
||||
foreach ($this->headers->getCookies() as $cookie) {
|
||||
header('Set-Cookie: '.$cookie->getName().strstr($cookie, '='), false, $this->statusCode);
|
||||
header('Set-Cookie: '.$cookie, false, $this->statusCode);
|
||||
}
|
||||
|
||||
// status
|
||||
@@ -377,6 +395,8 @@ class Response
|
||||
|
||||
if (\function_exists('fastcgi_finish_request')) {
|
||||
fastcgi_finish_request();
|
||||
} elseif (\function_exists('litespeed_finish_request')) {
|
||||
litespeed_finish_request();
|
||||
} elseif (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
|
||||
static::closeOutputBuffers(0, true);
|
||||
}
|
||||
@@ -387,21 +407,11 @@ class Response
|
||||
/**
|
||||
* Sets the response content.
|
||||
*
|
||||
* Valid types are strings, numbers, null, and objects that implement a __toString() method.
|
||||
*
|
||||
* @param mixed $content Content that can be cast to string
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws \UnexpectedValueException
|
||||
*/
|
||||
public function setContent($content)
|
||||
public function setContent(?string $content)
|
||||
{
|
||||
if (null !== $content && !\is_string($content) && !is_numeric($content) && !\is_callable([$content, '__toString'])) {
|
||||
throw new \UnexpectedValueException(sprintf('The Response content must be a string or object implementing __toString(), "%s" given.', \gettype($content)));
|
||||
}
|
||||
|
||||
$this->content = (string) $content;
|
||||
$this->content = $content ?? '';
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -409,7 +419,7 @@ class Response
|
||||
/**
|
||||
* Gets the current response content.
|
||||
*
|
||||
* @return string Content
|
||||
* @return string|false
|
||||
*/
|
||||
public function getContent()
|
||||
{
|
||||
@@ -423,7 +433,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setProtocolVersion(string $version)
|
||||
public function setProtocolVersion(string $version): object
|
||||
{
|
||||
$this->version = $version;
|
||||
|
||||
@@ -452,7 +462,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setStatusCode(int $code, $text = null)
|
||||
public function setStatusCode(int $code, string $text = null): object
|
||||
{
|
||||
$this->statusCode = $code;
|
||||
if ($this->isInvalid()) {
|
||||
@@ -460,7 +470,7 @@ class Response
|
||||
}
|
||||
|
||||
if (null === $text) {
|
||||
$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : 'unknown status';
|
||||
$this->statusText = self::$statusTexts[$code] ?? 'unknown status';
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -493,7 +503,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setCharset(string $charset)
|
||||
public function setCharset(string $charset): object
|
||||
{
|
||||
$this->charset = $charset;
|
||||
|
||||
@@ -574,7 +584,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setPrivate()
|
||||
public function setPrivate(): object
|
||||
{
|
||||
$this->headers->removeCacheControlDirective('public');
|
||||
$this->headers->addCacheControlDirective('private');
|
||||
@@ -591,7 +601,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setPublic()
|
||||
public function setPublic(): object
|
||||
{
|
||||
$this->headers->addCacheControlDirective('public');
|
||||
$this->headers->removeCacheControlDirective('private');
|
||||
@@ -606,7 +616,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setImmutable(bool $immutable = true)
|
||||
public function setImmutable(bool $immutable = true): object
|
||||
{
|
||||
if ($immutable) {
|
||||
$this->headers->addCacheControlDirective('immutable');
|
||||
@@ -628,7 +638,7 @@ class Response
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the response must be revalidated by caches.
|
||||
* Returns true if the response must be revalidated by shared caches once it has become stale.
|
||||
*
|
||||
* This method indicates that the response must not be served stale by a
|
||||
* cache in any circumstance without first revalidating with the origin.
|
||||
@@ -661,7 +671,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setDate(\DateTimeInterface $date)
|
||||
public function setDate(\DateTimeInterface $date): object
|
||||
{
|
||||
if ($date instanceof \DateTime) {
|
||||
$date = \DateTimeImmutable::createFromMutable($date);
|
||||
@@ -684,7 +694,7 @@ class Response
|
||||
return (int) $age;
|
||||
}
|
||||
|
||||
return max(time() - $this->getDate()->format('U'), 0);
|
||||
return max(time() - (int) $this->getDate()->format('U'), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -726,7 +736,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setExpires(\DateTimeInterface $date = null)
|
||||
public function setExpires(\DateTimeInterface $date = null): object
|
||||
{
|
||||
if (null === $date) {
|
||||
$this->headers->remove('Expires');
|
||||
@@ -764,7 +774,7 @@ class Response
|
||||
}
|
||||
|
||||
if (null !== $this->getExpires()) {
|
||||
return (int) ($this->getExpires()->format('U') - $this->getDate()->format('U'));
|
||||
return (int) $this->getExpires()->format('U') - (int) $this->getDate()->format('U');
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -779,7 +789,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setMaxAge(int $value)
|
||||
public function setMaxAge(int $value): object
|
||||
{
|
||||
$this->headers->addCacheControlDirective('max-age', $value);
|
||||
|
||||
@@ -795,7 +805,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setSharedMaxAge(int $value)
|
||||
public function setSharedMaxAge(int $value): object
|
||||
{
|
||||
$this->setPublic();
|
||||
$this->headers->addCacheControlDirective('s-maxage', $value);
|
||||
@@ -829,7 +839,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setTtl(int $seconds)
|
||||
public function setTtl(int $seconds): object
|
||||
{
|
||||
$this->setSharedMaxAge($this->getAge() + $seconds);
|
||||
|
||||
@@ -845,7 +855,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setClientTtl(int $seconds)
|
||||
public function setClientTtl(int $seconds): object
|
||||
{
|
||||
$this->setMaxAge($this->getAge() + $seconds);
|
||||
|
||||
@@ -873,7 +883,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setLastModified(\DateTimeInterface $date = null)
|
||||
public function setLastModified(\DateTimeInterface $date = null): object
|
||||
{
|
||||
if (null === $date) {
|
||||
$this->headers->remove('Last-Modified');
|
||||
@@ -911,12 +921,12 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setEtag(string $etag = null, bool $weak = false)
|
||||
public function setEtag(string $etag = null, bool $weak = false): object
|
||||
{
|
||||
if (null === $etag) {
|
||||
$this->headers->remove('Etag');
|
||||
} else {
|
||||
if (0 !== strpos($etag, '"')) {
|
||||
if (!str_starts_with($etag, '"')) {
|
||||
$etag = '"'.$etag.'"';
|
||||
}
|
||||
|
||||
@@ -929,7 +939,7 @@ class Response
|
||||
/**
|
||||
* Sets the response's cache headers (validation and/or expiration).
|
||||
*
|
||||
* Available options are: etag, last_modified, max_age, s_maxage, private, public and immutable.
|
||||
* Available options are: must_revalidate, no_cache, no_store, no_transform, public, private, proxy_revalidate, max_age, s_maxage, immutable, last_modified and etag.
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
@@ -937,9 +947,9 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setCache(array $options)
|
||||
public function setCache(array $options): object
|
||||
{
|
||||
if ($diff = array_diff(array_keys($options), ['etag', 'last_modified', 'max_age', 's_maxage', 'private', 'public', 'immutable'])) {
|
||||
if ($diff = array_diff(array_keys($options), array_keys(self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES))) {
|
||||
throw new \InvalidArgumentException(sprintf('Response does not support the following options: "%s".', implode('", "', $diff)));
|
||||
}
|
||||
|
||||
@@ -959,6 +969,16 @@ class Response
|
||||
$this->setSharedMaxAge($options['s_maxage']);
|
||||
}
|
||||
|
||||
foreach (self::HTTP_RESPONSE_CACHE_CONTROL_DIRECTIVES as $directive => $hasValue) {
|
||||
if (!$hasValue && isset($options[$directive])) {
|
||||
if ($options[$directive]) {
|
||||
$this->headers->addCacheControlDirective(str_replace('_', '-', $directive));
|
||||
} else {
|
||||
$this->headers->removeCacheControlDirective(str_replace('_', '-', $directive));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['public'])) {
|
||||
if ($options['public']) {
|
||||
$this->setPublic();
|
||||
@@ -975,10 +995,6 @@ class Response
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($options['immutable'])) {
|
||||
$this->setImmutable((bool) $options['immutable']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -990,11 +1006,11 @@ class Response
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @see http://tools.ietf.org/html/rfc2616#section-10.3.5
|
||||
* @see https://tools.ietf.org/html/rfc2616#section-10.3.5
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setNotModified()
|
||||
public function setNotModified(): object
|
||||
{
|
||||
$this->setStatusCode(304);
|
||||
$this->setContent(null);
|
||||
@@ -1024,16 +1040,16 @@ class Response
|
||||
*/
|
||||
public function getVary(): array
|
||||
{
|
||||
if (!$vary = $this->headers->get('Vary', null, false)) {
|
||||
if (!$vary = $this->headers->all('Vary')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$ret = [];
|
||||
foreach ($vary as $item) {
|
||||
$ret = array_merge($ret, preg_split('/[\s,]+/', $item));
|
||||
$ret[] = preg_split('/[\s,]+/', $item);
|
||||
}
|
||||
|
||||
return $ret;
|
||||
return array_merge([], ...$ret);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1046,7 +1062,7 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function setVary($headers, bool $replace = true)
|
||||
public function setVary($headers, bool $replace = true): object
|
||||
{
|
||||
$this->headers->set('Vary', $headers, $replace);
|
||||
|
||||
@@ -1060,8 +1076,6 @@ class Response
|
||||
* If the Response is not modified, it sets the status code to 304 and
|
||||
* removes the actual content by calling the setNotModified() method.
|
||||
*
|
||||
* @return bool true if the Response validators match the Request, false otherwise
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public function isNotModified(Request $request): bool
|
||||
@@ -1074,12 +1088,26 @@ class Response
|
||||
$lastModified = $this->headers->get('Last-Modified');
|
||||
$modifiedSince = $request->headers->get('If-Modified-Since');
|
||||
|
||||
if ($etags = $request->getETags()) {
|
||||
$notModified = \in_array($this->getEtag(), $etags) || \in_array('*', $etags);
|
||||
}
|
||||
if (($ifNoneMatchEtags = $request->getETags()) && (null !== $etag = $this->getEtag())) {
|
||||
if (0 == strncmp($etag, 'W/', 2)) {
|
||||
$etag = substr($etag, 2);
|
||||
}
|
||||
|
||||
if ($modifiedSince && $lastModified) {
|
||||
$notModified = strtotime($modifiedSince) >= strtotime($lastModified) && (!$etags || $notModified);
|
||||
// Use weak comparison as per https://tools.ietf.org/html/rfc7232#section-3.2.
|
||||
foreach ($ifNoneMatchEtags as $ifNoneMatchEtag) {
|
||||
if (0 == strncmp($ifNoneMatchEtag, 'W/', 2)) {
|
||||
$ifNoneMatchEtag = substr($ifNoneMatchEtag, 2);
|
||||
}
|
||||
|
||||
if ($ifNoneMatchEtag === $etag || '*' === $ifNoneMatchEtag) {
|
||||
$notModified = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Only do If-Modified-Since date comparison when If-None-Match is not present as per https://tools.ietf.org/html/rfc7232#section-3.3.
|
||||
elseif ($modifiedSince && $lastModified) {
|
||||
$notModified = strtotime($modifiedSince) >= strtotime($lastModified);
|
||||
}
|
||||
|
||||
if ($notModified) {
|
||||
@@ -1092,7 +1120,7 @@ class Response
|
||||
/**
|
||||
* Is response invalid?
|
||||
*
|
||||
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
* @see https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
@@ -1208,11 +1236,11 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
public static function closeOutputBuffers(int $targetLevel, bool $flush)
|
||||
public static function closeOutputBuffers(int $targetLevel, bool $flush): void
|
||||
{
|
||||
$status = ob_get_status(true);
|
||||
$level = \count($status);
|
||||
$flags = PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? PHP_OUTPUT_HANDLER_FLUSHABLE : PHP_OUTPUT_HANDLER_CLEANABLE);
|
||||
$flags = \PHP_OUTPUT_HANDLER_REMOVABLE | ($flush ? \PHP_OUTPUT_HANDLER_FLUSHABLE : \PHP_OUTPUT_HANDLER_CLEANABLE);
|
||||
|
||||
while ($level-- > $targetLevel && ($s = $status[$level]) && (!isset($s['del']) ? !isset($s['flags']) || ($s['flags'] & $flags) === $flags : $s['del'])) {
|
||||
if ($flush) {
|
||||
@@ -1223,6 +1251,22 @@ class Response
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a response as safe according to RFC8674.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc8674
|
||||
*/
|
||||
public function setContentSafe(bool $safe = true): void
|
||||
{
|
||||
if ($safe) {
|
||||
$this->headers->set('Preference-Applied', 'safe');
|
||||
} elseif ('safe' === $this->headers->get('Preference-Applied')) {
|
||||
$this->headers->remove('Preference-Applied');
|
||||
}
|
||||
|
||||
$this->setVary('Prefer', false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if we need to remove Cache-Control for SSL encrypted downloads when using IE < 9.
|
||||
*
|
||||
@@ -1230,9 +1274,9 @@ class Response
|
||||
*
|
||||
* @final
|
||||
*/
|
||||
protected function ensureIEOverSSLCompatibility(Request $request)
|
||||
protected function ensureIEOverSSLCompatibility(Request $request): void
|
||||
{
|
||||
if (false !== stripos($this->headers->get('Content-Disposition'), 'attachment') && 1 == preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT'), $match) && true === $request->isSecure()) {
|
||||
if (false !== stripos($this->headers->get('Content-Disposition') ?? '', 'attachment') && 1 == preg_match('/MSIE (.*?);/i', $request->server->get('HTTP_USER_AGENT') ?? '', $match) && true === $request->isSecure()) {
|
||||
if ((int) preg_replace('/(MSIE )(.*?);/', '$2', $match[0]) < 9) {
|
||||
$this->headers->remove('Cache-Control');
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user