HttpCache no longer returns 304 HTTP code when callbacks return null (#12099)

This commit is contained in:
Sergey Makinen
2016-08-08 23:58:39 +03:00
parent ef0658726f
commit bbbb98626f
3 changed files with 21 additions and 8 deletions

View File

@@ -26,6 +26,7 @@ Yii Framework 2 Change Log
- Enh #11979: Added `yii\mutex\OracleMutex` which implements mutex "lock" mechanism via Oracle locks (zlakomanoff) - Enh #11979: Added `yii\mutex\OracleMutex` which implements mutex "lock" mechanism via Oracle locks (zlakomanoff)
- Enh #12082: Used `jQuery.on(` instead of event method to ensure forwards compatibility (newerton) - Enh #12082: Used `jQuery.on(` instead of event method to ensure forwards compatibility (newerton)
- Enh #12028: Add -h|--help option to console command to display help information (pana1990) - Enh #12028: Add -h|--help option to console command to display help information (pana1990)
- Enh #12099: HttpCache no longer returns 304 HTTP code when callbacks return null (sergeymakinen)
- Bug #12053: `./yii migrate/create` was generating wrong code when using `bigPrimaryKey` (VojtechH, samdark) - Bug #12053: `./yii migrate/create` was generating wrong code when using `bigPrimaryKey` (VojtechH, samdark)
- Bug #11907: Fixed `yii\helpers\Console::getScreenSize()` on Windows was giving out width and height swapped (Spell6inder, samdark, cebe) - Bug #11907: Fixed `yii\helpers\Console::getScreenSize()` on Windows was giving out width and height swapped (Spell6inder, samdark, cebe)
- Bug #11973: Fixed `yii\helpers\BaseHtml::getAttributeValue()` to work with `items[]` notation correctly (silverfire) - Bug #11973: Fixed `yii\helpers\BaseHtml::getAttributeValue()` to work with `items[]` notation correctly (silverfire)

View File

@@ -130,7 +130,9 @@ class HttpCache extends ActionFilter
} }
if ($this->etagSeed !== null) { if ($this->etagSeed !== null) {
$seed = call_user_func($this->etagSeed, $action, $this->params); $seed = call_user_func($this->etagSeed, $action, $this->params);
$etag = $this->generateEtag($seed); if ($seed !== null) {
$etag = $this->generateEtag($seed);
}
} }
$this->sendCacheControlHeader(); $this->sendCacheControlHeader();
@@ -140,20 +142,22 @@ class HttpCache extends ActionFilter
$response->getHeaders()->set('Etag', $etag); $response->getHeaders()->set('Etag', $etag);
} }
if ($this->validateCache($lastModified, $etag)) { $cacheValid = $this->validateCache($lastModified, $etag);
// https://tools.ietf.org/html/rfc7232#section-4.1
if ($lastModified !== null && (!$cacheValid || ($cacheValid && $etag === null))) {
$response->getHeaders()->set('Last-Modified', gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
}
if ($cacheValid) {
$response->setStatusCode(304); $response->setStatusCode(304);
return false; return false;
} }
if ($lastModified !== null) {
$response->getHeaders()->set('Last-Modified', gmdate('D, d M Y H:i:s', $lastModified) . ' GMT');
}
return true; return true;
} }
/** /**
* Validates if the HTTP cache contains valid content. * Validates if the HTTP cache contains valid content.
* If both Last-Modified and ETag are null, returns false.
* @param integer $lastModified the calculated Last-Modified value in terms of a UNIX timestamp. * @param integer $lastModified the calculated Last-Modified value in terms of a UNIX timestamp.
* If null, the Last-Modified header will not be validated. * If null, the Last-Modified header will not be validated.
* @param string $etag the calculated ETag value. If null, the ETag header will not be validated. * @param string $etag the calculated ETag value. If null, the ETag header will not be validated.
@@ -168,7 +172,7 @@ class HttpCache extends ActionFilter
} elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { } elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
return $lastModified !== null && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified; return $lastModified !== null && @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified;
} else { } else {
return $etag === null && $lastModified === null; return false;
} }
} }

View File

@@ -38,7 +38,7 @@ class HttpCacheTest extends \yiiunit\TestCase
$method->setAccessible(true); $method->setAccessible(true);
unset($_SERVER['HTTP_IF_MODIFIED_SINCE'], $_SERVER['HTTP_IF_NONE_MATCH']); unset($_SERVER['HTTP_IF_MODIFIED_SINCE'], $_SERVER['HTTP_IF_NONE_MATCH']);
$this->assertTrue($method->invoke($httpCache, null, null)); $this->assertFalse($method->invoke($httpCache, null, null));
$this->assertFalse($method->invoke($httpCache, 0, null)); $this->assertFalse($method->invoke($httpCache, 0, null));
$this->assertFalse($method->invoke($httpCache, 0, '"foo"')); $this->assertFalse($method->invoke($httpCache, 0, '"foo"'));
@@ -65,6 +65,14 @@ class HttpCacheTest extends \yiiunit\TestCase
{ {
$httpCache = new HttpCache; $httpCache = new HttpCache;
$httpCache->weakEtag = false; $httpCache->weakEtag = false;
$httpCache->etagSeed = function($action, $params) {
return null;
};
$httpCache->beforeAction(null);
$response = Yii::$app->getResponse();
$this->assertFalse($response->getHeaders()->offsetExists('ETag'));
$httpCache->etagSeed = function($action, $params) { $httpCache->etagSeed = function($action, $params) {
return ''; return '';
}; };