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 ++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'src') 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; + } } -- cgit v1.2.3