From 1ee987a810bfc12a21927c0f05a20216422fa237 Mon Sep 17 00:00:00 2001 From: Lorna Jane Mitchell Date: Mon, 13 Aug 2018 12:32:50 +0100 Subject: [PATCH 1/3] Pick port defaults depending if the host was in HTTP_HOST or from the running server --- Slim/Http/Uri.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Slim/Http/Uri.php b/Slim/Http/Uri.php index 57b3acf3a..c44772439 100644 --- a/Slim/Http/Uri.php +++ b/Slim/Http/Uri.php @@ -173,15 +173,17 @@ public static function createFromEnvironment(Environment $env) $username = $env->get('PHP_AUTH_USER', ''); $password = $env->get('PHP_AUTH_PW', ''); - // Authority: Host + // Authority: Host and Port if ($env->has('HTTP_HOST')) { $host = $env->get('HTTP_HOST'); + // set a port default + $port = 80; } else { $host = $env->get('SERVER_NAME'); + // set a port default + $port = (int)$env->get('SERVER_PORT', 80); } - // Authority: Port - $port = (int)$env->get('SERVER_PORT', 80); if (preg_match('/^(\[[a-fA-F0-9:.]+\])(:\d+)?\z/', $host, $matches)) { $host = $matches[1]; From 8b7a44513a4e0e8720c99edd88549dcbfdf18969 Mon Sep 17 00:00:00 2001 From: Rob Allen Date: Tue, 11 Sep 2018 10:17:48 +0100 Subject: [PATCH 2/3] Don't set the default port when the Host header exists If there is a Host header, then we can expect the port to be part of it. If the port is not there, then we should use the default for the scheme as per RFC 2616, section 14.23. --- Slim/Http/Uri.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Slim/Http/Uri.php b/Slim/Http/Uri.php index c44772439..7e168a660 100644 --- a/Slim/Http/Uri.php +++ b/Slim/Http/Uri.php @@ -177,7 +177,7 @@ public static function createFromEnvironment(Environment $env) if ($env->has('HTTP_HOST')) { $host = $env->get('HTTP_HOST'); // set a port default - $port = 80; + $port = null; } else { $host = $env->get('SERVER_NAME'); // set a port default From 77bd8c982a0722e1378fd1e8d5f547f4411b6659 Mon Sep 17 00:00:00 2001 From: Rob Allen Date: Tue, 11 Sep 2018 10:19:08 +0100 Subject: [PATCH 3/3] Update tests for handling a default port in the Host header Also remove test where SERVER_PORT is used when Host header exists as this was an incorrect assumption that is wrong. --- tests/Http/UriTest.php | 52 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/tests/Http/UriTest.php b/tests/Http/UriTest.php index ef6f23d32..3d5ac82bf 100644 --- a/tests/Http/UriTest.php +++ b/tests/Http/UriTest.php @@ -546,6 +546,27 @@ public function testCreateEnvironment() $this->assertEquals('', $uri->getFragment()); } + public function testCreateFromEnvironmentSetsDefaultPortWhenHostHeaderDoesntHaveAPort() + { + $environment = Environment::mock([ + 'SCRIPT_NAME' => '/index.php', + 'REQUEST_URI' => '/foo/bar', + 'QUERY_STRING' => 'abc=123', + 'HTTP_HOST' => 'example.com', + 'HTTPS' => 'on', + ]); + + $uri = Uri::createFromEnvironment($environment); + + $this->assertEquals('example.com', $uri->getHost()); + $this->assertEquals(null, $uri->getPort()); + $this->assertEquals('/foo/bar', $uri->getPath()); + $this->assertEquals('abc=123', $uri->getQuery()); + $this->assertEquals('', $uri->getFragment()); + + $this->assertEquals('https://example.com/foo/bar?abc=123', (string)$uri); + } + public function testCreateEnvironmentWithIPv6HostNoPort() { $environment = Environment::mock([ @@ -556,14 +577,13 @@ public function testCreateEnvironmentWithIPv6HostNoPort() 'QUERY_STRING' => 'abc=123', 'HTTP_HOST' => '[2001:db8::1]', 'REMOTE_ADDR' => '2001:db8::1', - 'SERVER_PORT' => 8080, ]); $uri = Uri::createFromEnvironment($environment); $this->assertEquals('josh:sekrit', $uri->getUserInfo()); $this->assertEquals('[2001:db8::1]', $uri->getHost()); - $this->assertEquals('8080', $uri->getPort()); + $this->assertNull($uri->getPort()); $this->assertEquals('/foo/bar', $uri->getPath()); $this->assertEquals('abc=123', $uri->getQuery()); $this->assertEquals('', $uri->getFragment()); @@ -579,7 +599,6 @@ public function testCreateEnvironmentWithIPv6HostWithPort() 'QUERY_STRING' => 'abc=123', 'HTTP_HOST' => '[2001:db8::1]:8080', 'REMOTE_ADDR' => '2001:db8::1', - 'SERVER_PORT' => 8080, ]); $uri = Uri::createFromEnvironment($environment); @@ -592,6 +611,33 @@ public function testCreateEnvironmentWithIPv6HostWithPort() $this->assertEquals('', $uri->getFragment()); } + /** + * @group one + */ + public function testCreateEnvironmentWithNoHostHeader() + { + $environment = Environment::mock([ + 'SCRIPT_NAME' => '/index.php', + 'REQUEST_URI' => '/foo/bar', + 'PHP_AUTH_USER' => 'josh', + 'PHP_AUTH_PW' => 'sekrit', + 'QUERY_STRING' => 'abc=123', + 'REMOTE_ADDR' => '2001:db8::1', + 'SERVER_NAME' => '[2001:db8::1]', + 'SERVER_PORT' => '8080', + ]); + $environment->remove('HTTP_HOST'); + + $uri = Uri::createFromEnvironment($environment); + + $this->assertEquals('josh:sekrit', $uri->getUserInfo()); + $this->assertEquals('[2001:db8::1]', $uri->getHost()); + $this->assertEquals('8080', $uri->getPort()); + $this->assertEquals('/foo/bar', $uri->getPath()); + $this->assertEquals('abc=123', $uri->getQuery()); + $this->assertEquals('', $uri->getFragment()); + } + /** * @covers Slim\Http\Uri::createFromEnvironment * @ticket 1375