diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | plugins/cgi/cgi.cpp | 52 | ||||
-rw-r--r-- | plugins/webbox/TODO | 19 | ||||
-rw-r--r-- | response.cpp | 3 |
4 files changed, 65 insertions, 11 deletions
@@ -10,3 +10,5 @@ wildcard ip listen crypt pws config consistency: check double keys redirect-plugin +systemctl reload +licence bsd diff --git a/plugins/cgi/cgi.cpp b/plugins/cgi/cgi.cpp index 5921e98..232abff 100644 --- a/plugins/cgi/cgi.cpp +++ b/plugins/cgi/cgi.cpp @@ -24,16 +24,22 @@ namespace { std::function<std::string(const std::string& key)>& GetRequestParam; // request including body (POST...) std::function<void(const std::string& key, const std::string& value)>& SetResponseHeader; // to be added to result string fs::path& path; + fs::path& file_path; + fs::path& path_info; CGIContext(std::function<std::string(const std::string& key)>& p_GetServerParam, std::function<std::string(const std::string& key)>& p_GetRequestParam, std::function<void(const std::string& key, const std::string& value)>& p_SetResponseHeader, - fs::path& p_path + fs::path& p_path, + fs::path& p_file_path, + fs::path& p_path_info ) : GetServerParam(p_GetServerParam) , GetRequestParam(p_GetRequestParam) , SetResponseHeader(p_SetResponseHeader) , path(p_path) + , file_path(p_file_path) + , path_info(p_path_info) { } }; @@ -89,7 +95,17 @@ namespace { } std::unordered_map<std::string, std::function<void(std::string&, CGIContext&)>> headerMap { - { "Content-Type", [](std::string& v, CGIContext& c){ c.SetResponseHeader("content_type", v); } } + { "Cache-control", [](std::string& v, CGIContext& c){ c.SetResponseHeader("cache_control", v); } }, + + { "Content-Type", [](std::string& v, CGIContext& c){ c.SetResponseHeader("content_type", v); } }, + + { "Status", [](std::string& v, CGIContext& c) { + std::string status{"500"}; + if (v.size() >= 3) { + status = v.substr(0, 3); + } + c.SetResponseHeader("status", status); + } } }; void handleHeader(const std::string& s, CGIContext& context) @@ -123,11 +139,11 @@ namespace { size_t query_pos {target.find("?")}; std::string query; if (query_pos != target.npos) { - query = target.substr(0, query_pos); - target = target.substr(query_pos + 1); + query = target.substr(query_pos + 1); + target = target.substr(0, query_pos); } - env["PATH_INFO"] = target; + env["PATH_INFO"] = c.path_info.string(); env["PATH_TRANSLATED"] = c.path.string(); env["QUERY_STRING"] = query; env["REMOTE_ADDR"] = ""; @@ -135,7 +151,8 @@ namespace { env["REMOTE_IDENT"] = ""; env["REMOTE_USER"] = ""; env["REQUEST_METHOD"] = c.GetRequestParam("method"); - env["SCRIPT_NAME"] = c.GetRequestParam("rel_target"); + env["REQUEST_URI"] = target; + env["SCRIPT_NAME"] = c.file_path; env["SERVER_NAME"] = c.GetRequestParam("host"); env["SERVER_PORT"] = c.GetServerParam("port"); env["SERVER_PROTOCOL"] = c.GetRequestParam("http_version"); @@ -259,12 +276,25 @@ std::string cgi_plugin::generate_page( return HttpStatus("301", "Correcting directory path", SetResponseHeader); } + fs::path path_info{}; + fs::path file_path{target}; try { - if (!fs::is_regular_file(path)) { - return HttpStatus("500", "Bad Script: "s + rel_target, SetResponseHeader); - } + // file file name part and separate path_info + while (!fs::is_regular_file(path) && path != "/" && path != "") { + if (path_info.string() == "") + path_info = fs::path{"/"} / path.filename(); + else + path_info = fs::path{"/"} / path.filename() / path_info.relative_path(); + + path = path.parent_path(); + file_path = file_path.parent_path(); + } + + if (!fs::is_regular_file(path)) { + return HttpStatus("500", "Bad Script: "s + rel_target, SetResponseHeader); + } } catch (const std::exception& ex) { - return HttpStatus("500", "Bad file access: "s + rel_target, SetResponseHeader); + return HttpStatus("500", "Bad file access: "s + rel_target, SetResponseHeader); } try { @@ -277,7 +307,7 @@ std::string cgi_plugin::generate_page( SetResponseHeader("content_type", mime_type(path)); - CGIContext context(GetServerParam, GetRequestParam, SetResponseHeader, path); + CGIContext context(GetServerParam, GetRequestParam, SetResponseHeader, path, file_path, path_info); try { return executeFile(path, context); diff --git a/plugins/webbox/TODO b/plugins/webbox/TODO new file mode 100644 index 0000000..307dfe4 --- /dev/null +++ b/plugins/webbox/TODO @@ -0,0 +1,19 @@ +Prio 1 (for next version) +====== + +generate download link for selected file +selection button for files/dirs +fix minification on stable debian +gallery + +Prio 2 (for future versions) +====== + +links in path line, to dirs +google pagespeed insights https://developers.google.com/speed/pagespeed/insights/?url=http%3A%2F%2Fwww.kneipenband.com%2Fwebbox%2F&tab=mobile +chromecast +player +i18n +forward/back button +list: more info if appropriate, number of files, limit(?) +about page diff --git a/response.cpp b/response.cpp index ca7a58d..97e2019 100644 --- a/response.cpp +++ b/response.cpp @@ -168,6 +168,7 @@ void SetResponseHeader(const std::string& key, const std::string& value, respons { // following are the supported fields: + // TODO: unordered_map if (key == "status") { // HTTP Status, e.g. "200" (OK) res.result(unsigned(stoul(value))); } else if (key == "server") { // Server name/version string @@ -178,6 +179,8 @@ void SetResponseHeader(const std::string& key, const std::string& value, respons res.set(http::field::content_disposition, value); } else if (key == "location") { // e.g. 301 Moved Permanently: new Location res.set(http::field::location, value); + } else if (key == "cache_control") { + res.set(http::field::cache_control, value); } else throw std::runtime_error("Unsupported response field: "s + key); } |