mirror of
https://github.com/lux-tel/libsession-util.git
synced 2026-10-30 20:25:11 +00:00
74 lines
2.4 KiB
C++
74 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include <iostream>
|
|
#include <string_view>
|
|
#include <vector>
|
|
namespace session::network::backends {
|
|
|
|
const std::string_view FRAGMENT_PUBKEY = "p";
|
|
const std::string_view FRAGMENT_STREAM_ENCRYPTION = "d";
|
|
|
|
struct MatchedEndpoint {
|
|
std::string_view base; // everything before the pattern match (e.g. "https://example.com")
|
|
std::vector<std::string_view> captures;
|
|
};
|
|
|
|
static std::optional<MatchedEndpoint> match_endpoint(
|
|
std::string_view pattern, std::string_view input) {
|
|
if (input.empty())
|
|
return {};
|
|
|
|
auto first_placeholder = pattern.find("{}");
|
|
auto static_prefix = fmt::format("/{}", pattern.substr(0, first_placeholder));
|
|
|
|
auto pattern_start = input.find(static_prefix);
|
|
if (pattern_start == std::string_view::npos)
|
|
return std::nullopt;
|
|
|
|
MatchedEndpoint result;
|
|
result.base = input.substr(0, pattern_start);
|
|
|
|
// Skip leading '/' if present, otherwise start from the pattern directly
|
|
auto remaining = input.substr(pattern_start);
|
|
if (!remaining.empty() && remaining[0] == '/')
|
|
remaining = remaining.substr(1);
|
|
|
|
while (!pattern.empty()) {
|
|
auto placeholder = pattern.find("{}");
|
|
auto literal = pattern.substr(0, placeholder);
|
|
|
|
if (!remaining.starts_with(literal))
|
|
return std::nullopt;
|
|
|
|
remaining = remaining.substr(literal.size());
|
|
|
|
if (placeholder == std::string_view::npos)
|
|
break;
|
|
|
|
pattern = pattern.substr(placeholder + 2);
|
|
|
|
// Capture up to the next literal segment (or end of path segment if pattern is exhausted)
|
|
auto next_literal = pattern.substr(0, pattern.find("{}"));
|
|
auto capture_end = next_literal.empty() ? std::min(remaining.find('#'), remaining.find('?'))
|
|
: remaining.find(next_literal);
|
|
if (capture_end == std::string_view::npos && !next_literal.empty())
|
|
return std::nullopt;
|
|
|
|
// If no fragment/query, capture to end of string
|
|
if (capture_end == std::string_view::npos)
|
|
capture_end = remaining.size();
|
|
|
|
auto capture = remaining.substr(0, capture_end);
|
|
|
|
if (!capture.empty() && capture.back() == '/')
|
|
capture.remove_suffix(1);
|
|
|
|
result.captures.push_back(capture);
|
|
remaining = remaining.substr(capture_end);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
} // namespace session::network::backends
|