summaryrefslogtreecommitdiffhomepage
path: root/response.cpp
blob: 507b2d700233a91516e2d1d6cbf0aa555451fa63 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "response.h"
#include "file.h"

#include <functional>

using namespace std::placeholders;

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;
}

namespace {

std::string GetServerParam(const std::string& key, Server& server)
{
 return "";
}

std::string GetRequestParam(const std::string& key, http::request<http::string_body>& req)
{
 return "";
}

void SetResponseHeader(const std::string& key, const std::string& value)
{
}

}

std::string generate_response(http::request<http::string_body>& req, http::response<http::string_body>& res, Server& server)
{
#if 0
 std::string host{req["host"]}; // TODO: just use string_view
 std::string target{req.target()};
 std::string plugin_name { server.GetConfig().GetPlugin(server.GetSocket(), host, target)};
 plugin_type plugin{server.GetPlugin(plugin_name)};

 auto GetServerParamFunction {std::function<std::string(const std::string& key)>(std::bind(GetServerParam, _1, std::ref(server)))};
 auto GetRequestParamFunction {std::function<std::string(const std::string& key)>(std::bind(GetRequestParam, _1, req))};
 auto SetResponseHeaderFunction{std::function<void(const std::string& key, const std::string& value)>(SetResponseHeader)};
 
 return plugin->generate_page(GetServerParamFunction, GetRequestParamFunction, SetResponseHeaderFunction);

#else
 // 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(server.GetConfig().DocRoot(server.GetSocket(), 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;
#endif
}