diff --git a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php index 0422bf0..c393a34 100644 --- a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php @@ -63,7 +63,7 @@ protected static function getPriority() { */ public function on403(GetResponseForExceptionEvent $event) { $path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.403')); - $this->makeSubrequest($event, $event->getRequest()->getBasePath() . '/' . $path, Response::HTTP_FORBIDDEN); + $this->makeSubrequest($event, $path, Response::HTTP_FORBIDDEN); } /** @@ -71,7 +71,7 @@ public function on403(GetResponseForExceptionEvent $event) { */ public function on404(GetResponseForExceptionEvent $event) { $path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.404')); - $this->makeSubrequest($event, $event->getRequest()->getBasePath() . '/' . $path, Response::HTTP_NOT_FOUND); + $this->makeSubrequest($event, $path, Response::HTTP_NOT_FOUND); } } diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php index d6782b2..7d71d8c 100644 --- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php @@ -89,21 +89,25 @@ public function on404(GetResponseForExceptionEvent $event) { * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event * The event to process * @param string $url - * The url to which to make a subrequest for this error message. + * The path/url to which to make a subrequest for this error message. * @param int $status_code * The status code for the error being handled. */ protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code) { $request = $event->getRequest(); + if (!($url && $url[0] == '/')) { + $url = $request->getBasePath() . '/' . $url; + } + $current_url = $request->getBasePath() . $request->getPathInfo(); if ($url != $request->getBasePath() . '/' && $url != $current_url) { if ($request->getMethod() === 'POST') { - $sub_request = Request::create($url, 'POST', drupal_get_destination() + ['_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all()); + $sub_request = Request::create($url, 'POST', $this->drupalGetDestination() + ['_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all()); } else { - $sub_request = Request::create($url, 'GET', $request->query->all() + drupal_get_destination() + ['_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all()); + $sub_request = Request::create($url, 'GET', $request->query->all() + $this->drupalGetDestination() + ['_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all()); } try { @@ -124,4 +128,11 @@ protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $st } } + /** + * Wraps drupal_get_destination(). + */ + protected function drupalGetDestination() { + return drupal_get_destination(); + } + } diff --git a/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php b/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php index e4bc705..7a0023f 100644 --- a/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php +++ b/core/lib/Drupal/Core/RouteProcessor/RouteProcessorCurrent.php @@ -36,12 +36,18 @@ public function __construct(RouteMatchInterface $route_match) { * {@inheritdoc} */ public function processOutbound($route_name, Route $route, array &$parameters) { - if (($route_name === '') && ($current_route = $this->routeMatch->getRouteObject())) { - $route->setPath($current_route->getPath()); - $route->setRequirements($current_route->getRequirements()); - $route->setOptions($current_route->getOptions()); - $route->setDefaults($current_route->getDefaults()); - $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); + if ($route_name === '') { + if ($current_route = $this->routeMatch->getRouteObject()) { + $route->setPath($current_route->getPath()); + $route->setRequirements($current_route->getRequirements()); + $route->setOptions($current_route->getOptions()); + $route->setDefaults($current_route->getDefaults()); + $parameters = array_merge($parameters, $this->routeMatch->getRawParameters()->all()); + } + else { + // If we have no current route match available, point to the frontpage. + $route->setPath(''); + } } } diff --git a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php index d21d834..bb66f59 100644 --- a/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php +++ b/core/modules/system/src/Tests/RouteProcessor/RouteProcessorCurrentIntegrationTest.php @@ -96,6 +96,19 @@ public function testProcessOutbound() { $request_stack->push($request); $request_context->fromRequest($request); $this->assertEqual('/node/add', \Drupal::url('')); + + // Test request without a found route. This happens for example on an + // not found exception page. + $server = [ + 'SCRIPT_NAME' => '/index.php', + 'SCRIPT_FILENAME' => \Drupal::root() . '/index.php', + 'SERVER_NAME' => 'http://www.example.com', + ]; + $request = Request::create('/invalid-path', 'GET', [], [], [], $server); + + $request_stack->push($request); + $request_context->fromRequest($request); + $this->assertEqual('/', \Drupal::url('')); } } diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php index 1de4249..5b73c85 100644 --- a/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php +++ b/core/tests/Drupal/Tests/Core/EventSubscriber/CustomPageExceptionHtmlSubscriberTest.php @@ -60,7 +60,7 @@ class CustomPageExceptionHtmlSubscriberTest extends UnitTestCase { /** * The tested custom page exception subscriber. * - * @var \Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber + * @var \Drupal\Core\EventSubscriber\CustomPageExceptionHtmlSubscriber|\Drupal\Tests\Core\EventSubscriber\TestCustomPageExceptionHtmlSubscriber */ protected $customPageSubscriber; @@ -73,7 +73,7 @@ protected function setUp() { $this->aliasManager = $this->getMock('Drupal\Core\Path\AliasManagerInterface'); $this->kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface'); $this->logger = $this->getMock('Psr\Log\LoggerInterface'); - $this->customPageSubscriber = new CustomPageExceptionHtmlSubscriber($this->configFactory, $this->aliasManager, $this->kernel, $this->logger); + $this->customPageSubscriber = new TestCustomPageExceptionHtmlSubscriber($this->configFactory, $this->aliasManager, $this->kernel, $this->logger); // You can't create an exception in PHP without throwing it. Store the // current error_log, and disable it temporarily. @@ -124,7 +124,6 @@ public function testHandleWithGetRequest() { $this->setupStubAliasManager(); $request = Request::create('/test', 'GET', array('name' => 'druplicon', 'pass' => '12345')); - $request->attributes->set('_system_path', 'test'); $this->kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) { return new Response($request->getMethod() . ' ' . UrlHelper::buildQuery($request->query->all())); @@ -139,3 +138,14 @@ public function testHandleWithGetRequest() { } } + +class TestCustomPageExceptionHtmlSubscriber extends CustomPageExceptionHtmlSubscriber { + + /** + * {@inheritdoc} + */ + protected function drupalGetDestination() { + return ['destination' => 'test']; + } + +}