From fa2fe07d61719fab8e645a60d3c65873e4df6ec7 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 19 Jul 2018 13:30:06 -0500 Subject: [PATCH] Ensure checks for HTTPS scheme are case insensitive - Checks for either `HTTPS` or `https` in the `$server` array. - Does a case-insensitive check against the value discovered to see if it is equivalent to "off". - Does a case-insenstivie check against the value of the `X-Forwarded-Proto` header to see if it is equivalent to "https". --- src/functions/marshal_uri_from_sapi.php | 12 ++++-- test/ServerRequestFactoryTest.php | 51 ++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/src/functions/marshal_uri_from_sapi.php b/src/functions/marshal_uri_from_sapi.php index b906a290..98d0a32a 100644 --- a/src/functions/marshal_uri_from_sapi.php +++ b/src/functions/marshal_uri_from_sapi.php @@ -172,9 +172,15 @@ function marshalUriFromSapi(array $server, array $headers) // URI scheme $scheme = 'http'; - $https = array_key_exists('HTTPS', $server) ? $server['HTTPS'] : false; - if (($https && 'off' !== $https) - || $getHeaderFromArray('x-forwarded-proto', $headers, false) === 'https' + if (array_key_exists('HTTPS', $server)) { + $https = $server['HTTPS']; + } elseif (array_key_exists('https', $server)) { + $https = $server['https']; + } else { + $https = false; + } + if (($https && 'off' !== strtolower($https)) + || strtolower($getHeaderFromArray('x-forwarded-proto', $headers, false)) === 'https' ) { $scheme = 'https'; } diff --git a/test/ServerRequestFactoryTest.php b/test/ServerRequestFactoryTest.php index b4fa9c1b..4818c37b 100644 --- a/test/ServerRequestFactoryTest.php +++ b/test/ServerRequestFactoryTest.php @@ -306,14 +306,29 @@ public function testMarshalHostAndPortWillDetectPortInIpv6StyleHost() $this->assertNull($uri->getPort()); } - public function testMarshalUriDetectsHttpsSchemeFromServerValue() + /** + * @return array + */ + public function httpsParamProvider() + { + return [ + 'lowercase' => ['https'], + 'uppercase' => ['HTTPS'], + ]; + } + + /** + * @dataProvider httpsParamProvider + * @param string $param + */ + public function testMarshalUriDetectsHttpsSchemeFromServerValue($param) { $request = new ServerRequest(); $request = $request->withUri(new Uri('http://example.com/')); $request = $request->withHeader('Host', 'example.com'); $server = [ - 'HTTPS' => true, + $param => true, ]; $uri = marshalUriFromSapi($server, $request->getHeaders()); @@ -322,14 +337,34 @@ public function testMarshalUriDetectsHttpsSchemeFromServerValue() $this->assertSame('https', $uri->getScheme()); } - public function testMarshalUriUsesHttpSchemeIfHttpsServerValueEqualsOff() + /** + * @return iterable + */ + public function httpsDisableParamProvider() + { + foreach ($this->httpsParamProvider() as $key => $data) { + $param = array_shift($data); + foreach (['lowercase-off', 'uppercase-off'] as $type) { + $key = sprintf('%s-%s', $key, $type); + $value = false !== strpos($type, 'lowercase') ? 'off' : 'OFF'; + yield $key => [$param, $value]; + } + } + } + + /** + * @dataProvider httpsDisableParamProvider + * @param string $param + * @param string $value + */ + public function testMarshalUriUsesHttpSchemeIfHttpsServerValueEqualsOff($param, $value) { $request = new ServerRequest(); $request = $request->withUri(new Uri('http://example.com/')); $request = $request->withHeader('Host', 'example.com'); $server = [ - 'HTTPS' => 'off', + $param => $value, ]; $uri = marshalUriFromSapi($server, $request->getHeaders()); @@ -338,12 +373,16 @@ public function testMarshalUriUsesHttpSchemeIfHttpsServerValueEqualsOff() $this->assertSame('http', $uri->getScheme()); } - public function testMarshalUriDetectsHttpsSchemeFromXForwardedProtoValue() + /** + * @dataProvider httpsParamProvider + * @param string $xForwardedProto + */ + public function testMarshalUriDetectsHttpsSchemeFromXForwardedProtoValue($xForwardedProto) { $request = new ServerRequest(); $request = $request->withUri(new Uri('http://example.com/')); $request = $request->withHeader('Host', 'example.com'); - $request = $request->withHeader('X-Forwarded-Proto', 'https'); + $request = $request->withHeader('X-Forwarded-Proto', $xForwardedProto); $server = [];