blob: d04fd939fd30932868034f6f547a5d3630b23e3d [file] [log] [blame]
Ed Tanous9bd21fc2018-04-26 16:08:56 -07001#pragma once
Ed Tanous04e438c2020-10-03 08:06:26 -07002#include "http_request.hpp"
Tanousf00032d2018-11-05 01:18:10 -03003
Gunnar Mills1214b7e2020-06-04 10:11:30 -05004#include <boost/algorithm/string.hpp>
5
Ed Tanous1abe55e2018-09-05 08:30:59 -07006namespace http_helpers
7{
George Liuaf61db12021-03-08 19:36:32 +08008inline std::string parseAccept(const crow::Request& req)
9{
10 std::string_view acceptHeader = req.getHeaderValue("Accept");
11 // The iterators in boost/http/rfc7230.hpp end the string if '/' is found,
12 // so replace it with arbitrary character '|' which is not part of the
13 // Accept header syntax.
14 return boost::replace_all_copy(std::string(acceptHeader), "/", "|");
15}
16
Ed Tanous1abe55e2018-09-05 08:30:59 -070017inline bool requestPrefersHtml(const crow::Request& req)
18{
George Liuaf61db12021-03-08 19:36:32 +080019 for (const auto& param : boost::beast::http::ext_list{parseAccept(req)})
Ed Tanous1abe55e2018-09-05 08:30:59 -070020 {
George Liuaf61db12021-03-08 19:36:32 +080021 if (param.first == "text|html")
Ed Tanous1abe55e2018-09-05 08:30:59 -070022 {
23 return true;
24 }
George Liuaf61db12021-03-08 19:36:32 +080025 if (param.first == "application|json")
Ed Tanous1abe55e2018-09-05 08:30:59 -070026 {
27 return false;
28 }
Ed Tanous9bd21fc2018-04-26 16:08:56 -070029 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070030 return false;
Ed Tanous9bd21fc2018-04-26 16:08:56 -070031}
Ed Tanous6b5e77d2018-11-16 14:52:56 -080032
George Liuaf61db12021-03-08 19:36:32 +080033inline bool isOctetAccepted(const crow::Request& req)
34{
35 for (const auto& param : boost::beast::http::ext_list{parseAccept(req)})
36 {
37 if (param.first == "*|*" || param.first == "application|octet-stream")
38 {
39 return true;
40 }
41 }
42 return false;
43}
44
Ed Tanous39e77502019-03-04 17:35:53 -080045inline std::string urlEncode(const std::string_view value)
Ed Tanous6b5e77d2018-11-16 14:52:56 -080046{
47 std::ostringstream escaped;
48 escaped.fill('0');
49 escaped << std::hex;
50
51 for (const char c : value)
52 {
53 // Keep alphanumeric and other accepted characters intact
54 if (isalnum(c) || c == '-' || c == '_' || c == '.' || c == '~')
55 {
56 escaped << c;
57 continue;
58 }
59
60 // Any other characters are percent-encoded
61 escaped << std::uppercase;
62 escaped << '%' << std::setw(2)
63 << static_cast<int>(static_cast<unsigned char>(c));
64 escaped << std::nouppercase;
65 }
66
67 return escaped.str();
68}
Ed Tanous23a21a12020-07-25 04:45:05 +000069} // namespace http_helpers