-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathurl.cpp
More file actions
32 lines (28 loc) · 1.2 KB
/
url.cpp
File metadata and controls
32 lines (28 loc) · 1.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "expresscpp/url.hpp"
#include <regex>
#include <string>
#include "boost/algorithm/string.hpp"
namespace expresscpp {
ParsedURI parseURI(const std::string& url) {
ParsedURI result;
auto value_or = [](const std::string& value, std::string&& deflt) -> std::string {
return (value.empty() ? deflt : value);
};
// Note: only "http", "https", "ws", and "wss" protocols are supported
static const std::regex PARSE_URL{R"((([httpsw]{2,5})://)?([^/ :]+)(:(\d+))?(/([^ ?]+)?)?/?\??([^/ ]+\=[^/ ]+)?)",
std::regex_constants::ECMAScript | std::regex_constants::icase};
std::smatch match;
if (std::regex_match(url, match, PARSE_URL) && match.size() == 9) {
result.protocol = value_or(boost::algorithm::to_lower_copy(std::string(match[2])), "http");
result.domain = match[3];
const bool is_sequre_protocol = (result.protocol == "https" || result.protocol == "wss");
result.port = value_or(match[5], (is_sequre_protocol) ? "443" : "80");
result.resource = value_or(match[6], "/");
result.query = match[8];
if (result.domain.empty()) {
throw std::invalid_argument("domain cannot be empty");
}
}
return result;
}
} // namespace expresscpp