diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index 6b54305670..f63d3c5432 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -6,13 +6,13 @@ Yii Framework 2 Change Log - Bug #7529: Fixed `yii\web\Response::sendContentAsFile()` that was broken in 2.0.3 (samdark) - Bug #7603: Fixed escape characters in `FormatConverter` to work with unicode characters (maddoger, cebe) -- Bug: Added `yii\filters\PageCache::cacheCookies` to allow caching cookies selectively and turn off cookie caching by default (qiangxue) - Enh #6895: Added `ignoreCategories` config option for message command to ignore categories specified (samdark) - Enh #6975: Pressing arrows while focused in inputs of Active Form with `validateOnType` enabled no longer triggers validation (slinstj) - Enh #7488: Added `StringHelper::explode` to perform explode with trimming and skipping of empty elements (SilverFire, nineinchnick, creocoder, samdark) - Enh #7530: Improved default values for `yii\data\Sort` link labels in a `ListView` when used with an `ActiveDataProvider` (cebe) - Enh #7562: `yii help` now lists all sub-commands by default (callmez) - Enh #7571: HTTP status 500 and "An internal server error occurred." are now returned in case there was an exception in layout and `YII_DEBUG` is false (samdark) +- Enh #7850: Added `yii\filters\PageCache::cacheCookies` and `cacheHeaders` to allow selectively caching cookies and HTTP headers (qiangxue) - Enh: Added `yii\helper\Console::wrapText()` method to wrap indented text by console window width and used it in `yii help` command (cebe) - Chg: Updated dependency to `cebe/markdown` to version `1.1.x` (cebe) diff --git a/framework/filters/PageCache.php b/framework/filters/PageCache.php index 6d7bdd1073..1d0cfa2ce6 100644 --- a/framework/filters/PageCache.php +++ b/framework/filters/PageCache.php @@ -113,6 +113,13 @@ class PageCache extends ActionFilter * @since 2.0.4 */ public $cacheCookies = false; + /** + * @var boolean|array a boolean value indicating whether to cache all HTTP headers, or an array of + * HTTP header names (case-insensitive) indicating which HTTP headers can be cached. + * Note if your HTTP headers contain sensitive information, you should white-list which headers can be cached. + * @since 2.0.4 + */ + public $cacheHeaders = true; /** @@ -182,10 +189,12 @@ class PageCache extends ActionFilter $response->statusText = $data['statusText']; } if (isset($data['headers']) && is_array($data['headers'])) { - $response->getHeaders()->fromArray($data['headers']); + $headers = $response->getHeaders()->toArray(); + $response->getHeaders()->fromArray(array_merge($data['headers'], $headers)); } if (isset($data['cookies']) && is_array($data['cookies'])) { - $response->getCookies()->fromArray($data['cookies']); + $cookies = $response->getCookies()->toArray(); + $response->getCookies()->fromArray(array_merge($data['cookies'], $cookies)); } } @@ -202,8 +211,21 @@ class PageCache extends ActionFilter 'version' => $response->version, 'statusCode' => $response->statusCode, 'statusText' => $response->statusText, - 'headers' => $response->getHeaders()->toArray(), ]; + if (!empty($this->cacheHeaders)) { + $headers = $response->getHeaders()->toArray(); + if (is_array($this->cacheHeaders)) { + $filtered = []; + foreach ($this->cacheHeaders as $name) { + $name = strtolower($name); + if (isset($headers[$name])) { + $filtered[$name] = $headers[$name]; + } + } + $headers = $filtered; + } + $data['headers'] = $headers; + } if (!empty($this->cacheCookies)) { $cookies = $response->getCookies()->toArray(); if (is_array($this->cacheCookies)) {