Add support for safe preference - RFC8674
This commit is contained in:
parent
20bf17f6ad
commit
7f2cef759c
@ -7,6 +7,8 @@ CHANGELOG
|
||||
* Deprecate `Response::create()`, `JsonResponse::create()`,
|
||||
`RedirectResponse::create()`, and `StreamedResponse::create()` methods (use
|
||||
`__construct()` instead)
|
||||
* added `Request::preferSafeContent()` and `Response::setContentSafe()` to handle "safe" HTTP preference
|
||||
according to [RFC 8674](https://tools.ietf.org/html/rfc8674)
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
@ -199,6 +199,11 @@ class Request
|
||||
private $isHostValid = true;
|
||||
private $isForwardedValid = true;
|
||||
|
||||
/**
|
||||
* @var bool|null
|
||||
*/
|
||||
private $isSafeContentPreferred;
|
||||
|
||||
private static $trustedHeaderSet = -1;
|
||||
|
||||
private static $forwardedParams = [
|
||||
@ -1702,6 +1707,29 @@ class Request
|
||||
return 'XMLHttpRequest' == $this->headers->get('X-Requested-With');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the client browser prefers safe content or not according to RFC8674.
|
||||
*
|
||||
* @see https://tools.ietf.org/html/rfc8674
|
||||
*/
|
||||
public function preferSafeContent(): bool
|
||||
{
|
||||
if (null !== $this->isSafeContentPreferred) {
|
||||
return $this->isSafeContentPreferred;
|
||||
}
|
||||
|
||||
if (!$this->isSecure()) {
|
||||
// see https://tools.ietf.org/html/rfc8674#section-3
|
||||
$this->isSafeContentPreferred = false;
|
||||
|
||||
return $this->isSafeContentPreferred;
|
||||
}
|
||||
|
||||
$this->isSafeContentPreferred = AcceptHeader::fromString($this->headers->get('Prefer'))->has('safe');
|
||||
|
||||
return $this->isSafeContentPreferred;
|
||||
}
|
||||
|
||||
/*
|
||||
* The following methods are derived from code of the Zend Framework (1.10dev - 2010-01-24)
|
||||
*
|
||||
|
@ -1210,6 +1210,22 @@ class Response
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark 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.
|
||||
*
|
||||
|
@ -2325,6 +2325,64 @@ class RequestTest extends TestCase
|
||||
[null, ['REMOTE_ADDR', '2.2.2.2'], ['2.2.2.2']],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider preferSafeContentData
|
||||
*/
|
||||
public function testPreferSafeContent($server, bool $safePreferenceExpected)
|
||||
{
|
||||
$request = new Request([], [], [], [], [], $server);
|
||||
|
||||
$this->assertEquals($safePreferenceExpected, $request->preferSafeContent());
|
||||
}
|
||||
|
||||
public function preferSafeContentData()
|
||||
{
|
||||
return [
|
||||
[[], false],
|
||||
[
|
||||
[
|
||||
'HTTPS' => 'on',
|
||||
],
|
||||
false,
|
||||
],
|
||||
[
|
||||
[
|
||||
'HTTPS' => 'off',
|
||||
'HTTP_PREFER' => 'safe',
|
||||
],
|
||||
false,
|
||||
],
|
||||
[
|
||||
[
|
||||
'HTTPS' => 'on',
|
||||
'HTTP_PREFER' => 'safe',
|
||||
],
|
||||
true,
|
||||
],
|
||||
[
|
||||
[
|
||||
'HTTPS' => 'on',
|
||||
'HTTP_PREFER' => 'unknown-preference',
|
||||
],
|
||||
false,
|
||||
],
|
||||
[
|
||||
[
|
||||
'HTTPS' => 'on',
|
||||
'HTTP_PREFER' => 'unknown-preference=42, safe',
|
||||
],
|
||||
true,
|
||||
],
|
||||
[
|
||||
[
|
||||
'HTTPS' => 'on',
|
||||
'HTTP_PREFER' => 'safe, unknown-preference=42',
|
||||
],
|
||||
true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class RequestContentProxy extends Request
|
||||
|
@ -1040,6 +1040,24 @@ class ResponseTest extends ResponseTestCase
|
||||
{
|
||||
$this->assertEquals($reasonPhrase, Response::$statusTexts[$code]);
|
||||
}
|
||||
|
||||
public function testSetContentSafe()
|
||||
{
|
||||
$response = new Response();
|
||||
|
||||
$this->assertFalse($response->headers->has('Preference-Applied'));
|
||||
$this->assertFalse($response->headers->has('Vary'));
|
||||
|
||||
$response->setContentSafe();
|
||||
|
||||
$this->assertSame('safe', $response->headers->get('Preference-Applied'));
|
||||
$this->assertSame('Prefer', $response->headers->get('Vary'));
|
||||
|
||||
$response->setContentSafe(false);
|
||||
|
||||
$this->assertFalse($response->headers->has('Preference-Applied'));
|
||||
$this->assertSame('Prefer', $response->headers->get('Vary'));
|
||||
}
|
||||
}
|
||||
|
||||
class StringableObject
|
||||
|
Reference in New Issue
Block a user