diff --git a/system/Common.php b/system/Common.php index 2d876564846e..451e6c601a63 100644 --- a/system/Common.php +++ b/system/Common.php @@ -502,27 +502,11 @@ function force_https( Services::session()->regenerate(); // @codeCoverageIgnore } - $baseURL = config(App::class)->baseURL; - - if (strpos($baseURL, 'https://') === 0) { - $authority = substr($baseURL, strlen('https://')); - } elseif (strpos($baseURL, 'http://') === 0) { - $authority = substr($baseURL, strlen('http://')); - } else { - $authority = $baseURL; - } - - $uri = URI::createURIString( - 'https', - $authority, - $request->getUri()->getPath(), // Absolute URIs should use a "/" for an empty path - $request->getUri()->getQuery(), - $request->getUri()->getFragment() - ); + $uri = $request->getUri()->withScheme('https'); // Set an HSTS header $response->setHeader('Strict-Transport-Security', 'max-age=' . $duration) - ->redirect($uri) + ->redirect((string) $uri) ->setStatusCode(307) ->setBody('') ->getCookieStore() diff --git a/tests/system/CommonFunctionsTest.php b/tests/system/CommonFunctionsTest.php index 228a24e9a26f..a097cb2a81a0 100644 --- a/tests/system/CommonFunctionsTest.php +++ b/tests/system/CommonFunctionsTest.php @@ -612,6 +612,7 @@ public function testViewNotSaveData(): void public function testForceHttpsNullRequestAndResponse(): void { $this->assertNull(Services::response()->header('Location')); + Services::response()->setCookie('force', 'cookie'); Services::response()->setHeader('Force', 'header'); Services::response()->setBody('default body'); @@ -634,6 +635,25 @@ public function testForceHttpsNullRequestAndResponse(): void force_https(); } + public function testForceHttpsWithBaseUrlSubFolder(): void + { + $config = config(App::class); + $config->baseURL = 'https://example.jp/codeIgniter/'; + $uri = new SiteURI($config, 'en/home?foo=bar'); + $request = new IncomingRequest($config, $uri, '', new UserAgent()); + Services::injectMock('request', $request); + + try { + force_https(); + } catch (Exception $e) { + $this->assertInstanceOf(RedirectException::class, $e); + $this->assertSame( + 'https://example.jp/codeIgniter/index.php/en/home?foo=bar', + $e->getResponse()->header('Location')->getValue() + ); + } + } + /** * @dataProvider provideCleanPathActuallyCleaningThePaths *