diff options
Diffstat (limited to 'plugins/webbox/webbox.cpp')
-rw-r--r-- | plugins/webbox/webbox.cpp | 94 |
1 files changed, 92 insertions, 2 deletions
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")}; |