summaryrefslogtreecommitdiffhomepage
path: root/plugins
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-05-10 16:51:20 +0200
committerRoland Reichwein <mail@reichwein.it>2020-05-10 16:51:20 +0200
commit5b32a4415c9776dd6cae859c8d718b5e68f01d81 (patch)
tree9c9684367a1d415b1d836065daca2e8789fcd1a5 /plugins
parenteb7c96f1ee9cf3eff2dd86f2a1b6ea46a80e41c8 (diff)
Move webbox to root to make index
Diffstat (limited to 'plugins')
-rw-r--r--plugins/fcgi/fcgi.cpp11
-rw-r--r--plugins/webbox/html/index.html9
-rw-r--r--plugins/webbox/html/webbox.js33
-rw-r--r--plugins/webbox/webbox.cpp94
4 files changed, 117 insertions, 30 deletions
diff --git a/plugins/fcgi/fcgi.cpp b/plugins/fcgi/fcgi.cpp
index f9d8a4d..a97f1c0 100644
--- a/plugins/fcgi/fcgi.cpp
+++ b/plugins/fcgi/fcgi.cpp
@@ -314,16 +314,6 @@ namespace {
return status + " " + message;
}
- void DumpAppValues(const std::unordered_map<std::string, std::string>& app_values)
- {
- std::cout << "App properties:" << std::endl;
- if (app_values.size() == 0)
- std::cout << " (empty)" << std::endl;
- else for (auto&[key, value]: app_values) {
- std::cout << " " << key << "=" << value << std::endl;
- }
- }
-
} // anonymous namespace
std::string fcgi_plugin::fcgiQuery(FCGIContext& context)
@@ -448,7 +438,6 @@ std::string fcgi_plugin::fcgiQuery(FCGIContext& context)
std::cerr << "FCGI STDERR: " << r.getContent() << std::endl;
} else if (r.getType() == FCGI_GET_VALUES_RESULT) {
FCGI_DecodeEnv(r.getContent(), app_values);
- //DumpAppValues(app_values);
} else
throw std::runtime_error("Unhandled FCGI type: "s + std::to_string(r.getType()));
} catch (const std::length_error& ex) {
diff --git a/plugins/webbox/html/index.html b/plugins/webbox/html/index.html
index e9ea819..cc1cf12 100644
--- a/plugins/webbox/html/index.html
+++ b/plugins/webbox/html/index.html
@@ -4,22 +4,23 @@
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Webbox</title>
- <link rel="stylesheet" type="text/css" href="webbox.css"/>
- <script src="webbox.js"></script>
+ <link rel="stylesheet" type="text/css" href="webbox-html/webbox.css"/>
+ <link rel="shortcut icon" href="webbox-html/favicon.ico" type="image/x-icon"/>
+ <script src="webbox-html/webbox.js"></script>
</head>
<body onload="initMainpage();">
<div>
<table>
<tr>
<td class="title">Webbox</td>
- <td class="menusymbol" onclick="showMenu();"><img src="menu.png" alt=""/></td>
+ <td class="menusymbol" onclick="showMenu();"><img src="webbox-html/menu.png" alt=""/></td>
</tr>
</table>
<input id="uploadfile" type="file" onchange="onUploadFile();" multiple hidden/>
<table class="menu">
<tr>
<td class="firsttd"></td>
- <td class="entry" onclick="refresh();"><img src="refresh-inverted.png" alt=""/></td>
+ <td class="entry" onclick="refresh();"><img src="webbox-html/refresh-inverted.png" alt=""/></td>
</tr>
</table>
</div>
diff --git a/plugins/webbox/html/webbox.js b/plugins/webbox/html/webbox.js
index 9a38051..602f76d 100644
--- a/plugins/webbox/html/webbox.js
+++ b/plugins/webbox/html/webbox.js
@@ -4,6 +4,13 @@ var numberOfSelectedRows = 0;
var username = "notaname";
var password = "password";
+function relativePath(path) {
+ if (path.startsWith("/"))
+ return path.substr(1);
+ else
+ return path;
+}
+
function clearContents() {
var result = "<table class=\"list\">";
// empty list
@@ -35,9 +42,9 @@ function loadContents(dir) {
for (var i = 0; i < listElements.length; i++) {
var type = listElements[i].getAttribute("type");
if (type == "file") {
- type = "<img src=\"file.png\"/>";
+ type = "<img src=\"webbox-html/file.png\"/>";
} else if (type == "dir") {
- type = "<img src=\"directory.png\"/>";
+ type = "<img src=\"webbox-html/directory.png\"/>";
} else {
type = "";
}
@@ -57,7 +64,7 @@ function loadContents(dir) {
}
- xhr.open("GET", "bin" + dir + "?command=list", true);
+ xhr.open("GET", relativePath(dir) + "?command=list", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.send();
}
@@ -329,7 +336,7 @@ function initMainpage() {
initMainpage2();
}
- xhrTitle.open("GET", "bin?command=server-info", true);
+ xhrTitle.open("GET", "?command=server-info", true);
xhrTitle.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhrTitle.send();
@@ -350,7 +357,7 @@ function initMainpage2() {
document.getElementsByClassName("footer")[0].innerHTML = xhrFooter.responseText;
}
- xhrFooter.open("GET", "bin?command=version", true);
+ xhrFooter.open("GET", "?command=version", true);
xhrFooter.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhrFooter.send();
@@ -431,7 +438,7 @@ function download(filename) {
filesElement.appendChild(fileElement);
}
- xhr.open("POST", "bin" + currentDir + "?command=download-zip", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=download-zip", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-type", "text/xml");
xhr.responseType = 'blob';
@@ -458,7 +465,7 @@ function download(filename) {
dir += "/"
}
progressOn();
- xhr.open("GET", "bin" + dir + filename, true);
+ xhr.open("GET", relativePath(dir) + filename, true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.responseType = 'blob';
xhr.send();
@@ -493,7 +500,7 @@ function createDir() {
dirElement.appendChild(document.createTextNode(document.getElementById("newdir").value));
- xhr.open("POST", "bin" + currentDir + "?command=newdir", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=newdir", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-type", "text/xml");
xhr.send(xmlDocument);
@@ -557,7 +564,7 @@ function onUploadFile() {
formData.append("uploadfile", uploadfile.files[i]);
}
- xhr.open("POST", "bin" + currentDir + "?command=upload", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=upload", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.send(formData);
}
@@ -607,7 +614,7 @@ function deleteItems() {
filesElement.appendChild(fileElement);
}
- xhr.open("POST", "bin" + currentDir + "?command=delete", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=delete", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-type", "text/xml");
xhr.send(xmlDocument);
@@ -672,7 +679,7 @@ function move() {
filesElement.appendChild(fileElement);
}
- xhr.open("POST", "bin" + currentDir + "?command=move", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=move", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-type", "text/xml");
xhr.send(xmlDocument);
@@ -736,7 +743,7 @@ function rename() {
newnameElement.appendChild(document.createTextNode(document.getElementById("renamenew").value));
filesElement.appendChild(newnameElement);
- xhr.open("POST", "bin" + currentDir + "?command=rename", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=rename", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-type", "text/xml");
xhr.send(xmlDocument);
@@ -784,7 +791,7 @@ function info() {
filesElement.appendChild(fileElement);
}
- xhr.open("POST", "bin" + currentDir + "?command=info", true);
+ xhr.open("POST", relativePath(currentDir) + "?command=info", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
xhr.setRequestHeader("Content-type", "text/xml");
xhr.send(xmlDocument);
diff --git a/plugins/webbox/webbox.cpp b/plugins/webbox/webbox.cpp
index 7d15ee9..c58bd0c 100644
--- a/plugins/webbox/webbox.cpp
+++ b/plugins/webbox/webbox.cpp
@@ -30,6 +30,11 @@ namespace {
static const std::string PROGRAMVERSION{"Webbox 2.0"};
static const std::string DOWNLOAD_FILENAME{"webbox-download.zip"};
+ // STATIC_HTML_TARGET: no leading slash because comparision is done with relative path;
+ // trailing slash because of path comparison
+ static const std::string STATIC_HTML_TARGET{"webbox-html/"};
+ static const fs::path STATIC_HTML_DOC_ROOT{"/usr/lib/webbox/html"};
+
// TODO: separate out
class Tempfile
{
@@ -109,6 +114,8 @@ namespace {
result[urlDecode(i.substr(0, pos))] = urlDecode(i.substr(pos + 1));
}
}
+ } else if (s == "/" || s == "" || boost::algorithm::starts_with(s, STATIC_HTML_TARGET)) {
+ result["command"] = "static-html";
}
return result;
@@ -125,6 +132,7 @@ namespace {
std::string webboxPath;
std::string webboxName;
bool webboxReadOnly;
+ fs::path webboxStaticHtml;
CommandParameters(
std::function<std::string(const std::string& key)>& GetServerParam,
@@ -138,7 +146,10 @@ namespace {
, webboxPath(m_GetRequestParam("doc_root"))
, webboxName(m_GetRequestParam("WEBBOX_NAME"))
, webboxReadOnly(m_GetRequestParam("WEBBOX_READONLY") == "1")
+ , webboxStaticHtml(m_GetRequestParam("WEBBOX_STATIC_HTML"))
{
+ if (webboxStaticHtml == "")
+ webboxStaticHtml = STATIC_HTML_DOC_ROOT;
}
};
@@ -780,7 +791,83 @@ protected:
return result;
} catch (const std::exception& ex) {
- return HttpStatus("500", "Bad file: "s + m_path.filename().string(), p);
+ return HttpStatus("404", "Bad file: "s + m_path.filename().string(), p);
+ }
+ }
+};
+
+// Return a reasonable mime type based on the extension of a file.
+static std::string
+mime_type(fs::path path)
+{
+ using boost::algorithm::iequals;
+ auto const ext = [&path]
+ {
+ size_t pos = path.string().rfind(".");
+ if (pos == std::string::npos)
+ return std::string{};
+ return path.string().substr(pos);
+ }();
+ if(iequals(ext, ".htm")) return "text/html"; // TODO: unordered_map
+ if(iequals(ext, ".html")) return "text/html";
+ if(iequals(ext, ".php")) return "text/html";
+ if(iequals(ext, ".css")) return "text/css";
+ if(iequals(ext, ".txt")) return "text/plain";
+ if(iequals(ext, ".js")) return "application/javascript";
+ if(iequals(ext, ".json")) return "application/json";
+ if(iequals(ext, ".xml")) return "application/xml";
+ if(iequals(ext, ".swf")) return "application/x-shockwave-flash";
+ if(iequals(ext, ".flv")) return "video/x-flv";
+ if(iequals(ext, ".png")) return "image/png";
+ if(iequals(ext, ".jpe")) return "image/jpeg";
+ if(iequals(ext, ".jpeg")) return "image/jpeg";
+ if(iequals(ext, ".jpg")) return "image/jpeg";
+ if(iequals(ext, ".gif")) return "image/gif";
+ if(iequals(ext, ".bmp")) return "image/bmp";
+ if(iequals(ext, ".ico")) return "image/vnd.microsoft.icon";
+ if(iequals(ext, ".tiff")) return "image/tiff";
+ if(iequals(ext, ".tif")) return "image/tiff";
+ if(iequals(ext, ".svg")) return "image/svg+xml";
+ if(iequals(ext, ".svgz")) return "image/svg+xml";
+ return "application/text";
+}
+
+class StaticHtmlCommand: public GetCommand
+{
+public:
+ StaticHtmlCommand()
+ {
+ m_commandName = "static-html";
+ m_isWriteCommand = false;
+ }
+
+protected:
+ virtual std::string start(CommandParameters& p)
+ {
+ // redirect to xyz/ if xyz was requested
+ std::string target = p.m_GetRequestParam("target");
+ if (m_pathInfo == "" && !target.empty() && target.back() != '/') {
+ p.m_SetResponseHeader("location", target + "/");
+ return HttpStatus("301", "Use correct index: /"s, p);
+ }
+
+ try {
+
+ fs::path file_path;
+ if (m_pathInfo == "/" || m_pathInfo == "") {
+ file_path = p.webboxStaticHtml / "index.html";
+ } else if (boost::algorithm::starts_with(m_pathInfo, STATIC_HTML_TARGET)) {
+ file_path = p.webboxStaticHtml / m_pathInfo.substr(STATIC_HTML_TARGET.size());
+ } else {
+ return HttpStatus("500", "Bad request: "s + m_pathInfo, p);
+ }
+
+ p.m_SetResponseHeader("content_type", mime_type(file_path));
+ std::string result{File::getFile(file_path)};
+ return result;
+
+ } catch (const std::exception& ex) {
+ return HttpStatus("500", "Server error: "s + m_pathInfo, p);
}
}
};
@@ -805,6 +892,7 @@ webbox_plugin::webbox_plugin()
registerCommand(std::make_shared<RenameCommand>());
registerCommand(std::make_shared<UploadCommand>());
registerCommand(std::make_shared<DownloadCommand>());
+ registerCommand(std::make_shared<StaticHtmlCommand>());
}
webbox_plugin::~webbox_plugin()
@@ -818,8 +906,10 @@ std::string webbox_plugin::generate_page(
std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader // to be added to result string
)
{
- CommandParameters commandParameters(GetServerParam, GetRequestParam, SetResponseHeader);
+ // Queries under STATIC_HTML_TARGET will be served statically from STATIC_HTML_DOC_ROOT
+ CommandParameters commandParameters(GetServerParam, GetRequestParam, SetResponseHeader);
+
std::string commandName;
auto it {commandParameters.paramHash.find("command")};