From e0dfb7406dd51db2727269ac9d626986914ecc7f Mon Sep 17 00:00:00 2001 From: Hugues Lismonde Date: Tue, 23 Jul 2019 11:52:53 +0200 Subject: [PATCH] Fix request schem As mentionned in #396, the request scheme was not as documented, returning SERVER_PROTOCOL instead. The `getScheme` function is now used to handle common cases (HTTPS, FORWATED_PROTO, ...). `request->secure` is also based on the scheme now as `$_SERVER['HTTPS']` is unreliable for this purpose. --- flight/net/Request.php | 19 +++++++++++++++++-- tests/RequestTest.php | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/flight/net/Request.php b/flight/net/Request.php index 8cae7c2..728df5c 100644 --- a/flight/net/Request.php +++ b/flight/net/Request.php @@ -135,7 +135,7 @@ class Request { 'referrer' => self::getVar('HTTP_REFERER'), 'ip' => self::getVar('REMOTE_ADDR'), 'ajax' => self::getVar('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest', - 'scheme' => self::getVar('SERVER_PROTOCOL', 'HTTP/1.1'), + 'scheme' => self::getScheme(), 'user_agent' => self::getVar('HTTP_USER_AGENT'), 'type' => self::getVar('CONTENT_TYPE'), 'length' => self::getVar('CONTENT_LENGTH', 0), @@ -143,7 +143,7 @@ class Request { 'data' => new Collection($_POST), 'cookies' => new Collection($_COOKIE), 'files' => new Collection($_FILES), - 'secure' => self::getVar('HTTPS', 'off') != 'off', + 'secure' => self::getScheme() == 'https', 'accept' => self::getVar('HTTP_ACCEPT'), 'proxy_ip' => self::getProxyIpAddress() ); @@ -286,4 +286,19 @@ class Request { return $params; } + + public static function getScheme() { + if ( + (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) === 'on') + || + (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') + || + (isset($_SERVER['HTTP_FRONT_END_HTTPS']) && $_SERVER['HTTP_FRONT_END_HTTPS'] === 'on') + || + (isset($_SERVER['REQUEST_SCHEME']) && $_SERVER['REQUEST_SCHEME'] === 'https') + ) { + return 'https'; + } + return 'http'; + } } diff --git a/tests/RequestTest.php b/tests/RequestTest.php index 1c6d144..d9ed265 100644 --- a/tests/RequestTest.php +++ b/tests/RequestTest.php @@ -22,7 +22,6 @@ class RequestTest extends PHPUnit_Framework_TestCase $_SERVER['REQUEST_METHOD'] = 'GET'; $_SERVER['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'; $_SERVER['REMOTE_ADDR'] = '8.8.8.8'; - $_SERVER['HTTPS'] = 'on'; $_SERVER['HTTP_X_FORWARDED_FOR'] = '32.32.32.32'; $this->request = new \flight\net\Request(); @@ -34,10 +33,10 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals('GET', $this->request->method); $this->assertEquals('', $this->request->referrer); $this->assertEquals(true, $this->request->ajax); - $this->assertEquals('HTTP/1.1', $this->request->scheme); + $this->assertEquals('http', $this->request->scheme); $this->assertEquals('', $this->request->type); $this->assertEquals(0, $this->request->length); - $this->assertEquals(true, $this->request->secure); + $this->assertEquals(false, $this->request->secure); $this->assertEquals('', $this->request->accept); } @@ -96,4 +95,34 @@ class RequestTest extends PHPUnit_Framework_TestCase $this->assertEquals('PUT', $request->method); } + + function testHttps() { + $_SERVER['HTTPS'] = 'on'; + $request = new \flight\net\Request(); + $this->assertEquals('https', $request->scheme); + $_SERVER['HTTPS'] = 'off'; + $request = new \flight\net\Request(); + $this->assertEquals('http', $request->scheme); + + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'; + $request = new \flight\net\Request(); + $this->assertEquals('https', $request->scheme); + $_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; + $request = new \flight\net\Request(); + $this->assertEquals('http', $request->scheme); + + $_SERVER['HTTP_FRONT_END_HTTPS'] = 'on'; + $request = new \flight\net\Request(); + $this->assertEquals('https', $request->scheme); + $_SERVER['HTTP_FRONT_END_HTTPS'] = 'off'; + $request = new \flight\net\Request(); + $this->assertEquals('http', $request->scheme); + + $_SERVER['REQUEST_SCHEME'] = 'https'; + $request = new \flight\net\Request(); + $this->assertEquals('https', $request->scheme); + $_SERVER['REQUEST_SCHEME'] = 'http'; + $request = new \flight\net\Request(); + $this->assertEquals('http', $request->scheme); + } }