documentRoot = $documentRoot ?: getcwd(); $this->indexFile = $indexFile; $this->useDirectoryListing = $useDirectoryListing; } public function __invoke(Response $response, Request $request): Response { $requestPath = $this->trim(urldecode($request->getPath())); $filePath = $this->documentRoot . $requestPath; $documentPath = $filePath; if (! is_file($documentPath)) { $documentPath = $filePath . '/' . $this->indexFile; } if (is_file($documentPath)) { $content = file_get_contents($documentPath); $response->setBody($content); $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; } }