blob: e55a8911a3d516906cb9513e9d3fed7cc09988ea (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
<?php
namespace GeminiFoundation\Server\RequestHandlers;
use GeminiFoundation\Request;
use GeminiFoundation\RequestHandlerInterface;
use GeminiFoundation\Response;
use GeminiFoundation\Status;
use function GeminiFoundation\mime_content_type;
class DocumentServer implements RequestHandlerInterface
{
protected string $documentRoot;
protected string $indexFile;
protected bool $useDirectoryListing;
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
{
$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;
}
}
|