blob: 78368f6031bf3dbacdb6a7954a425df78c10ff0b (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
#include "response.h"
#include "file.h"
namespace {
// 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;
}
}
http_exception::http_exception(std::string message): m_message(message)
{
}
const char* http_exception::what() const noexcept
{
return m_message.data();
}
bad_request_exception::bad_request_exception(std::string message): http_exception(message)
{
}
not_found_exception::not_found_exception(std::string message): http_exception(message)
{
}
server_error_exception::server_error_exception(std::string message): http_exception(message)
{
}
std::string extend_index_html(std::string path)
{
if (path.size() && path.back() == '/')
path.append("index.html");
return path;
}
std::string generate_response(http::request<http::string_body>& req, const Config& config, const Socket& socket)
{
// Make sure we can handle the method
if( req.method() != http::verb::get &&
req.method() != http::verb::head)
throw bad_request_exception("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)
throw bad_request_exception("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), extend_index_html(std::string(req.target())));
std::string result;
try {
result = File::getFile(path);
} catch (const std::runtime_error& ex) {
throw not_found_exception(std::string(req.target()));
} catch (const std::exception& ex) {
throw server_error_exception(ex.what());
}
return result;
}
|