87 static const std::regex re(R"(^(?:un://)([^/?#]+)(/[^?#]*)?(\?[^#]*)?(?:#.*)?$)", std::regex::ECMAScript | std::regex::icase);
89 auto pct_decode = [](std::string_view s) -> std::string {
91 out.reserve(s.size());
92 for (size_t i = 0; i < s.size(); ++i) {
93 if (s[i] ==
'%' && i + 2 < s.size()) {
94 auto hex = [](
char c) ->
int {
95 if (c >=
'0' && c <=
'9') {
99 if (c >=
'a' && c <=
'f') {
100 return 10 + (c -
'a');
104 const int h = hex(s[i + 1]);
105 const int l = hex(s[i + 2]);
106 if (h >= 0 && l >= 0) {
107 out.push_back(
static_cast<
char>((h << 4) | l));
118 if (std::regex_match(url, match, re)) {
125 const std::string sockToken = match[1].str();
126 std::string socketPath = pct_decode(sockToken);
128 if ((!socketPath.empty() && (socketPath.front() ==
'/' || socketPath.front() ==
'@'))) {
129 const std::string scheme =
"un";
130 const std::string httpPath = match[2].matched ? match[2].str() :
"/";
131 const std::string query = match[3].matched ? match[3].str() :
"";
133 eventSource =
EventSource(scheme
, net::un::SocketAddress
(socketPath
), httpPath + query
);
135 LOG(ERROR) <<
"UNIX socket must decode to absolute ('/..') or abstract ('@name'): " << sockToken;
138 LOG(ERROR) <<
"EventSource unix-domain url not accepted: " << url;