mirror of
https://codeberg.org/Codeberg/pages-server.git
synced 2025-01-19 08:57:55 +00:00
fix path if incomplete, more mime-types, security work
This commit is contained in:
parent
d0ea43788d
commit
369907392e
1 changed files with 68 additions and 27 deletions
|
@ -1,57 +1,98 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
function error($code, $message) {
|
function send_response($code, $message) {
|
||||||
http_response_code(code);
|
http_response_code($code);
|
||||||
echo("$code : $message");
|
echo $message;
|
||||||
die();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
$request_url = $_SERVER["PHP_SELF"];
|
$request_url = filter_var($_SERVER["PHP_SELF"], FILTER_SANITIZE_URL);
|
||||||
|
|
||||||
if (substr($request_url, -1) == "/") {
|
if ($request_url === "/") {
|
||||||
$request_url .= "index.html";
|
send_response(200, "
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Codeberg Pages</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Codeberg Pages. Static Pages for your Project.</h1>
|
||||||
|
<p>
|
||||||
|
Create a repo called 'pages' to your user account or org, push static content including HTML+CSS styles, fonts, images.
|
||||||
|
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Access your rendered pages via:
|
||||||
|
<pre>
|
||||||
|
https://" . $_SERVER["HTTP_HOST"] . "/<username>/
|
||||||
|
</pre>
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (preg_match("/\/[a-zA-Z0-9_ +\-\/\.]+\z/", $request_url) != 1) {
|
if (preg_match("/^\/[a-zA-Z0-9_ +\-\/\.]+\$/", $request_url) != 1) {
|
||||||
error(404, "invalid request URL '$request_url'");
|
send_response(404, "invalid request URL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$git_prefix = "/data/git/gitea-repositories";
|
||||||
$parts = explode("/", $request_url);
|
$parts = explode("/", $request_url);
|
||||||
array_shift($parts); # remove empty first
|
array_shift($parts); # remove empty first
|
||||||
$owner = strtolower(array_shift($parts));
|
$owner = strtolower(array_shift($parts));
|
||||||
$git_root = "/data/git/gitea-repositories/$owner/pages.git";
|
$git_root = realpath("$git_prefix/$owner/pages.git");
|
||||||
$file_url = implode("/", $parts);
|
|
||||||
|
|
||||||
if (!is_dir($git_root)) {
|
if (substr($git_root, 0, strlen($git_prefix)) !== $git_prefix) {
|
||||||
error(404, "this user/organization does not have codeberg pages");
|
send_response(404, "this user/organization does not have codeberg pages");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (end($parts) === '') {
|
||||||
|
array_shift($parts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof($parts) === 0 || strpos(end($parts), ".") === false) {
|
||||||
|
$h = "Location: https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
|
||||||
|
if (substr($h, -1) != "/") {
|
||||||
|
$h .= "/";
|
||||||
|
}
|
||||||
|
$h .= "index.html";
|
||||||
|
header($h);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$file_url = implode("/", $parts);
|
||||||
|
|
||||||
$command = "sh -c \"cd '$git_root' && /usr/bin/git show 'master:$file_url'\"";
|
$command = "sh -c \"cd '$git_root' && /usr/bin/git show 'master:$file_url'\"";
|
||||||
|
|
||||||
## We are executing command twice (first for error-checking, then for actual raw output to stream),
|
## We are executing command twice (first for send_response-checking, then for actual raw output to stream),
|
||||||
## which seems wasteful, but it seems exec+echo cannot do raw binary output? Is this true?
|
## which seems wasteful, but it seems exec+echo cannot do raw binary output? Is this true?
|
||||||
exec($command, $output, $retval);
|
exec($command, $output, $retval);
|
||||||
if ($retval != 0) {
|
if ($retval != 0) {
|
||||||
error(404 , "no such file in repo: '$file_url'");
|
send_response(404 , "no such file in repo: '" . htmlspecialchars($file_url) . "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$mime_types = array(
|
||||||
|
"svg" => "image/svg+xml",
|
||||||
|
"png" => "image/png",
|
||||||
|
"jpg" => "image/jpeg",
|
||||||
|
"jpeg" => "image/jpeg",
|
||||||
|
"gif" => "image/gif",
|
||||||
|
"js" => "application/javascript",
|
||||||
|
"html" => "text/html",
|
||||||
|
"css" => "text/css",
|
||||||
|
"ico" => "image/x-icon"
|
||||||
|
);
|
||||||
|
|
||||||
$ext = pathinfo($file_url, PATHINFO_EXTENSION);
|
$ext = pathinfo($file_url, PATHINFO_EXTENSION);
|
||||||
$ext = strtolower($ext);
|
$ext = strtolower($ext);
|
||||||
|
|
||||||
if ($ext == "svg") {
|
if (array_key_exists($ext, $mime_types)) {
|
||||||
header("Content-Type: image/svg+xml");
|
$mime_type = $mime_types[$ext];
|
||||||
} elseif ($ext == "jpg") {
|
} else {
|
||||||
header("Content-Type: image/jpeg");
|
$mime_type = "text/plain";
|
||||||
} elseif ($ext == "png") {
|
|
||||||
header("Content-Type: image/png");
|
|
||||||
} elseif ($ext == "gif") {
|
|
||||||
header("Content-Type: image/gif");
|
|
||||||
} elseif ($ext == "js") {
|
|
||||||
header("Content-Type: application/javascript");
|
|
||||||
} elseif ($ext == "css") {
|
|
||||||
header("Content-Type: text/css");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
header("Content-Type: " . $mime_type);
|
||||||
|
|
||||||
## If we could directly implode+echo raw output from above, we wouldn't need to execute command twice:
|
## If we could directly implode+echo raw output from above, we wouldn't need to execute command twice:
|
||||||
passthru($command);
|
passthru($command);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue