Kurlyk
Loading...
Searching...
No Matches
url_utils.hpp
Go to the documentation of this file.
1#pragma once
2#ifndef KURLYK_HEADER_KURLYK_UTILS_URL_UTILS_HPP_INCLUDED
3#define KURLYK_HEADER_KURLYK_UTILS_URL_UTILS_HPP_INCLUDED
4
7
8namespace kurlyk {
9namespace utils {
10
14 inline std::string extract_protocol(const std::string& url) {
15 std::string protocol;
16 std::size_t pos = url.find("://");
17
18 if (pos != std::string::npos) {
19 protocol = url.substr(0, pos);
20 }
21
22 return protocol;
23 }
24
28 inline std::string remove_ws_prefix(const std::string& url) {
29 const std::string wss_prefix = "wss://";
30 const std::string ws_prefix = "ws://";
31
32 std::string modified_url = url;
33
34 // Find the position of "wss://" or "ws://"
35 std::size_t pos = modified_url.find(wss_prefix);
36 if (pos == std::string::npos) {
37 pos = modified_url.find(ws_prefix);
38 }
39
40 // If found, erase the substring
41 if (pos != std::string::npos) {
42 if (modified_url.compare(pos, wss_prefix.length(), wss_prefix) == 0) {
43 modified_url.erase(pos, wss_prefix.length());
44 } else if (modified_url.compare(pos, ws_prefix.length(), ws_prefix) == 0) {
45 modified_url.erase(pos, ws_prefix.length());
46 }
47 }
48
49 return modified_url;
50 }
51
56 inline bool is_valid_scheme(const std::string& url, const std::string& scheme) {
57 return url.compare(0, scheme.length(), scheme) == 0;
58 }
59
63 inline bool is_valid_domain(const std::string& domain) {
64 size_t dot_pos = domain.find('.');
65
66 if (dot_pos == std::string::npos ||
67 dot_pos == 0 ||
68 dot_pos == domain.length() - 1) {
69 return false;
70 }
71
72 for (char ch : domain) {
73 if (!isalnum(ch) && ch != '-' && ch != '.') {
74 return false;
75 }
76 }
77
78 std::string tld = domain.substr(dot_pos + 1);
79 for (char ch : tld) {
80 if (!isalpha(ch)) {
81 return false;
82 }
83 }
84 return true;
85 }
86
90 inline bool is_valid_path(const std::string& path) {
91 if (path.empty() || path[0] != '/') return false;
92 for (char ch : path) {
93 if (!isalnum(ch) && ch != '/' && ch != '-' && ch != '_') {
94 return false;
95 }
96 }
97 return true;
98 }
99
103 inline bool is_valid_query(const std::string& query) {
104 if (query.empty() || query[0] != '?') {
105 return false;
106 }
107
108 size_t pos = 1;
109 while (pos < query.length()) {
110 size_t equalPos = query.find('=', pos);
111 size_t ampPos = query.find('&', pos);
112
113 if (equalPos == std::string::npos || (ampPos != std::string::npos && ampPos < equalPos)) {
114 return false;
115 }
116
117 pos = (ampPos == std::string::npos) ? query.length() : ampPos + 1;
118 }
119
120 return true;
121 }
122
127 inline bool is_valid_url(const std::string& url, const std::vector<std::string>& protocol) {
128 size_t scheme_end = url.find("://");
129 if (scheme_end == std::string::npos) {
130 return false;
131 }
132
133 const std::string scheme = url.substr(0, scheme_end);
134 const auto it = std::find(protocol.begin(), protocol.end(), scheme);
135 if (it == protocol.end()) return false;
136
137 const size_t domain_start = scheme_end + 3;
138 const size_t path_start = url.find('/', domain_start);
139 const size_t query_start = url.find('?', domain_start);
140
141 // Определяем конец домена
142 size_t domain_end = (path_start != std::string::npos) ? path_start : query_start;
143 if (domain_end == std::string::npos) {
144 domain_end = url.length();
145 }
146
147 const std::string domain = url.substr(domain_start, domain_end - domain_start);
148 if (!is_valid_domain(domain)) {
149 return false;
150 }
151
152 // Проверяем путь, если он есть
153 if (path_start != std::string::npos) {
154 std::string path = (query_start != std::string::npos) ? url.substr(path_start, query_start - path_start) : url.substr(path_start);
155 if (!is_valid_path(path)) {
156 return false;
157 }
158 }
159
160 // Проверяем query, если он есть
161 if (query_start != std::string::npos) {
162 std::string query = url.substr(query_start);
163 if (!is_valid_query(query)) {
164 return false;
165 }
166 }
167
168 return true;
169 }
170
171} // namespace utils
172} // namespace kurlyk
173
174#endif // KURLYK_HEADER_KURLYK_UTILS_URL_UTILS_HPP_INCLUDED
bool is_valid_scheme(const std::string &url, const std::string &scheme)
Checks if a given URL starts with a specified scheme.
Definition url_utils.hpp:56
bool is_valid_url(const std::string &url, const std::vector< std::string > &protocol)
Validates if a URL is correctly formatted.
std::string extract_protocol(const std::string &url)
Extracts the protocol from a URL.
Definition url_utils.hpp:14
bool is_valid_query(const std::string &query)
Validates if a query string is correctly formatted.
std::string remove_ws_prefix(const std::string &url)
Removes the first occurrence of "wss://" or "ws://" from the given URL.
Definition url_utils.hpp:28
bool is_valid_path(const std::string &path)
Checks if a path is correctly formatted.
Definition url_utils.hpp:90
bool is_valid_domain(const std::string &domain)
Validates if a domain name is correctly formatted.
Definition url_utils.hpp:63
Primary namespace for the Kurlyk library, encompassing initialization, request management,...