10#include <boost/beast/http/message.hpp>
11#include <boost/beast/http/empty_body.hpp>
12#include <boost/algorithm/string/classification.hpp>
13#include <boost/algorithm/string/constants.hpp>
14#include <boost/algorithm/string/split.hpp>
15#include <boost/algorithm/string/trim.hpp>
16#include <boost/beast/websocket/rfc6455.hpp>
17#include <boost/lexical_cast.hpp>
19#ifdef ROAR_ENABLE_NLOHMANN_JSON
20# include <nlohmann/json.hpp>
26#include <unordered_map>
37 std::unordered_map<std::string, std::string>
query_;
48 template <
typename BodyT>
58 :
boost::beast::http::request<BodyT>{}
68 :
boost::beast::http::request<BodyT>{std::move(req)}
80 :
boost::beast::http::request<BodyT>{std::move(req)}
109 this->set(boost::beast::http::field::host,
host_);
115 this->set(boost::beast::http::field::host,
host_);
121 this->set(boost::beast::http::field::host,
host_);
127 this->set(boost::beast::http::field::host,
host_);
167 this->set(field, std::move(value));
207 template <
typename FieldT>
210 std::vector<std::string> splitList;
211 boost::algorithm::split(
213 std::string{this->at(std::forward<FieldT>(field))},
214 boost::algorithm::is_any_of(
","),
215 boost::algorithm::token_compress_on);
217 for (
auto& element : splitList)
218 boost::algorithm::trim(element);
231 return boost::beast::websocket::is_upgrade(*
this);
234#ifdef ROAR_ENABLE_NLOHMANN_JSON
241 template <
typename Body = BodyT>
242 std::enable_if_t<std::is_same_v<Body, boost::beast::http::string_body>, nlohmann::json> json()
const
244 return nlohmann::json::parse(this->body());
247 template <
typename Body = BodyT>
248 std::enable_if_t<std::is_same_v<Body, boost::beast::http::string_body>, Request<BodyT>&>
249 json(nlohmann::json
const& j,
int indent = -1)
251 this->body() = j.dump(indent);
252 this->set(boost::beast::http::field::content_type,
"application/json");
253 this->prepare_payload();
266 .path_ = std::move(
path_),
267 .query_ = std::move(
query_),
268 .host_ = std::move(
host_),
269 .port_ = std::move(
port_)};
280 auto iter = this->find(boost::beast::http::field::expect);
281 if (iter == std::end(*
this))
284 return iter->value() ==
"100-continue";
295 this->set(boost::beast::http::field::expect,
"100-continue");
297 this->erase(boost::beast::http::field::expect);
311 return boost::lexical_cast<std::size_t>(
contentLength->value());
321 this->set(boost::beast::http::field::content_length, std::to_string(length));
331 auto iter = this->find(boost::beast::http::field::range);
332 if (iter == std::end(*
this))
342 auto iter = this->find(boost::beast::http::field::authorization);
343 if (iter == std::end(*
this))
345 auto spacePos = iter->value().find(
' ');
346 if (spacePos == std::string::npos)
356 auto iter = this->find(boost::beast::http::field::authorization);
357 auto value = iter->value();
358 if (iter == std::end(*
this))
360 auto spacePos = value.find(
' ');
361 if (spacePos == std::string::npos)
363 if (value.substr(0, spacePos) !=
"Basic")
370 this->set(boost::beast::http::field::authorization,
"Basic " + auth.
toBase64());
379 auto iter = this->find(boost::beast::http::field::authorization);
380 auto value = iter->value();
381 if (iter == std::end(*
this))
383 auto spacePos = value.find(
' ');
384 if (spacePos == std::string::npos)
386 if (value.substr(0, spacePos) !=
"Digest")
393 this->set(boost::beast::http::field::authorization,
"Digest " + auth.
toParameters());
402 auto iter = this->find(boost::beast::http::field::authorization);
403 if (iter == std::end(*
this))
405 auto spacePos = iter->value().find(
' ');
406 if (spacePos == std::string::npos)
408 if (iter->value().substr(0, spacePos) !=
"Bearer")
410 return std::string{iter->value().substr(spacePos + 1)};
415 this->set(boost::beast::http::field::authorization,
"Bearer " + token);
424 std::unordered_map<std::string, std::string>
getCookies()
const
426 auto [begin, end] = this->equal_range(boost::beast::http::field::cookie);
427 std::unordered_map<std::string, std::string> cookies;
428 for (; begin != end; ++begin)
440 auto queryPos =
path.find_last_of(
'?');
441 if (queryPos != std::string::npos)
444 path.erase(queryPos);
456 std::unordered_map<std::string, std::string>
parseQuery(std::string_view queryString)
const
458 std::vector<std::string> splitBySeperator;
459 boost::algorithm::split(
460 splitBySeperator, queryString, boost::algorithm::is_any_of(
"&;"), boost::algorithm::token_compress_off);
462 std::unordered_map<std::string, std::string>
query;
463 for (
auto const& pair : splitBySeperator)
465 auto pos = pair.find(
'=');
466 if (pos == std::string::npos)
469 query[pair.substr(0, pos)] = pair.substr(pos + 1, pair.length() - pos - 1);
static std::unordered_map< std::string, std::string > parseCookies(std::string const &cookieHeaderEntry)
Definition cookie.cpp:33
This class extends the boost::beast::http::request<BodyT> with additional convenience.
Definition request.hpp:52
std::vector< std::string > splitCommaSeperatedHeaderEntry(FieldT &&field) const
Retrieves a header which value is a typically comma seperated list as a vector of string.
Definition request.hpp:208
bool isWebsocketUpgrade() const
Is this a websocket upgrade request?
Definition request.hpp:229
Request< BodyT > & bearerAuth(std::string const &token)
Definition request.hpp:413
std::unordered_map< std::string, std::string > getCookies() const
Gets all cookies.
Definition request.hpp:424
void parseTarget()
Extracts path and query from boost::beast::http::request::target()
Definition request.hpp:437
Request< BodyT > & port(std::string_view port)
Definition request.hpp:145
bool expectsContinue() const
Returns true if the request expects a continue response.
Definition request.hpp:278
auto const & query() const
Returns the query part of the url as an unordered_map<string, string>.
Definition request.hpp:176
Request< BodyT > & host(char const *host)
Definition request.hpp:124
std::optional< Ranges > ranges() const
Extracts the Range header.
Definition request.hpp:329
std::optional< std::size_t > contentLength() const
Returns the content length header.
Definition request.hpp:305
Request< BodyT > & host(std::string_view host)
Definition request.hpp:118
Request()
Definition request.hpp:57
Request< BodyT > & digestAuth(DigestAuth const &auth)
Definition request.hpp:391
void contentLength(std::size_t length)
Sets the content length header.
Definition request.hpp:319
Detail::RequestExtensions ejectExtensions() &&
Rips extensions out of this request object intended to be implanted into another request object.
Definition request.hpp:262
Request< BodyT > & setHeader(boost::beast::http::field field, std::string value)
Definition request.hpp:165
std::string host() const
Definition request.hpp:130
std::optional< BasicAuth > basicAuth() const
Returns a basic auth object if the authorization scheme is "Basic".
Definition request.hpp:354
Request(beast_request req)
Construct a new Request object from a beast request to upgrade it.
Definition request.hpp:67
std::string path() const
Returns only the path of the url.
Definition request.hpp:91
std::string_view target() const
Definition request.hpp:101
std::optional< AuthorizationScheme > authorizationScheme() const
Returns the authorization scheme of the Authorization header if it exists.
Definition request.hpp:340
Request< BodyT > & port(std::string &&port)
Definition request.hpp:135
std::string port() const
Definition request.hpp:160
void target(std::string_view target)
Definition request.hpp:96
Request< BodyT > & port(std::string const &port)
Definition request.hpp:140
Request< BodyT > & host(std::string &&host)
Definition request.hpp:106
Request< BodyT > & host(std::string const &host)
Definition request.hpp:112
Request< BodyT > & port(char const *port)
Definition request.hpp:155
boost::beast::http::request< BodyT > beast_request
Definition request.hpp:55
auto const & pathMatches() const
Retrieves regex matches for this request with the registered route.
Definition request.hpp:186
std::optional< DigestAuth > digestAuth() const
Returns a digest auth object with all digest auth information.
Definition request.hpp:377
Request< BodyT > & pathMatches(std::vector< std::string > &&matches)
Sets regex matches for this request with the registered route.
Definition request.hpp:196
Request< BodyT > & basicAuth(BasicAuth const &auth)
Definition request.hpp:368
void expectsContinue(bool enable)
enables/disables the expect continue header.
Definition request.hpp:292
std::optional< std::string > bearerAuth() const
Returns token data of bearer authentication method.
Definition request.hpp:400
Request(beast_request req, Detail::RequestExtensions &&extensions)
Construct a new Request object from a beast request and takes extensions of a previous request object...
Definition request.hpp:79
Request< BodyT > & port(unsigned short port)
Definition request.hpp:150
std::unordered_map< std::string, std::string > parseQuery(std::string_view queryString) const
Transforms the query part from string to map.
Definition request.hpp:456
Definition authorization.hpp:10
AuthorizationScheme authorizationSchemeFromString(std::string_view)
Definition authorization.cpp:9
Definition basic_auth.hpp:10
static std::optional< BasicAuth > fromBase64(std::string_view base64Encoded)
Definition basic_auth.cpp:7
std::string toBase64() const
Definition basic_auth.cpp:24
Definition request.hpp:34
std::string host_
Definition request.hpp:38
std::unordered_map< std::string, std::string > query_
Definition request.hpp:37
std::optional< std::vector< std::string > > regexMatches_
Definition request.hpp:35
std::string port_
Definition request.hpp:39
std::string path_
Definition request.hpp:36
Definition digest_auth.hpp:10
std::string toParameters() const
Definition digest_auth.cpp:34
static std::optional< DigestAuth > fromParameters(std::string_view parameterList)
Definition digest_auth.cpp:67
static std::optional< Ranges > fromString(std::string const &str)
Definition ranges.cpp:37