Update composer dependencies
authorTim Düsterhus <duesterhus@woltlab.com>
Wed, 29 Jun 2022 14:17:09 +0000 (16:17 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Wed, 29 Jun 2022 14:17:09 +0000 (16:17 +0200)
This fixes a Diactoros regression in e707bb4c8f19bd627f06738e64e5c823f88dc4f7.

wcfsetup/install/files/lib/system/api/composer.lock
wcfsetup/install/files/lib/system/api/composer/installed.json
wcfsetup/install/files/lib/system/api/composer/installed.php
wcfsetup/install/files/lib/system/api/laminas/laminas-diactoros/psalm-baseline.xml
wcfsetup/install/files/lib/system/api/laminas/laminas-diactoros/src/ServerRequestFactory.php
wcfsetup/install/files/lib/system/api/laminas/laminas-diactoros/src/ServerRequestFilter/FilterUsingXForwardedHeaders.php

index 8273a2fab056be129fb16073770b7ce469b7b57e..fcf5bc79958aed3f5578e8be528ab6ce38bdfb75 100644 (file)
         },
         {
             "name": "laminas/laminas-diactoros",
-            "version": "2.11.1",
+            "version": "2.11.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laminas/laminas-diactoros.git",
-                "reference": "25b11d422c2e5dad868f68619888763b30f91e2d"
+                "reference": "78846cbce0550ec174508a646f46fd6dee76099b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/25b11d422c2e5dad868f68619888763b30f91e2d",
-                "reference": "25b11d422c2e5dad868f68619888763b30f91e2d",
+                "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/78846cbce0550ec174508a646f46fd6dee76099b",
+                "reference": "78846cbce0550ec174508a646f46fd6dee76099b",
                 "shasum": ""
             },
             "require": {
                     "type": "community_bridge"
                 }
             ],
-            "time": "2022-06-28T21:07:29+00:00"
+            "time": "2022-06-29T14:15:02+00:00"
         },
         {
             "name": "laminas/laminas-httphandlerrunner",
index bd2d62d2ea666190cb7ff6822782d6c03ba8fc6b..a03c5de7779d312383d2b67299c913d28185d646 100644 (file)
         },
         {
             "name": "laminas/laminas-diactoros",
-            "version": "2.11.1",
-            "version_normalized": "2.11.1.0",
+            "version": "2.11.2",
+            "version_normalized": "2.11.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/laminas/laminas-diactoros.git",
-                "reference": "25b11d422c2e5dad868f68619888763b30f91e2d"
+                "reference": "78846cbce0550ec174508a646f46fd6dee76099b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/25b11d422c2e5dad868f68619888763b30f91e2d",
-                "reference": "25b11d422c2e5dad868f68619888763b30f91e2d",
+                "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/78846cbce0550ec174508a646f46fd6dee76099b",
+                "reference": "78846cbce0550ec174508a646f46fd6dee76099b",
                 "shasum": ""
             },
             "require": {
                 "psalm/plugin-phpunit": "^0.14.0",
                 "vimeo/psalm": "^4.3"
             },
-            "time": "2022-06-28T21:07:29+00:00",
+            "time": "2022-06-29T14:15:02+00:00",
             "type": "library",
             "extra": {
                 "laminas": {
index 94088a9b6ffe7740a5f1287fe3b349e3eb3d2c44..b02b1598affedb21b57a36156ca8d1e7dac8d424 100644 (file)
@@ -74,9 +74,9 @@
             'dev_requirement' => false,
         ),
         'laminas/laminas-diactoros' => array(
-            'pretty_version' => '2.11.1',
-            'version' => '2.11.1.0',
-            'reference' => '25b11d422c2e5dad868f68619888763b30f91e2d',
+            'pretty_version' => '2.11.2',
+            'version' => '2.11.2.0',
+            'reference' => '78846cbce0550ec174508a646f46fd6dee76099b',
             'type' => 'library',
             'install_path' => __DIR__ . '/../laminas/laminas-diactoros',
             'aliases' => array(),
index 21ba727135d0a7b3c88ee1f1444a0924a8474254..1456fb1248550841d090c998287d50241720dd51 100644 (file)
   </file>
   <file src="src/ServerRequestFactory.php">
     <LessSpecificReturnStatement occurrences="1"/>
-    <MixedArgument occurrences="1">
+    <MixedArgument occurrences="2">
       <code>$headers['cookie']</code>
+      <code>$host</code>
     </MixedArgument>
+    <MixedArgumentTypeCoercion occurrences="1">
+      <code>$headers</code>
+    </MixedArgumentTypeCoercion>
     <MixedAssignment occurrences="3">
       <code>$iisUrlRewritten</code>
       <code>$requestUri</code>
     <MixedReturnStatement occurrences="1">
       <code>$defaults</code>
     </MixedReturnStatement>
+    <MixedReturnTypeCoercion occurrences="1">
+      <code>self::marshalHostAndPortFromHeader($host)</code>
+    </MixedReturnTypeCoercion>
     <MoreSpecificReturnType occurrences="1">
       <code>ServerRequest</code>
     </MoreSpecificReturnType>
index 8b9d5fda119365511481b613176e123103ca8fcf..30eb71cbe0ef597b827d8beda2154bae2561fade 100644 (file)
@@ -75,7 +75,7 @@ class ServerRequestFactory implements ServerRequestFactoryInterface
         return $requestFilter(new ServerRequest(
             $server,
             $files,
-            self::marshalUriFromSapi($server),
+            self::marshalUriFromSapi($server, $headers),
             marshalMethodFromSapi($server),
             'php://input',
             $headers,
@@ -105,9 +105,10 @@ class ServerRequestFactory implements ServerRequestFactoryInterface
     /**
      * Marshal a Uri instance based on the values present in the $_SERVER array and headers.
      *
+     * @param array<string, string|list<string>> $headers
      * @param array $server SAPI parameters
      */
-    private static function marshalUriFromSapi(array $server) : Uri
+    private static function marshalUriFromSapi(array $server, array $headers) : Uri
     {
         $uri = new Uri('');
 
@@ -122,7 +123,7 @@ class ServerRequestFactory implements ServerRequestFactoryInterface
         $uri = $uri->withScheme($https ? 'https' : 'http');
 
         // Set the host
-        [$host, $port] = self::marshalHostAndPort($server);
+        [$host, $port] = self::marshalHostAndPort($server, $headers);
         if (! empty($host)) {
             $uri = $uri->withHost($host);
             if (! empty($port)) {
@@ -157,13 +158,19 @@ class ServerRequestFactory implements ServerRequestFactoryInterface
     /**
      * Marshal the host and port from the PHP environment.
      *
+     * @param array<string, string|list<string>> $headers
      * @return array{string, int|null} Array of two items, host and port,
      *     in that order (can be passed to a list() operation).
      */
-    private static function marshalHostAndPort(array $server) : array
+    private static function marshalHostAndPort(array $server, array $headers) : array
     {
         static $defaults = ['', null];
 
+        $host = self::getHeaderFromArray('host', $headers, false);
+        if ($host !== false) {
+            return self::marshalHostAndPortFromHeader($host);
+        }
+
         if (! isset($server['SERVER_NAME'])) {
             return $defaults;
         }
@@ -256,4 +263,48 @@ class ServerRequestFactory implements ServerRequestFactoryInterface
 
         return 'on' === strtolower($https);
     }
+
+    /**
+     * @param string|list<string> $host
+     * @return array Array of two items, host and port, in that order (can be
+     *     passed to a list() operation).
+     */
+    private static function marshalHostAndPortFromHeader($host): array
+    {
+        if (is_array($host)) {
+            $host = implode(', ', $host);
+        }
+
+        $port = null;
+
+        // works for regname, IPv4 & IPv6
+        if (preg_match('|\:(\d+)$|', $host, $matches)) {
+            $host = substr($host, 0, -1 * (strlen($matches[1]) + 1));
+            $port = (int) $matches[1];
+        }
+
+        return [$host, $port];
+    }
+
+    /**
+     * Retrieve a header value from an array of headers using a case-insensitive lookup.
+     *
+     * @param array<string, string|list<string>> $headers Key/value header pairs
+     * @param mixed $default Default value to return if header not found
+     * @return mixed
+     */
+    private static function getHeaderFromArray(string $name, array $headers, $default = null)
+    {
+        $header  = strtolower($name);
+        $headers = array_change_key_case($headers, CASE_LOWER);
+        if (! array_key_exists($header, $headers)) {
+            return $default;
+        }
+
+        if (is_string($headers[$header])) {
+            return $headers[$header];
+        }
+
+        return implode(', ', $headers[$header]);
+    }
 }
index fcac3753ea0e01b3368f0212ff31cd79e259d242..00b9707b454b4bfe4008c05db14f4c6d30a5a008 100644 (file)
@@ -83,7 +83,8 @@ final class FilterUsingXForwardedHeaders implements FilterServerRequestInterface
                     $uri = $uri->withPort((int) $header);
                     break;
                 case self::HEADER_PROTO:
-                    $uri = $uri->withScheme($header);
+                    $scheme = strtolower($header) === 'https' ? 'https' : 'http';
+                    $uri = $uri->withScheme($scheme);
                     break;
             }
         }