Browse Source

Set request context for the router before running middleware queue.

This allows the Router to properly generate at least URLs for static
assets incase an exception occurs before the RoutingMiddleware is run.
ADmad 3 years ago
parent
commit
26bad8fda7
2 changed files with 27 additions and 0 deletions
  1. 9 0
      src/Http/Runner.php
  2. 18 0
      tests/TestCase/Http/RunnerTest.php

+ 9 - 0
src/Http/Runner.php

@@ -16,6 +16,8 @@ declare(strict_types=1);
  */
 namespace Cake\Http;
 
+use Cake\Routing\Router;
+use Cake\Routing\RoutingApplicationInterface;
 use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\RequestHandlerInterface;
@@ -55,6 +57,13 @@ class Runner implements RequestHandlerInterface
         $this->queue->rewind();
         $this->fallbackHandler = $fallbackHandler;
 
+        if (
+            $fallbackHandler instanceof RoutingApplicationInterface &&
+            $request instanceof ServerRequest
+        ) {
+            Router::setRequest($request);
+        }
+
         return $this->handle($request);
     }
 

+ 18 - 0
tests/TestCase/Http/RunnerTest.php

@@ -19,9 +19,13 @@ namespace Cake\Test\TestCase\Http;
 use Cake\Http\MiddlewareQueue;
 use Cake\Http\Response;
 use Cake\Http\Runner;
+use Cake\Http\ServerRequest;
+use Cake\Routing\Router;
 use Cake\TestSuite\TestCase;
 use Psr\Http\Message\ResponseInterface;
 use RuntimeException;
+use TestApp\Application;
+use Throwable;
 
 /**
  * Test case for runner.
@@ -126,4 +130,18 @@ class RunnerTest extends TestCase
         $runner = new Runner();
         $runner->run($this->queue, $req);
     }
+
+    public function testRunSetRouterContext(): void
+    {
+        $runner = new Runner();
+        $request = new ServerRequest();
+        $app = new Application(CONFIG);
+
+        try {
+            $runner->run($this->queue, $request, $app);
+        } catch (Throwable $e) {
+        }
+
+        $this->assertSame($request, Router::getRequest());
+    }
 }