Commit ffd4be4d authored by catch's avatar catch
Browse files

Issue #3272985 by recrit, grasmash, catch, smustgrave, xjm: RSS Feed header...

Issue #3272985 by recrit, grasmash, catch, smustgrave, xjm: RSS Feed header reverts to text/html when cached

(cherry picked from commit b20ec518)
parent bcc82ff1
Loading
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
@@ -116,9 +116,47 @@ public static function buildResponse($view_id, $display_id, array $args = []) {
    $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}
   */
+5 −0
Original line number Diff line number Diff line
@@ -67,6 +67,11 @@ public function render() {
      '#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;
+5 −0
Original line number Diff line number Diff line
@@ -132,6 +132,11 @@ public function render() {
      '#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;
+34 −0
Original line number Diff line number Diff line
@@ -204,4 +204,38 @@ public function testDisabledLinkedDisplay() {
    $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');
  }

}
+0 −12
Original line number Diff line number Diff line
@@ -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');
  }
}

/**