Browse Source

Merge pull request #16855 from cakephp/request-uri-scheme

Sync Uri::getScheme() with ServerRequest::scheme().
ADmad 3 years ago
parent
commit
a5f9900b1b

+ 1 - 1
composer.json

@@ -115,7 +115,7 @@
         ],
         "stan-tests": "phpstan.phar analyze -c tests/phpstan.neon",
         "stan-baseline": "phpstan.phar --generate-baseline",
-        "stan-setup": "cp composer.json composer.backup && composer require --dev symfony/polyfill-php81 phpstan/phpstan:~1.9.0 psalm/phar:~4.29.0 && mv composer.backup composer.json",
+        "stan-setup": "cp composer.json composer.backup && composer require --dev symfony/polyfill-php81 phpstan/phpstan:~1.9.0 psalm/phar:~4.30.0 && mv composer.backup composer.json",
         "lowest": "validate-prefer-lowest",
         "lowest-setup": "composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction && cp composer.json composer.backup && composer require --dev dereuromark/composer-prefer-lowest && mv composer.backup composer.json",
         "test": "phpunit",

+ 24 - 21
psalm-baseline.xml

@@ -1,9 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <files psalm-version="4.x-dev@">
   <file src="src/Cache/Engine/RedisEngine.php">
-    <InvalidArgument occurrences="2">
-      <code>Redis::OPT_SCAN</code>
-    </InvalidArgument>
     <InvalidReturnStatement occurrences="4">
       <code>$this-&gt;_Redis-&gt;set($key, $value)</code>
       <code>$this-&gt;_Redis-&gt;setEx($key, $duration, $value)</code>
@@ -138,9 +135,7 @@
     </DeprecatedClass>
   </file>
   <file src="src/Controller/Component/RequestHandlerComponent.php">
-    <DeprecatedMethod occurrences="2">
-      <code>prefers</code>
-      <code>prefers</code>
+    <DeprecatedMethod occurrences="1">
       <code>prefers</code>
     </DeprecatedMethod>
   </file>
@@ -225,14 +220,11 @@
     </DeprecatedProperty>
   </file>
   <file src="src/Error/BaseErrorHandler.php">
-    <DeprecatedMethod occurrences="1">
-      <code>log</code>
-    </DeprecatedMethod>
     <DeprecatedMethod occurrences="2">
+      <code>log</code>
       <code>logMessage</code>
     </DeprecatedMethod>
   </file>
-
   <file src="src/Error/ErrorHandler.php">
     <DeprecatedClass occurrences="1">
       <code>ExceptionRenderer::class</code>
@@ -244,11 +236,13 @@
   <file src="src/Error/ErrorTrap.php">
     <DeprecatedMethod occurrences="2">
       <code>logMessage</code>
+      <code>logMessage</code>
     </DeprecatedMethod>
   </file>
   <file src="src/Error/ExceptionTrap.php">
     <DeprecatedClass occurrences="2">
-      <code>\Cake\Error\ExceptionRenderer</code>
+      <code>ExceptionRenderer::class</code>
+      <code>ExceptionRenderer::class</code>
     </DeprecatedClass>
     <DeprecatedMethod occurrences="1">
       <code>log</code>
@@ -265,15 +259,23 @@
       <code>new DoublePassDecoratorMiddleware($middleware)</code>
     </DeprecatedClass>
   </file>
+  <file src="src/Http/Response.php">
+    <DeprecatedMethod occurrences="1">
+      <code>notModified</code>
+    </DeprecatedMethod>
+  </file>
   <file src="src/Http/ServerRequest.php">
     <ArgumentTypeCoercion occurrences="1">
       <code>$this-&gt;data</code>
     </ArgumentTypeCoercion>
+    <PossiblyNullArgument occurrences="1">
+      <code>$this-&gt;scheme()</code>
+    </PossiblyNullArgument>
   </file>
-  <file src="src/Http/Response.php">
-    <DeprecatedMethod occurrences="1">
-      <code>notModified</code>
-    </DeprecatedMethod>
+  <file src="src/Http/ServerRequestFactory.php">
+    <PossiblyNullArgument occurrences="1">
+      <code>$request-&gt;scheme()</code>
+    </PossiblyNullArgument>
   </file>
   <file src="src/I18n/DateFormatTrait.php">
     <DeprecatedClass occurrences="5">
@@ -345,6 +347,11 @@
       <code>$instances</code>
     </NonInvariantDocblockPropertyType>
   </file>
+  <file src="src/ORM/Query.php">
+    <ArgumentTypeCoercion occurrences="1">
+      <code>$this-&gt;_repository</code>
+    </ArgumentTypeCoercion>
+  </file>
   <file src="src/ORM/Table.php">
     <DeprecatedClass occurrences="6">
       <code>SaveOptionsBuilder</code>
@@ -355,11 +362,6 @@
       <code>new SaveOptionsBuilder($this, $options)</code>
     </DeprecatedClass>
   </file>
-  <file src="src/ORM/Query.php">
-    <ArgumentTypeCoercion occurrences="1">
-      <code>$this-&gt;_repository</code>
-    </ArgumentTypeCoercion>
-  </file>
   <file src="src/Routing/Middleware/RoutingMiddleware.php">
     <ArgumentTypeCoercion occurrences="2">
       <code>$request</code>
@@ -479,7 +481,8 @@
     </DeprecatedMethod>
   </file>
   <file src="src/View/SerializedView.php">
-    <DeprecatedProperty occurrences="3">
+    <DeprecatedProperty occurrences="2">
+      <code>$this-&gt;_responseType</code>
       <code>$this-&gt;_responseType</code>
     </DeprecatedProperty>
   </file>

+ 1 - 0
src/Http/ServerRequest.php

@@ -409,6 +409,7 @@ class ServerRequest implements ServerRequestInterface
     {
         $this->trustedProxies = $proxies;
         $this->trustProxy = true;
+        $this->uri = $this->uri->withScheme($this->scheme());
     }
 
     /**

+ 9 - 7
src/Http/ServerRequestFactory.php

@@ -30,9 +30,9 @@ use function Laminas\Diactoros\normalizeUploadedFiles;
 /**
  * Factory for making ServerRequest instances.
  *
- * This subclass adds in CakePHP specific behavior to populate
- * the basePath and webroot attributes. Furthermore the Uri's path
- * is corrected to only contain the 'virtual' path for the request.
+ * This adds in CakePHP specific behavior to populate the basePath and webroot
+ * attributes. Furthermore the Uri's path is corrected to only contain the
+ * 'virtual' path for the request.
  */
 abstract class ServerRequestFactory implements ServerRequestFactoryInterface
 {
@@ -42,10 +42,6 @@ abstract class ServerRequestFactory implements ServerRequestFactoryInterface
      * If any argument is not supplied, the corresponding superglobal value will
      * be used.
      *
-     * The ServerRequest created is then passed to the fromServer() method in
-     * order to marshal the request URI and headers.
-     *
-     * @see fromServer()
      * @param array|null $server $_SERVER superglobal
      * @param array|null $query $_GET superglobal
      * @param array|null $parsedBody $_POST superglobal
@@ -94,6 +90,12 @@ abstract class ServerRequestFactory implements ServerRequestFactoryInterface
         ]);
 
         $request = static::marshalBodyAndRequestMethod($parsedBody ?? $_POST, $request);
+        // This is required as `ServerRequest::scheme()` ignores the value of
+        // `HTTP_X_FORWARDED_PROTO` unless `trustProxy` is enabled, while the
+        // `Uri` instance intially created always takes values of `HTTP_X_FORWARDED_PROTO`
+        // into account.
+        $uri = $request->getUri()->withScheme($request->scheme());
+        $request = $request->withUri($uri, true);
 
         return static::marshalFiles($files ?? $_FILES, $request);
     }

+ 20 - 0
tests/TestCase/Http/ServerRequestFactoryTest.php

@@ -64,6 +64,25 @@ class ServerRequestFactoryTest extends TestCase
         $this->assertSame($files['image']['type'], $expected->getClientMediaType());
     }
 
+    public function testFromGlobalsUriScheme(): void
+    {
+        $server = [
+            'DOCUMENT_ROOT' => '/cake/repo/webroot',
+            'PHP_SELF' => '/index.php',
+            'REQUEST_URI' => '/posts/add',
+            'HTTP_X_FORWARDED_PROTO' => 'https',
+        ];
+        $request = ServerRequestFactory::fromGlobals($server);
+
+        $this->assertSame('http', $request->scheme());
+        $this->assertSame('http', $request->getUri()->getScheme());
+
+        $request->setTrustedProxies([]);
+        // Yeah even setting an empty list of proxies does the trick.
+        $this->assertSame('https', $request->scheme());
+        $this->assertSame('https', $request->getUri()->getScheme());
+    }
+
     /**
      * Test fromGlobals includes the session
      *
@@ -989,6 +1008,7 @@ class ServerRequestFactoryTest extends TestCase
             'CONTENT_TYPE' => null,
             'HTTP_CONTENT_TYPE' => null,
             'ORIGINAL_REQUEST_METHOD' => 'PUT',
+            'HTTP_HOST' => 'localhost',
         ];
         $this->assertSame($expected, $request->getServerParams());
     }