Issue #2653318 by Wim Leers, aneek, marthinal, dawehner: While in maintenance mode, REST routes respond with HTML instead of XML/JSON/…

8.2.x
Alex Pott 2016-06-16 18:10:50 +01:00
parent 58256f9ce3
commit 4b6d125f1c
3 changed files with 58 additions and 7 deletions

View File

@ -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.
*/

View File

@ -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.
*

View File

@ -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('<front>', ['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');
}
}
}