← All changes
|
vendor_prefixed/guzzlehttp/psr7/src/ServerRequest.php
+101
-24
27.6
→
trunk
View file →
| @@ -128,26 +128,66 @@ | ||
| 128 | 128 | * $_SERVER |
| 129 | 129 | */ |
| 130 | 130 | public static function fromGlobals() : \YoastSEO_Vendor\Psr\Http\Message\ServerRequestInterface |
| 131 | 131 | { |
| 132 | - $method = $_SERVER['REQUEST_METHOD'] ?? 'GET'; | |
| 133 | - $headers = \getallheaders(); | |
| 132 | + $method = \YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::asciiToUpper(self::getServerParam('REQUEST_METHOD') ?? 'GET'); | |
| 133 | + $headers = self::removeInvalidHostHeader(self::getAllHeaders()); | |
| 134 | 134 | $uri = self::getUriFromGlobals(); |
| 135 | 135 | $body = new \YoastSEO_Vendor\GuzzleHttp\Psr7\CachingStream(new \YoastSEO_Vendor\GuzzleHttp\Psr7\LazyOpenStream('php://input', 'r+')); |
| 136 | - $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? \str_replace('HTTP/', '', $_SERVER['SERVER_PROTOCOL']) : '1.1'; | |
| 136 | + $serverProtocol = self::getServerParam('SERVER_PROTOCOL'); | |
| 137 | + $protocol = $serverProtocol !== null ? \str_replace('HTTP/', '', $serverProtocol) : '1.1'; | |
| 137 | 138 | $serverRequest = new \YoastSEO_Vendor\GuzzleHttp\Psr7\ServerRequest($method, $uri, $headers, $body, $protocol, $_SERVER); |
| 138 | 139 | return $serverRequest->withCookieParams($_COOKIE)->withQueryParams($_GET)->withParsedBody($_POST)->withUploadedFiles(self::normalizeFiles($_FILES)); |
| 139 | 140 | } |
| 141 | + /** | |
| 142 | + * @return array<array-key, string> | |
| 143 | + */ | |
| 144 | + private static function getAllHeaders() : array | |
| 145 | + { | |
| 146 | + return self::normalizeHeaderValues(\getallheaders()); | |
| 147 | + } | |
| 148 | + /** | |
| 149 | + * @param array<array-key, mixed> $headers | |
| 150 | + * | |
| 151 | + * @return array<array-key, string> | |
| 152 | + */ | |
| 153 | + private static function normalizeHeaderValues(array $headers) : array | |
| 154 | + { | |
| 155 | + $normalized = []; | |
| 156 | + foreach ($headers as $name => $value) { | |
| 157 | + if (\is_scalar($value) || \is_object($value) && \method_exists($value, '__toString')) { | |
| 158 | + $normalized[$name] = (string) $value; | |
| 159 | + } | |
| 160 | + } | |
| 161 | + return $normalized; | |
| 162 | + } | |
| 163 | + private static function getServerParam(string $key) : ?string | |
| 164 | + { | |
| 165 | + return isset($_SERVER[$key]) && \is_string($_SERVER[$key]) ? $_SERVER[$key] : null; | |
| 166 | + } | |
| 167 | + /** | |
| 168 | + * @param array<array-key, string> $headers | |
| 169 | + * | |
| 170 | + * @return array<array-key, string> | |
| 171 | + */ | |
| 172 | + private static function removeInvalidHostHeader(array $headers) : array | |
| 173 | + { | |
| 174 | + foreach ($headers as $name => $value) { | |
| 175 | + if (\YoastSEO_Vendor\GuzzleHttp\Psr7\Utils::asciiToLower((string) $name) !== 'host') { | |
| 176 | + continue; | |
| 177 | + } | |
| 178 | + if (\YoastSEO_Vendor\GuzzleHttp\Psr7\Rfc7230::parseHostHeader($value) === null) { | |
| 179 | + unset($headers[$name]); | |
| 180 | + } | |
| 181 | + } | |
| 182 | + return $headers; | |
| 183 | + } | |
| 184 | + /** | |
| 185 | + * @return array{0: string|null, 1: int|null} | |
| 186 | + */ | |
| 140 | 187 | private static function extractHostAndPortFromAuthority(string $authority) : array |
| 141 | 188 | { |
| 142 | - $uri = 'http://' . $authority; | |
| 143 | - $parts = \parse_url($uri); | |
| 144 | - if (\false === $parts) { | |
| 145 | - return [null, null]; | |
| 146 | - } | |
| 147 | - $host = $parts['host'] ?? null; | |
| 148 | - $port = $parts['port'] ?? null; | |
| 149 | - return [$host, $port]; | |
| 189 | + return \YoastSEO_Vendor\GuzzleHttp\Psr7\Rfc7230::parseHostHeader($authority) ?? [null, null]; | |
| 150 | 190 | } |
| 151 | 191 | /** |
| 152 | 192 | * Get a Uri populated with values from $_SERVER. |
| 153 | 193 | */ |
| @@ -153,12 +193,14 @@ | ||
| 153 | 193 | */ |
| 154 | 194 | public static function getUriFromGlobals() : \YoastSEO_Vendor\Psr\Http\Message\UriInterface |
| 155 | 195 | { |
| 156 | 196 | $uri = new \YoastSEO_Vendor\GuzzleHttp\Psr7\Uri(''); |
| 157 | - $uri = $uri->withScheme(!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' ? 'https' : 'http'); | |
| 197 | + $https = self::getServerParam('HTTPS'); | |
| 198 | + $uri = $uri->withScheme(!empty($https) && $https !== 'off' ? 'https' : 'http'); | |
| 158 | 199 | $hasPort = \false; |
| 159 | - if (isset($_SERVER['HTTP_HOST'])) { | |
| 160 | - [$host, $port] = self::extractHostAndPortFromAuthority($_SERVER['HTTP_HOST']); | |
| 200 | + $authority = self::getServerParam('HTTP_HOST'); | |
| 201 | + if ($authority !== null) { | |
| 202 | + [$host, $port] = self::extractHostAndPortFromAuthority($authority); | |
| 161 | 203 | if ($host !== null) { |
| 162 | 204 | $uri = $uri->withHost($host); |
| 163 | 205 | } |
| 164 | 206 | if ($port !== null) { |
| @@ -164,19 +206,21 @@ | ||
| 164 | 206 | if ($port !== null) { |
| 165 | 207 | $hasPort = \true; |
| 166 | 208 | $uri = $uri->withPort($port); |
| 167 | 209 | } |
| 168 | - } elseif (isset($_SERVER['SERVER_NAME'])) { | |
| 169 | - $uri = $uri->withHost($_SERVER['SERVER_NAME']); | |
| 170 | - } elseif (isset($_SERVER['SERVER_ADDR'])) { | |
| 171 | - $uri = $uri->withHost($_SERVER['SERVER_ADDR']); | |
| 210 | + } elseif (($serverName = self::getServerParam('SERVER_NAME')) !== null) { | |
| 211 | + $uri = $uri->withHost($serverName); | |
| 212 | + } elseif (($serverAddr = self::getServerParam('SERVER_ADDR')) !== null) { | |
| 213 | + $uri = $uri->withHost($serverAddr); | |
| 172 | 214 | } |
| 173 | - if (!$hasPort && isset($_SERVER['SERVER_PORT'])) { | |
| 174 | - $uri = $uri->withPort($_SERVER['SERVER_PORT']); | |
| 215 | + $serverPort = self::getServerParam('SERVER_PORT'); | |
| 216 | + if (!$hasPort && $serverPort !== null && \preg_match('/^[+-]?\\d+$/D', $serverPort) === 1) { | |
| 217 | + $uri = $uri->withPort((int) $serverPort); | |
| 175 | 218 | } |
| 176 | 219 | $hasQuery = \false; |
| 177 | - if (isset($_SERVER['REQUEST_URI'])) { | |
| 178 | - $requestUriParts = \explode('?', $_SERVER['REQUEST_URI'], 2); | |
| 220 | + $requestUri = self::getServerParam('REQUEST_URI'); | |
| 221 | + if ($requestUri !== null) { | |
| 222 | + $requestUriParts = \explode('?', $requestUri, 2); | |
| 179 | 223 | $uri = $uri->withPath($requestUriParts[0]); |
| 180 | 224 | if (isset($requestUriParts[1])) { |
| 181 | 225 | $hasQuery = \true; |
| 182 | 226 | $uri = $uri->withQuery($requestUriParts[1]); |
| @@ -181,10 +225,11 @@ | ||
| 181 | 225 | $hasQuery = \true; |
| 182 | 226 | $uri = $uri->withQuery($requestUriParts[1]); |
| 183 | 227 | } |
| 184 | 228 | } |
| 185 | - if (!$hasQuery && isset($_SERVER['QUERY_STRING'])) { | |
| 186 | - $uri = $uri->withQuery($_SERVER['QUERY_STRING']); | |
| 229 | + $queryString = self::getServerParam('QUERY_STRING'); | |
| 230 | + if (!$hasQuery && $queryString !== null) { | |
| 231 | + $uri = $uri->withQuery($queryString); | |
| 187 | 232 | } |
| 188 | 233 | return $uri; |
| 189 | 234 | } |
| 190 | 235 | public function getServerParams() : array |
| @@ -196,8 +241,28 @@ | ||
| 196 | 241 | return $this->uploadedFiles; |
| 197 | 242 | } |
| 198 | 243 | public function withUploadedFiles(array $uploadedFiles) : \YoastSEO_Vendor\Psr\Http\Message\ServerRequestInterface |
| 199 | 244 | { |
| 245 | + $invalidUploadedFileFound = \false; | |
| 246 | + $invalidUploadedFile = null; | |
| 247 | + $stack = [$uploadedFiles]; | |
| 248 | + while ($stack !== []) { | |
| 249 | + foreach (\array_pop($stack) as $uploadedFile) { | |
| 250 | + if ($uploadedFile instanceof \YoastSEO_Vendor\Psr\Http\Message\UploadedFileInterface) { | |
| 251 | + continue; | |
| 252 | + } | |
| 253 | + if (\is_array($uploadedFile)) { | |
| 254 | + $stack[] = $uploadedFile; | |
| 255 | + continue; | |
| 256 | + } | |
| 257 | + $invalidUploadedFileFound = \true; | |
| 258 | + $invalidUploadedFile = $uploadedFile; | |
| 259 | + break 2; | |
| 260 | + } | |
| 261 | + } | |
| 262 | + if ($invalidUploadedFileFound) { | |
| 263 | + \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s inside ServerRequestInterface::withUploadedFiles() is deprecated; guzzlehttp/psr7 3.0 requires an UploadedFileInterface[] tree.', \get_debug_type($invalidUploadedFile)); | |
| 264 | + } | |
| 200 | 265 | $new = clone $this; |
| 201 | 266 | $new->uploadedFiles = $uploadedFiles; |
| 202 | 267 | return $new; |
| 203 | 268 | } |
| @@ -229,8 +294,11 @@ | ||
| 229 | 294 | return $this->parsedBody; |
| 230 | 295 | } |
| 231 | 296 | public function withParsedBody($data) : \YoastSEO_Vendor\Psr\Http\Message\ServerRequestInterface |
| 232 | 297 | { |
| 298 | + if ($data !== null && !\is_array($data) && !\is_object($data)) { | |
| 299 | + \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to ServerRequestInterface::withParsedBody() is deprecated; guzzlehttp/psr7 3.0 requires array|object|null.', \get_debug_type($data)); | |
| 300 | + } | |
| 233 | 301 | $new = clone $this; |
| 234 | 302 | $new->parsedBody = $data; |
| 235 | 303 | return $new; |
| 236 | 304 | } |
| @@ -242,8 +310,11 @@ | ||
| 242 | 310 | * @return mixed |
| 243 | 311 | */ |
| 244 | 312 | public function getAttribute($attribute, $default = null) |
| 245 | 313 | { |
| 314 | + if (!\is_string($attribute)) { | |
| 315 | + \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to ServerRequestInterface::getAttribute() is deprecated; guzzlehttp/psr7 3.0 requires string for $attribute.', \get_debug_type($attribute)); | |
| 316 | + } | |
| 246 | 317 | if (\false === \array_key_exists($attribute, $this->attributes)) { |
| 247 | 318 | return $default; |
| 248 | 319 | } |
| 249 | 320 | return $this->attributes[$attribute]; |
| @@ -249,8 +320,11 @@ | ||
| 249 | 320 | return $this->attributes[$attribute]; |
| 250 | 321 | } |
| 251 | 322 | public function withAttribute($attribute, $value) : \YoastSEO_Vendor\Psr\Http\Message\ServerRequestInterface |
| 252 | 323 | { |
| 324 | + if (!\is_string($attribute)) { | |
| 325 | + \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to ServerRequestInterface::withAttribute() is deprecated; guzzlehttp/psr7 3.0 requires string for $attribute.', \get_debug_type($attribute)); | |
| 326 | + } | |
| 253 | 327 | $new = clone $this; |
| 254 | 328 | $new->attributes[$attribute] = $value; |
| 255 | 329 | return $new; |
| 256 | 330 | } |
| @@ -255,8 +329,11 @@ | ||
| 255 | 329 | return $new; |
| 256 | 330 | } |
| 257 | 331 | public function withoutAttribute($attribute) : \YoastSEO_Vendor\Psr\Http\Message\ServerRequestInterface |
| 258 | 332 | { |
| 333 | + if (!\is_string($attribute)) { | |
| 334 | + \YoastSEO_Vendor\trigger_deprecation('guzzlehttp/psr7', '2.11', 'Passing %s to ServerRequestInterface::withoutAttribute() is deprecated; guzzlehttp/psr7 3.0 requires string for $attribute.', \get_debug_type($attribute)); | |
| 335 | + } | |
| 259 | 336 | if (\false === \array_key_exists($attribute, $this->attributes)) { |
| 260 | 337 | return $this; |
| 261 | 338 | } |
| 262 | 339 | $new = clone $this; |