mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 05:48:11 +08:00
Additional fix to #4728.
This commit is contained in:
@ -107,12 +107,10 @@ Expensive ETag generation may defeat the purpose of using `HttpCache` and introd
|
||||
since they need to be re-evaluated on every request. Try to find a simple expression that invalidates
|
||||
the cache if the page content has been modified.
|
||||
|
||||
|
||||
> Note: In compliance to [RFC 7232, section 2.4](http://tools.ietf.org/html/rfc7232#section-2.4),
|
||||
> Note: In compliance to [RFC 7232](http://tools.ietf.org/html/rfc7232#section-2.4),
|
||||
`HttpCache` will send out both `ETag` and `Last-Modified` headers if they are both configured.
|
||||
However, in order to satisfy [section 3.3](http://tools.ietf.org/html/rfc7232#section-3.3) the
|
||||
`If-None-Match` client header will always take precedence over `If-Modified-Since` during validation; meaning
|
||||
latter one is going to be ignored if a `If-None-Match` header is present in the request.
|
||||
And if the client sends both of the `If-None-Match` header and the `If-Modified-Since` header, only the former
|
||||
will be respected.
|
||||
|
||||
|
||||
## `Cache-Control` Header <a name="cache-control"></a>
|
||||
|
||||
@ -130,7 +130,6 @@ class HttpCache extends ActionFilter
|
||||
|
||||
if ($this->validateCache($lastModified, $etag)) {
|
||||
$response->setStatusCode(304);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -150,10 +149,14 @@ class HttpCache extends ActionFilter
|
||||
*/
|
||||
protected function validateCache($lastModified, $etag)
|
||||
{
|
||||
if($etag !== null && in_array($etag, Yii::$app->request->getEtags(), true)) {
|
||||
return true;
|
||||
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
|
||||
// HTTP_IF_NONE_MATCH takes precedence over HTTP_IF_MODIFIED_SINCE
|
||||
// http://tools.ietf.org/html/rfc7232#section-3.3
|
||||
return $etag === null || in_array($etag, Yii::$app->request->getEtags(), true);
|
||||
} elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
|
||||
return $lastModified === null || @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified;
|
||||
} else {
|
||||
return $lastModified !== null && isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified;
|
||||
return $etag === null && $lastModified === null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -37,7 +37,10 @@ class HttpCacheTest extends \yiiunit\TestCase
|
||||
$method = new \ReflectionMethod($httpCache, 'validateCache');
|
||||
$method->setAccessible(true);
|
||||
|
||||
$this->assertFalse($method->invoke($httpCache, null, null));
|
||||
unset($_SERVER['HTTP_IF_MODIFIED_SINCE'], $_SERVER['HTTP_IF_NONE_MATCH']);
|
||||
$this->assertTrue($method->invoke($httpCache, null, null));
|
||||
$this->assertFalse($method->invoke($httpCache, 0, null));
|
||||
$this->assertFalse($method->invoke($httpCache, 0, '"foo"'));
|
||||
|
||||
$_SERVER['HTTP_IF_MODIFIED_SINCE'] = 'Thu, 01 Jan 1970 00:00:00 GMT';
|
||||
$this->assertTrue($method->invoke($httpCache, 0, null));
|
||||
@ -45,8 +48,10 @@ class HttpCacheTest extends \yiiunit\TestCase
|
||||
|
||||
$_SERVER['HTTP_IF_NONE_MATCH'] = '"foo"';
|
||||
$this->assertTrue($method->invoke($httpCache, 0, '"foo"'));
|
||||
$this->assertFalse($method->invoke($httpCache, 0, '"foos"'));
|
||||
$this->assertTrue($method->invoke($httpCache, 1, '"foo"'));
|
||||
$this->assertFalse($method->invoke($httpCache, null, null));
|
||||
$this->assertFalse($method->invoke($httpCache, 1, '"foos"'));
|
||||
$this->assertTrue($method->invoke($httpCache, null, null));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,4 +72,4 @@ class HttpCacheTest extends \yiiunit\TestCase
|
||||
$this->assertStringStartsWith('"', $etag);
|
||||
$this->assertStringEndsWith('"', $etag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user