14 #include <boost/xpressive/xpressive.hpp>
15 #include <boost/archive/iterators/binary_from_base64.hpp>
16 #include <boost/archive/iterators/base64_from_binary.hpp>
17 #include <boost/archive/iterators/transform_width.hpp>
18 #include <boost/algorithm/string.hpp>
20 #include "xxhrtypes.hpp"
26 inline Header parseHeader(
const std::string& headers);
27 inline size_t writeFunction(
void* ptr,
size_t size,
size_t nmemb, std::string* data);
28 inline std::vector<std::string> split(
const std::string& to_split,
char delimiter);
33 inline std::string urlEncode(
const std::string& response);
34 inline std::string decode64(
const std::string &val);
35 inline std::string encode64(
const std::string &val);
55 std::string parameters;
62 return protocol ==
"https";
67 inline url_parts parse_url(
const std::string &url);
80 inline Header parseHeader(
const std::string& headers) {
82 std::vector<std::string> lines;
83 std::istringstream stream(headers);
86 while (std::getline(stream, line,
'\n')) {
87 lines.push_back(line);
91 for (
auto& line : lines) {
92 if (line.substr(0, 5) ==
"HTTP/") {
96 if (line.length() > 0) {
97 auto found = line.find(
":");
98 if (found != std::string::npos) {
99 auto value = line.substr(found + 2, line.length() - 1);
100 if (value.back() ==
'\r') {
101 value = value.substr(0, value.length() - 1);
103 header[line.substr(0, found)] = value;
111 std::vector<std::string> split(
const std::string& to_split,
char delimiter) {
112 std::vector<std::string> tokens;
114 std::stringstream stream(to_split);
116 while (std::getline(stream, item, delimiter)) {
117 tokens.push_back(item);
123 inline size_t writeFunction(
void* ptr,
size_t size,
size_t nmemb, std::string* data) {
124 data->append((
char*) ptr, size * nmemb);
128 inline std::string urlEncode(
const std::string& value) {
129 std::ostringstream escaped;
133 for (
auto i = value.cbegin(), n = value.cend(); i != n; ++i) {
134 std::string::value_type c = (*i);
136 if (std::isalnum(c) || c ==
'-' || c ==
'_' || c ==
'.' || c ==
'~') {
141 escaped <<
'%' << std::setw(2) << std::int32_t((
unsigned char) c);
144 return escaped.str();
147 inline std::string urlDecode(
const std::string& str){
150 int i, ii, len = str.length();
152 for (i=0; i < len; i++){
159 sscanf(str.substr(i + 1, 2).c_str(),
"%x", &ii);
160 ch =
static_cast<char>(ii);
168 inline std::string decode64(
const std::string &val) {
169 using namespace boost::archive::iterators;
170 using It = transform_width<binary_from_base64<std::string::const_iterator>, 8, 6>;
171 return boost::algorithm::trim_right_copy_if(std::string(It(std::begin(val)), It(std::end(val))), [](
char c) {
176 inline std::string encode64(
const std::string &val) {
177 using namespace boost::archive::iterators;
178 using It = base64_from_binary<transform_width<std::string::const_iterator, 6, 8>>;
179 auto tmp = std::string(It(std::begin(val)), It(std::end(val)));
180 return tmp.append((3 - val.size() % 3) % 3,
'=');
184 const boost::xpressive::sregex url_regex =
185 boost::xpressive::sregex::compile(
"(http|https)://([^/ :]+):?([^/ ]*)(/?[^ #?]*)\\x3f?([^ #]*)#?([^ ]*)");
187 inline url_parts parse_url(
const std::string &url) {
194 using namespace boost::xpressive;
196 if( regex_match( url, what, url_regex ) ) {
198 ret.protocol = what[1];
202 if (ret.port.empty()) {
203 ret.port = (ret.protocol ==
"https") ?
"443" :
"80";
207 ret.parameters = what[5];
208 ret.fragment = what[6];