From c21e099932ca96b22683b1b097cc74246001c410 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Wed, 3 Jun 2015 15:11:26 +0100
Subject: [PATCH] Issue #2477461 by borisson_, googletorp, Wim Leers, Crell:
 Move X-Generator header to its own listener

---
 core/core.services.yml                        |  4 ++
 .../ResponseGeneratorSubscriber.php           | 45 ++++++++++++
 .../Core/Render/MainContent/HtmlRenderer.php  |  4 --
 .../Tests/System/ResponseGeneratorTest.php    | 72 +++++++++++++++++++
 4 files changed, 121 insertions(+), 4 deletions(-)
 create mode 100644 core/lib/Drupal/Core/EventSubscriber/ResponseGeneratorSubscriber.php
 create mode 100644 core/modules/system/src/Tests/System/ResponseGeneratorTest.php

diff --git a/core/core.services.yml b/core/core.services.yml
index 2bc5edc1d4ff..0e5c025bb883 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -958,6 +958,10 @@ services:
     tags:
       - { name: event_subscriber }
     arguments: ['@language_manager', '@config.factory', '@page_cache_request_policy', '@page_cache_response_policy', '@cache_contexts_manager']
+  response_generator_subscriber:
+    class: Drupal\Core\EventSubscriber\ResponseGeneratorSubscriber
+    tags:
+      - { name: event_subscriber }
   redirect_response_subscriber:
     class: Drupal\Core\EventSubscriber\RedirectResponseSubscriber
     arguments: ['@url_generator', '@router.request_context']
diff --git a/core/lib/Drupal/Core/EventSubscriber/ResponseGeneratorSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ResponseGeneratorSubscriber.php
new file mode 100644
index 000000000000..7e653661c0f4
--- /dev/null
+++ b/core/lib/Drupal/Core/EventSubscriber/ResponseGeneratorSubscriber.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventSubscriber\ResponseGeneratorSubscriber.
+ */
+
+namespace Drupal\Core\EventSubscriber;
+
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Response subscriber to add X-Generator header tag.
+ */
+class ResponseGeneratorSubscriber implements EventSubscriberInterface {
+
+  /**
+   * Sets extra X-Generator header on successful responses.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
+   *   The event to process.
+   */
+  public function onRespond(FilterResponseEvent $event) {
+    if (!$event->isMasterRequest()) {
+      return;
+    }
+
+    $response = $event->getResponse();
+
+    // Set the generator in the HTTP header.
+    list($version) = explode('.', \Drupal::VERSION, 2);
+    $response->headers->set('X-Generator', 'Drupal ' . $version . ' (https://www.drupal.org)');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    $events[KernelEvents::RESPONSE][] = ['onRespond'];
+    return $events;
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
index addd13cfa800..c3be3de6298a 100644
--- a/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
+++ b/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php
@@ -136,12 +136,8 @@ public function renderResponse(array $main_content, Request $request, RouteMatch
     }
     $content = $this->renderer->render($html);
 
-    // Set the generator in the HTTP header.
-    list($version) = explode('.', \Drupal::VERSION, 2);
-
     $response = new CacheableResponse($content, 200,[
       'Content-Type' => 'text/html; charset=UTF-8',
-      'X-Generator' => 'Drupal ' . $version . ' (https://www.drupal.org)'
     ]);
 
     // Bubble the cacheability metadata associated with the rendered render
diff --git a/core/modules/system/src/Tests/System/ResponseGeneratorTest.php b/core/modules/system/src/Tests/System/ResponseGeneratorTest.php
new file mode 100644
index 000000000000..061f7f9bfeda
--- /dev/null
+++ b/core/modules/system/src/Tests/System/ResponseGeneratorTest.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\system\Tests\System\ResponseGeneratorTest.
+ */
+
+namespace Drupal\system\Tests\System;
+
+use Drupal\rest\Tests\RESTTestBase;
+
+/**
+ * Tests to see if generator header is added.
+ *
+ * @group system
+ */
+class ResponseGeneratorTest extends RESTTestBase {
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  public static $modules = array('hal', 'rest', 'node');
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->drupalCreateContentType(array('type' => 'page', 'name' => 'Basic page'));
+
+    $permissions = $this->entityPermissions('node', 'view');
+    $permissions[] = 'restful get entity:node';
+    $account = $this->drupalCreateUser($permissions);
+    $this->drupalLogin($account);
+  }
+
+  /**
+   * Test to see if generator header is added.
+   */
+  function testGeneratorHeaderAdded() {
+
+    $node = $this->drupalCreateNode();
+
+    list($version) = explode('.', \Drupal::VERSION, 2);
+    $expectedGeneratorHeader = 'Drupal ' . $version . ' (https://www.drupal.org)';
+
+    // Check to see if the header is added when viewing a normal content page
+    $this->drupalGet($node->urlInfo());
+    $this->assertResponse(200);
+    $this->assertEqual('text/html; charset=UTF-8', $this->drupalGetHeader('Content-Type'));
+    $this->assertEqual($expectedGeneratorHeader, $this->drupalGetHeader('X-Generator'));
+
+    // Check to see if the header is also added for a non-successful response
+    $this->drupalGet('llama');
+    $this->assertResponse(404);
+    $this->assertEqual('text/html; charset=UTF-8', $this->drupalGetHeader('Content-Type'));
+    $this->assertEqual($expectedGeneratorHeader, $this->drupalGetHeader('X-Generator'));
+
+    // Enable rest API for nodes
+    $this->enableService('entity:node', 'GET', 'json');
+
+    // Tests to see if this also works for a non-html request
+    $this->httpRequest($node->urlInfo(), 'GET', NULL, 'application/json');
+    $this->assertResponse(200);
+    $this->assertEqual('application/json', $this->drupalGetHeader('Content-Type'));
+    $this->assertEqual($expectedGeneratorHeader, $this->drupalGetHeader('X-Generator'));
+
+  }
+
+}
-- 
GitLab