From 4b6d125f1cd25472eeadb0fb97e8b5870e62c203 Mon Sep 17 00:00:00 2001 From: Alex Pott Date: Thu, 16 Jun 2016 18:10:50 +0100 Subject: [PATCH] =?UTF-8?q?Issue=20#2653318=20by=20Wim=20Leers,=20aneek,?= =?UTF-8?q?=20marthinal,=20dawehner:=20While=20in=20maintenance=20mode,=20?= =?UTF-8?q?REST=20routes=20respond=20with=20HTML=20instead=20of=20XML/JSON?= =?UTF-8?q?/=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MaintenanceModeSubscriber.php | 31 +++++++++++++++---- .../src/Tests/Views/StyleSerializerTest.php | 16 ++++++++++ .../src/Tests/System/SiteMaintenanceTest.php | 18 ++++++++++- 3 files changed, 58 insertions(+), 7 deletions(-) diff --git a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php index 873996b0237..57d43ec0be1 100644 --- a/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/MaintenanceModeSubscriber.php @@ -3,7 +3,6 @@ namespace Drupal\Core\EventSubscriber; use Drupal\Component\Utility\SafeMarkup; -use Drupal\Component\Utility\Xss; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Render\BareHtmlPageRendererInterface; use Drupal\Core\Routing\RouteMatch; @@ -13,6 +12,7 @@ use Drupal\Core\Site\MaintenanceModeInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\KernelEvents; @@ -90,18 +90,25 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface { * The event to process. */ public function onKernelRequestMaintenance(GetResponseEvent $event) { - $route_match = RouteMatch::createFromRequest($event->getRequest()); + $request = $event->getRequest(); + $route_match = RouteMatch::createFromRequest($request); if ($this->maintenanceMode->applies($route_match)) { // Don't cache maintenance mode pages. \Drupal::service('page_cache_kill_switch')->trigger(); + if (!$this->maintenanceMode->exempt($this->account)) { // Deliver the 503 page if the site is in maintenance mode and the // logged in user is not allowed to bypass it. + + // If the request format is not 'html' then show default maintenance + // mode page else show a text/plain page with maintenance message. + if ($request->getRequestFormat() !== 'html') { + $response = new Response($this->getSiteMaintenanceMessage(), 503, array('Content-Type' => 'text/plain')); + $event->setResponse($response); + return; + } drupal_maintenance_theme(); - $content = Xss::filterAdmin(SafeMarkup::format($this->config->get('system.maintenance')->get('message'), array( - '@site' => $this->config->get('system.site')->get('name'), - ))); - $response = $this->bareHtmlPageRenderer->renderBarePage(['#markup' => $content], $this->t('Site under maintenance'), 'maintenance_page'); + $response = $this->bareHtmlPageRenderer->renderBarePage(['#markup' => $this->getSiteMaintenanceMessage()], $this->t('Site under maintenance'), 'maintenance_page'); $response->setStatusCode(503); $event->setResponse($response); } @@ -121,6 +128,18 @@ class MaintenanceModeSubscriber implements EventSubscriberInterface { } } + /** + * Gets the site maintenance message. + * + * @return \Drupal\Component\Render\MarkupInterface + * The formatted site maintenance message. + */ + protected function getSiteMaintenanceMessage() { + return SafeMarkup::format($this->config->get('system.maintenance')->get('message'), array( + '@site' => $this->config->get('system.site')->get('name'), + )); + } + /** * Wraps the drupal_set_message function. */ diff --git a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php index bc6f0539dfd..23508998c7f 100644 --- a/core/modules/rest/src/Tests/Views/StyleSerializerTest.php +++ b/core/modules/rest/src/Tests/Views/StyleSerializerTest.php @@ -183,6 +183,22 @@ class StyleSerializerTest extends PluginTestBase { $this->assertIdentical($actual_xml, $expected, 'The expected XML output was found.'); } + /** + * Verifies site maintenance mode functionality. + */ + protected function testSiteMaintenance() { + $view = Views::getView('test_serializer_display_field'); + $view->initDisplay(); + $this->executeView($view); + + // Set the site to maintenance mode. + $this->container->get('state')->set('system.maintenance_mode', TRUE); + + $this->drupalGetWithFormat('test/serialize/entity', 'json'); + // Verify that the endpoint is unavailable for anonymous users. + $this->assertResponse(503); + } + /** * Sets up a request on the request stack with a specified format. * diff --git a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php index 6a86083b3ab..49aff66e4d6 100644 --- a/core/modules/system/src/Tests/System/SiteMaintenanceTest.php +++ b/core/modules/system/src/Tests/System/SiteMaintenanceTest.php @@ -36,7 +36,7 @@ class SiteMaintenanceTest extends WebTestBase { } /** - * Verify site maintenance mode functionality. + * Verifies site maintenance mode functionality. */ protected function testSiteMaintenance() { $this->drupalGet(Url::fromRoute('user.page')); @@ -131,4 +131,20 @@ class SiteMaintenanceTest extends WebTestBase { $this->assertEqual('Site under maintenance', $this->cssSelect('main h1')[0]); } + /** + * Tests responses to non-HTML requests when in maintenance mode. + */ + public function testNonHtmlRequest() { + $this->drupalLogout(); + \Drupal::state()->set('system.maintenance_mode', TRUE); + $formats = ['json', 'xml', 'non-existing']; + foreach ($formats as $format) { + $this->pass('Testing format ' . $format); + $this->drupalGet('', ['query' => ['_format' => $format]]); + $this->assertResponse(503); + $this->assertRaw('Drupal is currently under maintenance. We should be back shortly. Thank you for your patience.'); + $this->assertHeader('Content-Type', 'text/plain; charset=UTF-8'); + } + } + }