summaryrefslogtreecommitdiffhomepage
path: root/response.cpp
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2020-04-26 13:01:19 +0200
committerRoland Reichwein <mail@reichwein.it>2020-04-26 13:01:19 +0200
commitaebe139d00b44684158edb3616da5c37b12db6d1 (patch)
treef37eaa7a59523f2e7db42875e65f2ca2714c0e9d /response.cpp
parent91073ca08f5f9582196712ae6753714f3333979f (diff)
Added stats output
Diffstat (limited to 'response.cpp')
-rw-r--r--response.cpp63
1 files changed, 27 insertions, 36 deletions
diff --git a/response.cpp b/response.cpp
index c5ba426..696b859 100644
--- a/response.cpp
+++ b/response.cpp
@@ -79,10 +79,11 @@ bool is_ipv6_address(const std::string& addr)
std::unordered_map<std::string, std::function<std::string(Server&)>> GetServerParamFunctions{
// following are the supported fields:
- {"version", [](Server& server) { return Server::VersionString; }},
{"address", [](Server& server) { return server.GetSocket().address; }},
{"ipv6", [](Server& server) { return is_ipv6_address(server.GetSocket().address) ? "yes" : "no"; }},
{"port", [](Server& server) { return server.GetSocket().port; }},
+ {"statistics", [](Server& server) { return server.GetStatistics().getValues(); }},
+ {"version", [](Server& server) { return Server::VersionString; }},
};
std::string GetServerParam(const std::string& key, Server& server)
@@ -233,42 +234,34 @@ mime_type(beast::string_view path)
return "application/text";
}
-// Used to return errors by generating response page and HTTP status code
response_type HttpStatus(std::string status, std::string message, response_type& res)
{
- res.result(unsigned(stoul(status)));
- res.set(http::field::content_type, "text/html");
- if (res.result_int() == 401)
- res.set(http::field::www_authenticate, "Basic realm=\"Webbox Login\"");
- res.body() = "<html><body><h1>"s + Server::VersionString + " Error</h1><p>"s + status + " "s + message + "</p></body></html>"s;
- res.prepare_payload();
+ if (status != "200") { // already handled at res init
+ res.result(unsigned(stoul(status)));
+ res.set(http::field::content_type, "text/html");
+ if (res.result_int() == 401)
+ res.set(http::field::www_authenticate, "Basic realm=\"Webbox Login\"");
+ res.body() = "<html><body><h1>"s + Server::VersionString + " Error</h1><p>"s + status + " "s + message + "</p></body></html>"s;
+ res.prepare_payload();
+ }
return res;
}
-// Do statistics at end of response generation, handle all exit paths via RAII
-class StatisticsGuard
+// Used to return errors by generating response page and HTTP status code
+response_type HttpStatusAndStats(std::string status, std::string message, RequestContext& req_ctx, response_type& res)
{
- request_type& mReq;
- response_type& mRes;
- Server& mServer;
-public:
- StatisticsGuard(request_type& req, response_type& res, Server& server)
- : mReq(req)
- , mRes(res)
- , mServer(server)
- {
- }
+ HttpStatus(status, message, res);
- ~StatisticsGuard()
- {
- mServer.GetStatistics().count(mReq.body().size(),
- mRes.body().size(),
- mRes.result_int() == 200,
- is_ipv6_address(mServer.GetSocket().address),
- mServer.GetSocket().protocol == SocketProtocol::HTTPS);
- }
-};
+ req_ctx.GetServer().GetStatistics().count(
+ req_ctx.GetReq().body().size(),
+ res.body().size(),
+ res.result_int() != 200,
+ is_ipv6_address(req_ctx.GetServer().GetSocket().address),
+ req_ctx.GetServer().GetSocket().protocol == SocketProtocol::HTTPS);
+
+ return std::move(res);
+}
} // anonymous namespace
@@ -279,8 +272,6 @@ response_type generate_response(request_type& req, Server& server)
res.set(http::field::content_type, mime_type(extend_index_html(std::string(req.target()))));
res.keep_alive(req.keep_alive());
- StatisticsGuard statsGuard{req, res, server};
-
try {
RequestContext req_ctx{req, server}; // can throw std::out_of_range
@@ -288,21 +279,21 @@ response_type generate_response(request_type& req, Server& server)
if (auth.size() != 0) {
std::string authorization{req[http::field::authorization]};
if (authorization.substr(0, 6) != "Basic "s)
- return HttpStatus("401", "Bad Authorization Type", res);
+ return HttpStatusAndStats("401", "Bad Authorization Type", req_ctx, res);
authorization = authorization.substr(6);
authorization = decode64(authorization);
size_t pos {authorization.find(':')};
if (pos == authorization.npos)
- return HttpStatus("401", "Bad Authorization Encoding", res);
+ return HttpStatusAndStats("401", "Bad Authorization Encoding", req_ctx, res);
std::string login{authorization.substr(0, pos)};
std::string password{authorization.substr(pos + 1)};
auto it {auth.find(login)};
if (it == auth.end() || it->second != password)
- return HttpStatus("401", "Bad Authorization", res);
+ return HttpStatusAndStats("401", "Bad Authorization", req_ctx, res);
}
plugin_type plugin{req_ctx.GetPlugin()};
@@ -318,8 +309,8 @@ response_type generate_response(request_type& req, Server& server)
res.body() = res_data;
res.prepare_payload();
}
-
- return res;
+
+ return HttpStatusAndStats("200", "OK", req_ctx, res);
} catch(const std::out_of_range& ex) {
return HttpStatus("400", "Bad request: Host "s + std::string{req["host"]} + ":"s + std::string{req.target()} + " unknown"s, res);
} catch(const std::exception& ex) {