blob: c150943f8f9797ec7db96f495630593565ffaf7b [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
Ed Tanous11ba3972022-07-11 09:50:41 -07004#include <boost/algorithm/string/classification.hpp>
5#include <boost/algorithm/string/split.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -05006
Ed Tanous1abe55e2018-09-05 08:30:59 -07007namespace http_helpers
8{
George Liu647b3cd2021-07-05 12:43:56 +08009inline std::vector<std::string> parseAccept(std::string_view header)
Ed Tanous1abe55e2018-09-05 08:30:59 -070010{
Ed Tanous753d0342021-07-01 07:57:30 -070011 std::vector<std::string> encodings;
12 // chrome currently sends 6 accepts headers, firefox sends 4.
13 encodings.reserve(6);
14 boost::split(encodings, header, boost::is_any_of(", "),
15 boost::token_compress_on);
George Liu647b3cd2021-07-05 12:43:56 +080016
17 return encodings;
18}
19
20inline bool requestPrefersHtml(std::string_view header)
21{
22 for (const std::string& encoding : parseAccept(header))
Ed Tanous1abe55e2018-09-05 08:30:59 -070023 {
Ed Tanous753d0342021-07-01 07:57:30 -070024 if (encoding == "text/html")
Ed Tanous1abe55e2018-09-05 08:30:59 -070025 {
26 return true;
27 }
Ed Tanous753d0342021-07-01 07:57:30 -070028 if (encoding == "application/json")
Ed Tanous1abe55e2018-09-05 08:30:59 -070029 {
30 return false;
31 }
Ed Tanous9bd21fc2018-04-26 16:08:56 -070032 }
Ed Tanous1abe55e2018-09-05 08:30:59 -070033 return false;
Ed Tanous9bd21fc2018-04-26 16:08:56 -070034}
Ed Tanous6b5e77d2018-11-16 14:52:56 -080035
George Liu647b3cd2021-07-05 12:43:56 +080036inline bool isOctetAccepted(std::string_view header)
37{
38 for (const std::string& encoding : parseAccept(header))
39 {
40 if (encoding == "*/*" || encoding == "application/octet-stream")
41 {
42 return true;
43 }
44 }
45 return false;
46}
47
Ed Tanous39e77502019-03-04 17:35:53 -080048inline std::string urlEncode(const std::string_view value)
Ed Tanous6b5e77d2018-11-16 14:52:56 -080049{
50 std::ostringstream escaped;
51 escaped.fill('0');
52 escaped << std::hex;
53
54 for (const char c : value)
55 {
56 // Keep alphanumeric and other accepted characters intact
Ed Tanouse662eae2022-01-25 10:39:19 -080057 if ((isalnum(c) != 0) || c == '-' || c == '_' || c == '.' || c == '~')
Ed Tanous6b5e77d2018-11-16 14:52:56 -080058 {
59 escaped << c;
60 continue;
61 }
62
63 // Any other characters are percent-encoded
64 escaped << std::uppercase;
65 escaped << '%' << std::setw(2)
66 << static_cast<int>(static_cast<unsigned char>(c));
67 escaped << std::nouppercase;
68 }
69
70 return escaped.str();
71}
Ed Tanous23a21a12020-07-25 04:45:05 +000072} // namespace http_helpers