Fixes #16766: yii\filters\ContentNegotiator was not setting Vary header to inform cache recipients

This commit is contained in:
Kot
2018-10-07 19:03:01 +03:00
committed by Alexander Makarov
parent af3b8b2f23
commit 4e6eb5c814
3 changed files with 48 additions and 0 deletions

View File

@ -4,6 +4,7 @@ Yii Framework 2 Change Log
2.0.16 under development
------------------------
- Bug #16766: `yii\filters\ContentNegotiator` was not setting `Vary` header to inform cache recipients (koteq, cebe, samdark)
- Bug #11960: Fixed `checked` option ignore in `yii\helpers\BaseHtml::checkbox()` (misantron)
- Bug #14759: Fixed `yii\web\JsonResponseFormatter` output for `null` data (misantron)
- Bug #16490: Fix schema on rbac init (marcelodeandrade)

View File

@ -154,9 +154,15 @@ class ContentNegotiator extends ActionFilter implements BootstrapInterface
$request = $this->request ?: Yii::$app->getRequest();
$response = $this->response ?: Yii::$app->getResponse();
if (!empty($this->formats)) {
if (\count($this->formats) > 1) {
$response->getHeaders()->add('Vary', 'Accept');
}
$this->negotiateContentType($request, $response);
}
if (!empty($this->languages)) {
if (\count($this->languages) > 1) {
$response->getHeaders()->add('Vary', 'Accept-Language');
}
Yii::$app->language = $this->negotiateLanguage($request);
}
}

View File

@ -76,4 +76,45 @@ class ContentNegotiatorTest extends TestCase
$filter->beforeAction($action);
}
public function testVaryHeader()
{
list($action, $filter) = $this->mockActionAndFilter();
$filter->formats = [];
$filter->languages = [];
$filter->beforeAction($action);
$this->assertFalse($filter->response->getHeaders()->has('Vary'));
list($action, $filter) = $this->mockActionAndFilter();
$filter->formats = ['application/json' => Response::FORMAT_JSON];
$filter->languages = ['en'];
$filter->beforeAction($action);
$this->assertFalse($filter->response->getHeaders()->has('Vary')); // There is still nothing to vary
list($action, $filter) = $this->mockActionAndFilter();
$filter->formats = [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
];
$filter->languages = [];
$filter->beforeAction($action);
$this->assertContains('Accept', $filter->response->getHeaders()->get('Vary', [], false));
list($action, $filter) = $this->mockActionAndFilter();
$filter->formats = [];
$filter->languages = ['en', 'de'];
$filter->beforeAction($action);
$this->assertContains('Accept-Language', $filter->response->getHeaders()->get('Vary', [], false));
list($action, $filter) = $this->mockActionAndFilter();
$filter->formats = [
'application/json' => Response::FORMAT_JSON,
'application/xml' => Response::FORMAT_XML,
];
$filter->languages = ['en', 'de'];
$filter->beforeAction($action);
$varyHeader = $filter->response->getHeaders()->get('Vary', [], false);
$this->assertContains('Accept', $varyHeader);
$this->assertContains('Accept-Language', $varyHeader);
}
}