summaryrefslogtreecommitdiffhomepage
path: root/http.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-04-05 19:15:25 +0200
committerRoland Reichwein <mail@reichwein.it>2020-04-05 19:15:25 +0200
commit917d4574153fa57ea43e7410006f58aa5b1bbb0b (patch)
tree3d4535370f596a46740a434319e73daf7f2704ba /http.cpp
parentddc02ba7a6cc92d07cf073395b2d41347a8d35fb (diff)
Separate out response handling
Diffstat (limited to 'http.cpp')
-rw-r--r--http.cpp94
1 files changed, 16 insertions, 78 deletions
diff --git a/http.cpp b/http.cpp
index 2203ffe..eeff552 100644
--- a/http.cpp
+++ b/http.cpp
@@ -1,6 +1,7 @@
#include "http.h"
#include "server.h"
+#include "response.h"
#include <boost/beast/version.hpp>
#include <boost/beast/core.hpp>
@@ -61,33 +62,6 @@ mime_type(beast::string_view path)
return "application/text";
}
-// Append an HTTP rel-path to a local filesystem path.
-// The returned path is normalized for the platform.
-std::string
-path_cat(
- beast::string_view base,
- beast::string_view path)
-{
- if(base.empty())
- return std::string(path);
- std::string result(base);
-#ifdef BOOST_MSVC
- char constexpr path_separator = '\\';
- if(result.back() == path_separator)
- result.resize(result.size() - 1);
- result.append(path.data(), path.size());
- for(auto& c : result)
- if(c == '/')
- c = path_separator;
-#else
- char constexpr path_separator = '/';
- if(result.back() == path_separator)
- result.resize(result.size() - 1);
- result.append(path.data(), path.size());
-#endif
- return result;
-}
-
// This function produces an HTTP response for the given
// request. The type of the response object depends on the
// contents of the request, so the interface requires the
@@ -141,60 +115,24 @@ handle_request(
return res;
};
- // Make sure we can handle the method
- if( req.method() != http::verb::get &&
- req.method() != http::verb::head)
- return send(bad_request("Unknown HTTP-method"));
-
- // Request path must be absolute and not contain "..".
- if( req.target().empty() ||
- req.target()[0] != '/' ||
- req.target().find("..") != beast::string_view::npos)
- return send(bad_request("Illegal request-target"));
-
- // Build the path to the requested file
- std::string host{req["host"]}; // TODO: just use string_view
- std::string target{req.target()};
- std::string path = path_cat(config.DocRoot(socket, host, target), req.target());
- if(req.target().back() == '/')
- path.append("index.html");
-
- // Attempt to open the file
- beast::error_code ec;
- http::file_body::value_type body;
- body.open(path.c_str(), beast::file_mode::scan, ec);
-
- // Handle the case where the file doesn't exist
- if(ec == beast::errc::no_such_file_or_directory)
- return send(not_found(req.target()));
-
- // Handle an unknown error
- if(ec)
- return send(server_error(ec.message()));
-
- // Cache the size since we need it after the move
- auto const size = body.size();
-
- // Respond to HEAD request
- if(req.method() == http::verb::head)
- {
- http::response<http::empty_body> res{http::status::ok, req.version()};
- res.set(http::field::server, VersionString);
- res.set(http::field::content_type, mime_type(path));
- res.content_length(size);
- res.keep_alive(req.keep_alive());
- return send(std::move(res));
+ std::string res_data;
+ try {
+ res_data = generate_response(req, config, socket);
+ } catch(const bad_request_exception& ex) {
+ return send(bad_request(ex.what()));
+ } catch(const not_found_exception& ex) {
+ return send(not_found(ex.what()));
+ } catch(const server_error_exception& ex) {
+ return send(server_error(ex.what()));
}
-
- // Respond to GET request
- http::response<http::file_body> res{
- std::piecewise_construct,
- std::make_tuple(std::move(body)),
- std::make_tuple(http::status::ok, req.version())};
+
+ http::response<http::string_body> res{http::status::ok, req.version()};
res.set(http::field::server, VersionString);
- res.set(http::field::content_type, mime_type(path));
- res.content_length(size);
+ res.set(http::field::content_type, mime_type(extend_index_html(std::string(req.target()))));
+ res.content_length(res_data.size());
res.keep_alive(req.keep_alive());
+ if (req.method() != http::verb::head)
+ res.body() = res_data;
return send(std::move(res));
}