From b51d8c76dd49f6474c1299742ff9d41462fa9dca Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Wed, 22 Nov 2023 17:39:59 +0100 Subject: [DocumentServer] add directory listing --- src/Server/RequestHandlers/DocumentServer.php | 32 ++++++++++++++++++++++++--- test/server.php | 5 ++++- test/sub/index.gmi | 3 --- test/sub/sub.txt | 1 + 4 files changed, 34 insertions(+), 7 deletions(-) delete mode 100644 test/sub/index.gmi create mode 100644 test/sub/sub.txt diff --git a/src/Server/RequestHandlers/DocumentServer.php b/src/Server/RequestHandlers/DocumentServer.php index 37a3bd6..e55a891 100644 --- a/src/Server/RequestHandlers/DocumentServer.php +++ b/src/Server/RequestHandlers/DocumentServer.php @@ -11,17 +11,28 @@ use function GeminiFoundation\mime_content_type; class DocumentServer implements RequestHandlerInterface { protected string $documentRoot; + protected string $indexFile; + protected bool $useDirectoryListing; - public function __construct(string $documentRoot = '') + public function __construct( + string $documentRoot = '', + string $indexFile = 'index.gmi', + bool $useDirectoryListing = false + ) { $this->documentRoot = $documentRoot ?: getcwd(); + $this->indexFile = $indexFile; + $this->useDirectoryListing = $useDirectoryListing; } public function __invoke(Response $response, Request $request): Response { - $documentPath = $this->documentRoot . urldecode($request->getPath()); + $requestPath = $this->trim(urldecode($request->getPath())); + $filePath = $this->documentRoot . $requestPath; + + $documentPath = $filePath; if (! is_file($documentPath)) { - $documentPath = $this->documentRoot . $request->getPath() . '/index.gmi'; + $documentPath = $filePath . '/' . $this->indexFile; } if (is_file($documentPath)) { @@ -30,10 +41,25 @@ class DocumentServer implements RequestHandlerInterface $response->setStatusCode(Status::SUCCESS); $response->setMeta(mime_content_type($documentPath) . '; charset=utf-8'); + } else if ($this->useDirectoryListing && is_dir($filePath)) { + $body = ''; + foreach (scandir($filePath) as $fileName) { + $link = implode('/', array_map('urlencode', explode('/', "$requestPath/$fileName"))); + $body .= "=> $link $fileName \r\n"; + } + + $response->setBody($body); + $response->setStatusCode(Status::SUCCESS); + $response->setMeta('text/gemini; charset=utf-8'); } else { $response->setStatusCode(Status::NOT_FOUND); } return $response; } + + private function trim(string $string) + { + return str_ends_with($string, '/') ? substr($string, offset: 0, length: -1) : $string; + } } diff --git a/test/server.php b/test/server.php index c90942a..adc9d05 100644 --- a/test/server.php +++ b/test/server.php @@ -13,6 +13,9 @@ $server = new Server( ], ); -$server->onRequest(new DocumentServer(__DIR__)); +$server->onRequest(new DocumentServer( + documentRoot: __DIR__, + useDirectoryListing: true +)); $server->listen(); diff --git a/test/sub/index.gmi b/test/sub/index.gmi deleted file mode 100644 index 193cc4d..0000000 --- a/test/sub/index.gmi +++ /dev/null @@ -1,3 +0,0 @@ -subfolder - -=> / diff --git a/test/sub/sub.txt b/test/sub/sub.txt new file mode 100644 index 0000000..371b205 --- /dev/null +++ b/test/sub/sub.txt @@ -0,0 +1 @@ +textcontent -- cgit v1.2.3