Malloy
Toggle main menu visibility
Loading...
Searching...
No Matches
lib
malloy
server
routing
endpoint_http_regex.hpp
1
#pragma once
2
3
#include "endpoint_http.hpp"
4
#include "type_traits.hpp"
5
#include "../../core/http/response.hpp"
6
#include "../../core/type_traits.hpp"
7
8
#include <functional>
9
#include <regex>
10
#include <cassert>
11
12
namespace
malloy::server
13
{
14
struct
resource_matcher
15
{
16
[[nodiscard]]
17
virtual
18
bool
19
matches_resource(
const
boost::beast::http::request_header<>& req)
const
= 0;
20
};
21
22
template
<
typename
Response, concepts::request_filter Handler,
bool
WantsCapture>
23
class
endpoint_http_regex
:
24
public
endpoint_http,
public
resource_matcher
25
{
26
public
:
27
template
<
typename
Derived>
28
using
req_gen_t = std::shared_ptr<typename http::connection<Derived>::request_generator>;
29
30
template
<
typename
Req>
31
using
handler_t = std::conditional_t<
32
WantsCapture,
33
std::function<Response(
const
Req&,
const
std::vector<std::string>&)>,
34
std::function<Response(
const
Req&)>
35
>;
36
37
38
Handler filter;
39
std::regex resource_base;
40
handler_t<typename Handler::request_type> handler;
41
std::function<void(
const
boost::beast::http::request_header<>&, Response&&,
const
http::connection_t&)> writer;
42
43
[[nodiscard]]
44
bool
45
matches_resource(
const
req_header_t& req)
const override
46
{
47
48
return
std::regex_match(req.target().begin(), req.target().end(), resource_base);
49
}
50
51
[[nodiscard]]
52
bool
53
matches
(
const
req_header_t& req)
const override
54
{
55
// Resource
56
if
(!matches_resource(req))
57
return
false
;
58
59
// Base class
60
return
endpoint_http::matches
(req);
61
}
62
63
64
[[nodiscard]]
65
handle_retr
66
handle
(
const
req_t& gens,
const
http::connection_t& conn)
const override
67
{
68
if
(handler) {
69
std::visit(
70
[
this
, conn]<
typename
Generator>(Generator && gen) {
71
this->visit_bodies(std::forward<Generator>(gen), conn);
72
},
73
gens
74
);
75
76
return
std::nullopt;
77
}
78
else
79
return
malloy::http::generator::server_error
(
"no valid handler available."
);
80
}
81
private
:
82
void
83
handle_req(
const
auto
& req,
const
http::connection_t& conn)
const
84
{
85
if
constexpr
(WantsCapture) {
86
std::smatch url_matches;
87
std::string url{ req.target() };
88
std::regex_match(url, url_matches, resource_base);
89
90
if
(url_matches.empty()) {
91
throw
std::logic_error{
92
R
"(endpoint_http_regex passed request which does not match: )" +
93
std::string{req.target()} };
94
}
95
96
std::vector<std::string>
matches
{
// match_results[0] is the
97
// input
98
// string
99
url_matches.begin() + 1,
100
url_matches.end() };
101
102
writer(req, handler(req,
matches
), conn);
103
}
104
else
105
writer(req, handler(req), conn);
106
}
107
108
void
109
visit_bodies(
const
auto
& gen,
const
http::connection_t& conn)
const
110
{
111
using
body_t =
typename
Handler::request_type::body_type;
112
gen->template body<body_t>(
113
[
this
, conn](
const
auto
& req) {
114
this->handle_req(req, conn);
115
}, [&gen,
this
](
auto
& body) { filter.setup_body(gen->header(), body); });
116
}
117
};
118
119
}
malloy::http::generator::server_error
static response server_error(std::string_view what)
Definition
generator.cpp:47
malloy::server::endpoint_http_regex
Definition
endpoint_http_regex.hpp:25
malloy::server::endpoint_http_regex::matches
bool matches(const req_header_t &req) const override
Definition
endpoint_http_regex.hpp:53
malloy::server::endpoint_http_regex::handle
handle_retr handle(const req_t &gens, const http::connection_t &conn) const override
Definition
endpoint_http_regex.hpp:66
malloy::server::endpoint_http::matches
virtual bool matches(const req_header_t &req) const
Definition
endpoint_http.hpp:54
malloy::server::resource_matcher
Definition
endpoint_http_regex.hpp:15
Generated by
1.18.0