Issue #2835626 by 20th, vijaycs85, himanshu-dixit, naveenvalecha, Jo Fitzgerald, Wim Leers, xjm, dawehner, catch, alexpott: Rename & document Drupal\Core\EventSubscriber\AcceptNegotiation406 KernelEvents::VIEW event subscriber

8.4.x
Nathaniel Catchpole 2017-04-28 14:57:02 -04:00
parent 45e8efc948
commit 823aae4cb0
7 changed files with 110 additions and 12 deletions

View File

@ -1044,8 +1044,8 @@ services:
arguments: ['@class_resolver', '@current_route_match', '%main_content_renderers%']
tags:
- { name: event_subscriber }
accept_negotiation_406:
class: Drupal\Core\EventSubscriber\AcceptNegotiation406
renderer_non_html:
class: Drupal\Core\EventSubscriber\RenderArrayNonHtmlSubscriber
tags:
- { name: event_subscriber }
main_content_renderer.html:

View File

@ -8,25 +8,23 @@ use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* View subscriber rendering a 406 if we could not route or render a request.
*
* @todo fix or replace this in https://www.drupal.org/node/2364011
* Throws 406 if requesting non-HTML format and controller returns render array.
*/
class AcceptNegotiation406 implements EventSubscriberInterface {
class RenderArrayNonHtmlSubscriber implements EventSubscriberInterface {
/**
* Throws an HTTP 406 error if we get this far, which we normally shouldn't.
* Throws an HTTP 406 error if client requested a non-HTML format.
*
* @param \Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent $event
* The event to process.
*/
public function onViewDetect406(GetResponseForControllerResultEvent $event) {
public function onRespond(GetResponseForControllerResultEvent $event) {
$request = $event->getRequest();
$result = $event->getControllerResult();
// If this is a render array then we assume that the router went with the
// generic controller and not one with a format. If the format requested is
// not HTML though we can also assume that the requested format is invalid
// not HTML though, we can also assume that the requested format is invalid
// so we provide a 406 response.
if (is_array($result) && $request->getRequestFormat() !== 'html') {
throw new NotAcceptableHttpException('Not acceptable format: ' . $request->getRequestFormat());
@ -37,8 +35,7 @@ class AcceptNegotiation406 implements EventSubscriberInterface {
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
$events[KernelEvents::VIEW][] = ['onViewDetect406', -10];
$events[KernelEvents::VIEW][] = ['onRespond', -10];
return $events;
}

View File

@ -82,7 +82,7 @@ class DynamicPageCacheSubscriber implements EventSubscriberInterface {
// may be returning a domain object that a KernelEvents::VIEW subscriber
// must turn into an actual response, but perhaps a format is being
// requested that the subscriber does not support.
// @see \Drupal\Core\EventSubscriber\AcceptNegotiation406::onViewDetect406()
// @see \Drupal\Core\EventSubscriber\RenderArrayNonHtmlSubscriber::onResponse()
'request_format',
],
'bin' => 'dynamic_page_cache',

View File

@ -0,0 +1,6 @@
name: 'Array rendering for non-HTML requests subscriber test'
type: module
description: 'Support module for RenderArrayNonHtmlSubscriberTest.'
package: Testing
version: VERSION
core: 8.x

View File

@ -0,0 +1,13 @@
render_array_non_html_subscriber_test.raw_string:
path: '/render_array_non_html_subscriber_test/raw_string'
defaults:
_controller: '\Drupal\render_array_non_html_subscriber_test\RenderArrayNonHtmlSubscriberTestController::rawString'
requirements:
_access: 'TRUE'
render_array_non_html_subscriber_test.render_array:
path: '/render_array_non_html_subscriber_test/render_array'
defaults:
_controller: '\Drupal\render_array_non_html_subscriber_test\RenderArrayNonHtmlSubscriberTestController::renderArray'
requirements:
_access: 'TRUE'

View File

@ -0,0 +1,28 @@
<?php
namespace Drupal\render_array_non_html_subscriber_test;
use Drupal\Core\Controller\ControllerBase;
use Symfony\Component\HttpFoundation\Response;
class RenderArrayNonHtmlSubscriberTestController extends ControllerBase {
/**
* @return string
*/
public function rawString() {
return new Response($this->t('Raw controller response.'));
}
/**
* @return array
*/
public function renderArray() {
return [
'#type' => 'html_tag',
'#tag' => 'p',
'#value' => $this->t('Controller response successfully rendered.'),
];
}
}

View File

@ -0,0 +1,54 @@
<?php
namespace Drupal\Tests\system\Functional\Render;
use Drupal\Core\Url;
use Drupal\Tests\BrowserTestBase;
/**
* Functional test verifying that render array throws 406 for non-HTML requests.
*
* @group Render
*/
class RenderArrayNonHtmlSubscriberTest extends BrowserTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['render_array_non_html_subscriber_test'];
/**
* Tests handling of responses by events subscriber.
*/
public function testResponses() {
// Test that event subscriber does not interfere with normal requests.
$url = Url::fromRoute('render_array_non_html_subscriber_test.render_array');
$this->drupalGet($url);
$this->assertSession()->statusCodeEquals(200);
$this->assertRaw(t('Controller response successfully rendered.'));
// Test that correct response code is returned for any non-HTML format.
foreach (['json', 'hal+json', 'xml', 'foo'] as $format) {
$url = Url::fromRoute('render_array_non_html_subscriber_test.render_array', [
'_format' => $format,
]);
$this->drupalGet($url);
$this->assertSession()->statusCodeEquals(406);
$this->assertNoRaw(t('Controller response successfully rendered.'));
}
// Test that event subscriber does not interfere with raw string responses.
$url = Url::fromRoute('render_array_non_html_subscriber_test.raw_string', [
'_format' => 'foo',
]);
$this->drupalGet($url);
$this->assertSession()->statusCodeEquals(200);
$this->assertRaw(t('Raw controller response.'));
}
}