Add directory listing feature

This commit is contained in:
Jansen Price 2020-08-27 02:46:11 -05:00
parent 4083638ab0
commit a305a5a92a
3 changed files with 61 additions and 5 deletions

View File

@ -17,4 +17,6 @@ class Config
public $verbose = false;
public $root_dir = ".";
public $index_file = "index.gmi";
public $enable_directory_index = true;
}

View File

@ -49,8 +49,12 @@ class Response
if (false === $fp) {
throw new \Exception("Error reading file '{$this->filepath}'");
}
while (!feof($fp)) {
fwrite($client, fread($fp, 8192));
$result = 1;
while (!feof($fp) && $result) {
// If the client cancels, bail out before trying large files
// So, result will be 0 if the client cancels (broken socket)
$result = fwrite($client, fread($fp, 8192));
}
return $size;
} else {

View File

@ -131,14 +131,33 @@ class Server
}
// Check if index file exists
if (file_exists($resource_path . DIRECTORY_SEPARATOR . "index.gmi")) {
$resource_path = $resource_path . "/index.gmi";
if (file_exists($resource_path . DIRECTORY_SEPARATOR . $this->config->index_file)) {
$resource_path = $resource_path . DIRECTORY_SEPARATOR . $this->config->index_file;
} else {
if (!$this->config->enable_directory_index) {
$response->setStatus(Response::STATUS_BAD_REQUEST);
$response->setMeta('Path not available');
return $response;
} else {
$response->setStatus(Response::STATUS_SUCCESS);
$response->setMeta('text/gemini');
$response->setBody($this->makeDirectoryIndex($resource_path, $dir));
return $response;
}
}
}
if (file_exists($resource_path)) {
// File exists and is world readable
if (file_exists($resource_path) && (fileperms($resource_path) & 0x0004)) {
$response->setStatus(Response::STATUS_SUCCESS);
$pathinfo = pathinfo($resource_path);
if (!isset($pathinfo['extension'])) {
$response->setStatus(Response::STATUS_TEMPORARY_FAILURE);
$response->setMeta('Error reading resource');
return $response;
}
if ($pathinfo['extension'] == 'gmi' || $pathinfo['extension'] == 'gemini') {
$response->setMeta('text/gemini');
} elseif ($pathinfo['extension'] == 'md' || $pathinfo['extension'] == 'markdown') {
@ -179,6 +198,37 @@ class Server
return sprintf('tls://%s:%s', $this->config->host, $this->config->port);
}
public function makeDirectoryIndex($path, $root)
{
$files = glob($path . "*");
$body = "# Directory listing " . str_replace($root, '', $path) . "\n\n";
$body .= "=> " . str_replace($root, '', dirname($path)) . " ..\n";
foreach ($files as $file) {
$relative_path = str_replace($path, '', $file);
$is_dir = false;
if (is_dir($file)) {
$is_dir = true;
$size = '';
} else {
$size = filesize($file);
}
$body .= sprintf(
"=> %s%s %s%s%s\n",
urlencode($relative_path),
($is_dir ? '/' : ''),
$relative_path,
($is_dir ? '/' : ''),
($size ? " ($size)" : '')
);
}
return $body;
}
private function generateCert()
{
// Certificate data