|
|
@ -42,7 +42,7 @@ static beast::string_view mime_type(beast::string_view path) |
|
|
|
if(iequals(ext, ".tif")) return "image/tiff"; |
|
|
|
if(iequals(ext, ".svg")) return "image/svg+xml"; |
|
|
|
if(iequals(ext, ".svgz")) return "image/svg+xml"; |
|
|
|
return ""; |
|
|
|
return "application/octet-stream"; |
|
|
|
} |
|
|
|
|
|
|
|
static void fail(beast::error_code ec, char const* what) |
|
|
@ -61,22 +61,16 @@ void Webserver::remove_url_handler(std::string url_regex) { |
|
|
|
_urls.erase(url_regex); |
|
|
|
} |
|
|
|
|
|
|
|
void Webserver::deliver405(tcp::socket *socket, Webserver::request req) |
|
|
|
void Webserver::deliver_status(tcp::socket *socket, Webserver::request req, http::status status) |
|
|
|
{ |
|
|
|
http::response< http::string_body > res{http::status::method_not_allowed, req.version()}; |
|
|
|
http::response< http::string_body > res{status, req.version()}; |
|
|
|
res.set(http::field::content_type, "text/html"); |
|
|
|
res.body() = "<html><body>404 not found</body></html>"; |
|
|
|
res.keep_alive(req.keep_alive()); |
|
|
|
res.prepare_payload(); |
|
|
|
} |
|
|
|
|
|
|
|
void Webserver::deliver404(tcp::socket *socket, Webserver::request req) |
|
|
|
{ |
|
|
|
http::response< http::string_body > res{http::status::not_found, req.version()}; |
|
|
|
res.set(http::field::content_type, "text/html"); |
|
|
|
res.body() = "<html><body>404 not found</body></html>"; |
|
|
|
res.keep_alive(req.keep_alive()); |
|
|
|
res.prepare_payload(); |
|
|
|
if (status != http::status::internal_server_error) |
|
|
|
res.keep_alive(req.keep_alive()); |
|
|
|
beast::error_code ec; |
|
|
|
http::write(*socket, res, ec); |
|
|
|
} |
|
|
|
|
|
|
|
void Webserver::deliver_file(tcp::socket *socket, Webserver::request req) |
|
|
@ -86,9 +80,30 @@ void Webserver::deliver_file(tcp::socket *socket, Webserver::request req) |
|
|
|
if (boost::regex_match(req.target().data(), m, file)) { |
|
|
|
fs::path p{_doc_root}; |
|
|
|
p += m[1]; |
|
|
|
|
|
|
|
beast::error_code ec; |
|
|
|
http::file_body::value_type body; |
|
|
|
body.open(p.c_str(), beast::file_mode::scan, ec); |
|
|
|
if (ec == beast::errc::no_such_file_or_directory) { |
|
|
|
deliver_status(socket, req, http::status::not_found); |
|
|
|
} |
|
|
|
else if (ec) { |
|
|
|
deliver_status(socket, req, http::status::internal_server_error); |
|
|
|
} |
|
|
|
else { |
|
|
|
auto const size = body.size(); |
|
|
|
http::response<http::file_body> res{ |
|
|
|
std::piecewise_construct, |
|
|
|
std::make_tuple(std::move(body)), |
|
|
|
std::make_tuple(http::status::ok, req.version())}; |
|
|
|
res.set(http::field::content_type, mime_type(p.c_str())); |
|
|
|
res.content_length(size); |
|
|
|
res.keep_alive(req.keep_alive()); |
|
|
|
http::write(*socket, res, ec); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
deliver404(socket, req); |
|
|
|
deliver_status(socket, req, http::status::not_found); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -123,26 +138,17 @@ void Webserver::do_session(tcp::socket *socket) |
|
|
|
switch (req.method()) { |
|
|
|
case http::verb::post: { |
|
|
|
boost::cmatch m; |
|
|
|
Webserver::response *res = nullptr; |
|
|
|
Webserver::handler_t handler = find_handler(req, m); |
|
|
|
|
|
|
|
if (handler) { |
|
|
|
res = handler(m, req); |
|
|
|
if (res) { |
|
|
|
res->prepare_payload(); |
|
|
|
http::write(*socket, *res, ec); |
|
|
|
delete res; |
|
|
|
if (ec) { |
|
|
|
delete socket; |
|
|
|
return fail(ec, "writing to stream"); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
deliver404(socket, req); |
|
|
|
} |
|
|
|
Webserver::response *res = handler(m, req); |
|
|
|
if (!res) |
|
|
|
deliver_status(socket, req, http::status::not_found); |
|
|
|
http::write(*socket, *res, ec); |
|
|
|
delete res; |
|
|
|
} |
|
|
|
else { |
|
|
|
deliver404(socket, req); |
|
|
|
deliver_status(socket, req, http::status::not_found); |
|
|
|
} |
|
|
|
} |
|
|
|
break; |
|
|
@ -152,8 +158,13 @@ void Webserver::do_session(tcp::socket *socket) |
|
|
|
break; |
|
|
|
|
|
|
|
default: |
|
|
|
deliver405(socket, req); |
|
|
|
deliver_status(socket, req, http::status::method_not_allowed); |
|
|
|
}; |
|
|
|
|
|
|
|
if (ec) { |
|
|
|
delete socket; |
|
|
|
return fail(ec, "writing to stream"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
socket->shutdown(tcp::socket::shutdown_send, ec); |
|
|
|