#include "StaticFiles.hpp" #include #include #include namespace molo::example::fw { bool path_is_safe(const std::string& request_path) { if (request_path.find("..") != std::string::npos) return false; if (request_path.find('\\') != std::string::npos) return false; if (request_path.empty() || request_path.front() != '/') return false; return true; } namespace { std::string content_type_for(const std::string& name) { auto ends = [&](const char* ext) { std::string e(ext); return name.size() >= e.size() && name.compare(name.size() - e.size(), e.size(), e) == 0; }; if (ends(".html")) return "text/html; charset=utf-8"; if (ends(".css")) return "text/css; charset=utf-8"; if (ends(".js")) return "text/javascript; charset=utf-8"; if (ends(".json")) return "application/json"; if (ends(".svg")) return "image/svg+xml"; if (ends(".png")) return "image/png"; return "application/octet-stream"; } } // namespace std::string etag_for(const std::string& body) { unsigned long long h = 1469598103934665603ULL; for (unsigned char c : body) { h ^= c; h *= 1099511628211ULL; } char buf[32]; std::snprintf(buf, sizeof(buf), "\"%llx-%zu\"", (unsigned long long)h, body.size()); return buf; } Response serve_disk_file(const std::string& root, const std::string& subpath) { std::string full = "/" + subpath; if (!path_is_safe(full)) return TextResponse("unsafe path", 403); std::ifstream in(root + full, std::ios::binary); if (!in) return TextResponse("not found", 404); std::ostringstream ss; ss << in.rdbuf(); Response res(200, ss.str(), content_type_for(full)); res.headers.set("ETag", etag_for(res.body)); res.headers.set("Cache-Control", "public, max-age=3600"); return res; } Response serve_embedded(const std::map& assets, const std::string& subpath) { std::string full = "/" + subpath; if (!path_is_safe(full)) return TextResponse("unsafe path", 403); auto it = assets.find(full); if (it == assets.end()) return TextResponse("not found", 404); Response res(200, it->second, content_type_for(full)); res.headers.set("ETag", etag_for(res.body)); res.headers.set("Cache-Control", "public, max-age=3600"); res.headers.set("X-Asset-Source", "embedded"); return res; } } // namespace molo::example::fw