Issue #3272985 by recrit, grasmash, catch, smustgrave, xjm: RSS Feed header reverts to text/html when cached
parent
9cb09532f0
commit
b20ec5185c
|
@ -116,9 +116,47 @@ class Feed extends PathPluginBase implements ResponseDisplayPluginInterface {
|
|||
$cache_metadata = CacheableMetadata::createFromRenderArray($build);
|
||||
$response->addCacheableDependency($cache_metadata);
|
||||
|
||||
// Set the HTTP headers and status code on the response if any bubbled.
|
||||
if (!empty($build['#attached']['http_header'])) {
|
||||
static::setHeaders($response, $build['#attached']['http_header']);
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets headers on a response object.
|
||||
*
|
||||
* @param \Drupal\Core\Cache\CacheableResponse $response
|
||||
* The HTML response to update.
|
||||
* @param array $headers
|
||||
* The headers to set, as an array. The items in this array should be as
|
||||
* follows:
|
||||
* - The header name.
|
||||
* - The header value.
|
||||
* - (optional) Whether to replace a current value with the new one, or add
|
||||
* it to the others. If the value is not replaced, it will be appended,
|
||||
* resulting in a header like this: 'Header: value1,value2'.
|
||||
*
|
||||
* @see \Drupal\Core\Render\HtmlResponseAttachmentsProcessor::setHeaders()
|
||||
*/
|
||||
protected static function setHeaders(CacheableResponse $response, array $headers): void {
|
||||
foreach ($headers as $values) {
|
||||
$name = $values[0];
|
||||
$value = $values[1];
|
||||
$replace = !empty($values[2]);
|
||||
|
||||
// Drupal treats the HTTP response status code like a header, even though
|
||||
// it really is not.
|
||||
if (strtolower($name) === 'status') {
|
||||
$response->setStatusCode($value);
|
||||
}
|
||||
else {
|
||||
$response->headers->set($name, $value, $replace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
|
@ -67,6 +67,11 @@ class Opml extends StylePluginBase {
|
|||
'#view' => $this->view,
|
||||
'#options' => $this->options,
|
||||
'#rows' => $rows,
|
||||
'#attached' => [
|
||||
'http_header' => [
|
||||
['Content-Type', 'text/xml; charset=utf-8'],
|
||||
],
|
||||
],
|
||||
];
|
||||
unset($this->view->row_index);
|
||||
return $build;
|
||||
|
|
|
@ -132,6 +132,11 @@ class Rss extends StylePluginBase {
|
|||
'#view' => $this->view,
|
||||
'#options' => $this->options,
|
||||
'#rows' => $rows,
|
||||
'#attached' => [
|
||||
'http_header' => [
|
||||
['Content-Type', 'application/rss+xml; charset=utf-8'],
|
||||
],
|
||||
],
|
||||
];
|
||||
unset($this->view->row_index);
|
||||
return $build;
|
||||
|
|
|
@ -204,4 +204,38 @@ class DisplayFeedTest extends ViewTestBase {
|
|||
$this->assertSession()->statusCodeEquals(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the cacheability of the feed display.
|
||||
*/
|
||||
public function testFeedCacheability(): void {
|
||||
// Test as an anonymous user.
|
||||
$this->drupalLogout();
|
||||
|
||||
// Set the page cache max age to a value greater than zero.
|
||||
$config = $this->config('system.performance');
|
||||
$config->set('cache.page.max_age', 300);
|
||||
$config->save();
|
||||
|
||||
// Uninstall all page cache modules that could cache the HTTP response
|
||||
// headers.
|
||||
\Drupal::service('module_installer')->uninstall([
|
||||
'page_cache',
|
||||
'dynamic_page_cache',
|
||||
]);
|
||||
|
||||
// Reset all so that the config and module changes are active.
|
||||
$this->resetAll();
|
||||
|
||||
$url = 'test-feed-display.xml';
|
||||
$this->drupalGet($url);
|
||||
$this->assertSession()->statusCodeEquals(200);
|
||||
$this->assertSession()->responseHeaderEquals('Cache-Control', 'max-age=300, public');
|
||||
$this->assertSession()->responseHeaderEquals('Content-Type', 'application/rss+xml; charset=utf-8');
|
||||
|
||||
// Visit the page again to get the cached response.
|
||||
$this->drupalGet($url);
|
||||
$this->assertSession()->responseHeaderEquals('Cache-Control', 'max-age=300, public');
|
||||
$this->assertSession()->responseHeaderEquals('Content-Type', 'application/rss+xml; charset=utf-8');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -928,12 +928,6 @@ function template_preprocess_views_view_rss(&$variables) {
|
|||
$variables['namespaces'] = new Attribute($style->namespaces);
|
||||
$variables['items'] = $items;
|
||||
$variables['channel_elements'] = $style->channel_elements;
|
||||
|
||||
// During live preview we don't want to output the header since the contents
|
||||
// of the feed are being displayed inside a normal HTML page.
|
||||
if (empty($variables['view']->live_preview)) {
|
||||
$variables['view']->getResponse()->headers->set('Content-Type', 'application/rss+xml; charset=utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -995,12 +989,6 @@ function template_preprocess_views_view_opml(&$variables) {
|
|||
$variables['title'] = $title;
|
||||
$variables['items'] = $items;
|
||||
$variables['updated'] = gmdate(DATE_RFC2822, \Drupal::time()->getRequestTime());
|
||||
|
||||
// During live preview we don't want to output the header since the contents
|
||||
// of the feed are being displayed inside a normal HTML page.
|
||||
if (empty($variables['view']->live_preview)) {
|
||||
$variables['view']->getResponse()->headers->set('Content-Type', 'text/xml; charset=utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue