23 #include "static_processor.h"
25 #include <core/exception.h>
26 #include <core/exceptions/software.h>
27 #include <core/exceptions/system.h>
28 #include <logging/logger.h>
29 #include <webview/error_reply.h>
30 #include <webview/file_reply.h>
31 #include <webview/url_manager.h>
33 #include <boost/filesystem.hpp>
60 const std::string & base_url,
61 std::vector<std::string> &htdocs_dirs,
62 const std::string &catchall_file,
63 const std::string &mime_file,
65 : logger_(logger), url_manager_(url_manager), base_url_(base_url), catchall_file_(catchall_file)
67 if (htdocs_dirs.empty()) {
68 throw Exception(errno,
"htdocs_dirs is empty");
70 for (
const auto &h : htdocs_dirs) {
71 char htdocs_rp[PATH_MAX];
72 if (realpath(h.c_str(), htdocs_rp) != NULL) {
73 htdocs_dirs_.push_back(htdocs_rp);
75 throw Exception(errno,
"Failed to resolve htdocs path '%s'", h.c_str());
81 read_mime_database(mime_file);
85 std::bind(&WebviewStaticRequestProcessor::process_request,
87 std::placeholders::_1),
90 if (catchall_file_ !=
"") {
93 std::bind(&WebviewStaticRequestProcessor::process_request,
95 std::placeholders::_1),
103 url_manager_->
remove_handler(WebRequest::METHOD_GET, base_url_ +
"{file+}");
104 if (catchall_file_ !=
"") {
105 url_manager_->
remove_handler(WebRequest::METHOD_GET, base_url_ +
"?");
110 WebviewStaticRequestProcessor::read_mime_database(
const std::string &mime_file)
112 std::regex words_regex(
"[^\\s]+");
114 mime_types_[
"unknown"] =
"";
116 std::ifstream f(mime_file);
117 for (std::string line; std::getline(f, line);) {
121 auto words_begin = std::sregex_iterator(line.begin(), line.end(), words_regex);
122 auto words_end = std::sregex_iterator();
123 if (words_begin == words_end)
126 std::string mime_type = words_begin->str();
127 for (std::sregex_iterator i = ++words_begin; i != words_end; ++i) {
128 mime_types_[i->str()] = mime_type;
132 "Read %zu mime types from '%s'",
138 WebviewStaticRequestProcessor::get_mime_type(
const std::string &file_name)
140 std::string::size_type dot_pos = file_name.rfind(
".");
141 if (dot_pos == std::string::npos) {
142 return mime_types_[
"unknown"];
144 const auto &m = mime_types_.find(file_name.substr(dot_pos + 1));
145 if (m != mime_types_.end()) {
148 return mime_types_[
"unknown"];
153 WebviewStaticRequestProcessor::find_file(
const std::string &filename)
155 for (
const auto &h : htdocs_dirs_) {
156 std::string file_path = h + filename;
158 char * realfile = realpath(file_path.c_str(), rf);
161 if (boost::filesystem::is_directory(realfile))
164 if (strncmp(realfile, h.c_str(), h.length()) == 0) {
165 if (access(realfile, R_OK) == 0) {
188 std::string filename = find_file(
"/" + request->
path_arg(
"file"));
194 "Cannot fulfill request for file %s: %s",
195 request->
url().c_str(),
202 "Access denied for %s: %s",
203 request->
url().c_str(),
208 "Failed to serve %s: %s",
209 request->
url().c_str(),
213 std::string catchall_file;
215 catchall_file = find_file(
"/" + catchall_file_);
219 if (catchall_file.empty()) {
220 if (catchall_file_.empty()) {
224 "File not found. <i>Frontend not deployed?</i>");
233 "Failed to serve catchall file: %s",
~WebviewStaticRequestProcessor()
Destructor.
WebviewStaticRequestProcessor(fawkes::WebUrlManager *url_manager, const std::string &base_url, std::vector< std::string > &htdocs_dir, const std::string &catchall_file, const std::string &mime_file, fawkes::Logger *logger)
Constructor.
File could not be opened.
Dynamic raw file transfer reply.
Base class for exceptions in Fawkes.
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
Expected parameter is missing.
virtual void log_debug(const char *component, const char *format,...)=0
Log debug message.
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
Web request meta data carrier.
const std::string & url() const
Get URL.
std::string path_arg(const std::string &what) const
Get a path argument.
void remove_handler(WebRequest::Method method, const std::string &path)
Remove a request processor.
void add_handler(WebRequest::Method method, const std::string &path, Handler handler)
Add a request processor.
Fawkes library namespace.