diff --git a/system/HTTP/ResponseTrait.php b/system/HTTP/ResponseTrait.php index 3063e44116fb..265a62fb0a1f 100644 --- a/system/HTTP/ResponseTrait.php +++ b/system/HTTP/ResponseTrait.php @@ -733,20 +733,15 @@ public function download(string $filename = '', $data = '', bool $setMime = fals return null; } - $filepath = ''; if ($data === null) { - $filepath = $filename; - $filename = explode('/', str_replace(DIRECTORY_SEPARATOR, '/', $filename)); - $filename = end($filename); + $response = new DownloadResponse(basename($filename), $setMime); + $response->setFilePath($filename); + + return $response; } $response = new DownloadResponse($filename, $setMime); - - if ($filepath !== '') { - $response->setFilePath($filepath); - } elseif ($data !== null) { - $response->setBinary($data); - } + $response->setBinary($data); return $response; } diff --git a/tests/system/HTTP/ResponseTest.php b/tests/system/HTTP/ResponseTest.php index 38c349117cbb..8eb0432bd31d 100644 --- a/tests/system/HTTP/ResponseTest.php +++ b/tests/system/HTTP/ResponseTest.php @@ -494,6 +494,38 @@ public function testGetDownloadResponseByFilePath(): void $this->assertSame(file_get_contents(__FILE__), $actualOutput); } + public function testGetDownloadResponseByExtremeFilePath(): void + { + $response = new Response(new App()); + + $tempDir = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'ci4_test_dir'; + @mkdir($tempDir); + $extremeName = 'my_extreme_file_!@#$%.txt'; + $extremePath = $tempDir . DIRECTORY_SEPARATOR . $extremeName; + file_put_contents($extremePath, 'extreme data'); + + $actual = $response->download($extremePath, null); + + $this->assertInstanceOf(DownloadResponse::class, $actual); + $actual->buildHeaders(); + + $expectedBasename = basename($extremePath); + $this->assertSame( + 'attachment; filename="' . addslashes($expectedBasename) . '"; filename*=UTF-8\'\'' . rawurlencode($expectedBasename), + $actual->getHeaderLine('Content-Disposition'), + ); + + ob_start(); + $actual->sendBody(); + $actualOutput = ob_get_contents(); + ob_end_clean(); + + $this->assertSame('extreme data', $actualOutput); + + unlink($extremePath); + rmdir($tempDir); + } + public function testVagueDownload(): void { $response = new Response(new App());