Skip to content

Commit 0e032b7

Browse files
committed
feat: HttpService::IsTrustProxy support wildcard match
1 parent e9522d5 commit 0e032b7

File tree

7 files changed

+50
-19
lines changed

7 files changed

+50
-19
lines changed

base/hbase.c

+18
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,24 @@ bool hv_strcontains(const char* str, const char* sub) {
167167
return strstr(str, sub) != NULL;
168168
}
169169

170+
bool hv_wildcard_match(const char* str, const char* pattern) {
171+
assert(str != NULL && pattern != NULL);
172+
bool match = false;
173+
while (*str && *pattern) {
174+
if (*pattern == '*') {
175+
match = hv_strendswith(str, pattern + 1);
176+
break;
177+
} else if (*str != *pattern) {
178+
match = false;
179+
break;
180+
} else {
181+
++str;
182+
++pattern;
183+
}
184+
}
185+
return match ? match : (*str == '\0' && *pattern == '\0');
186+
}
187+
170188
char* hv_strnchr(const char* s, char c, size_t n) {
171189
assert(s != NULL);
172190
const char* p = s;

base/hbase.h

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ HV_EXPORT char* hv_strreverse(char* str);
6363
HV_EXPORT bool hv_strstartswith(const char* str, const char* start);
6464
HV_EXPORT bool hv_strendswith(const char* str, const char* end);
6565
HV_EXPORT bool hv_strcontains(const char* str, const char* sub);
66+
HV_EXPORT bool hv_wildcard_match(const char* str, const char* pattern);
6667

6768
// strncpy n = sizeof(dest_buf)-1
6869
// hv_strncpy n = sizeof(dest_buf)

docs/API.md

+1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
- hv_strstartswith
108108
- hv_strendswith
109109
- hv_strcontains
110+
- hv_wildcard_match
110111
- hv_strnchr
111112
- hv_strrchr_dot
112113
- hv_strrchr_dir

http/server/HttpHandler.cpp

+1-19
Original file line numberDiff line numberDiff line change
@@ -1014,25 +1014,7 @@ int HttpHandler::connectProxy(const std::string& strUrl) {
10141014
}
10151015
}
10161016

1017-
bool allow_proxy = true;
1018-
if (service && service->trustProxies.size() != 0) {
1019-
allow_proxy = false;
1020-
for (const auto& trust_proxy : service->trustProxies) {
1021-
if (trust_proxy == url.host) {
1022-
allow_proxy = true;
1023-
break;
1024-
}
1025-
}
1026-
}
1027-
if (service && service->noProxies.size() != 0) {
1028-
for (const auto& no_proxy : service->noProxies) {
1029-
if (no_proxy == url.host) {
1030-
allow_proxy = false;
1031-
break;
1032-
}
1033-
}
1034-
}
1035-
if (!allow_proxy) {
1017+
if (!service || !service->IsTrustProxy(url.host.c_str())) {
10361018
hlogw("Forbidden to proxy %s", url.host.c_str());
10371019
SetError(HTTP_STATUS_FORBIDDEN, HTTP_STATUS_FORBIDDEN);
10381020
return 0;

http/server/HttpService.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,29 @@ void HttpService::AddNoProxy(const char* host) {
179179
noProxies.emplace_back(host);
180180
}
181181

182+
bool HttpService::IsTrustProxy(const char* host) {
183+
if (!host || *host == '\0') return false;
184+
bool trust = true;
185+
if (trustProxies.size() != 0) {
186+
trust = false;
187+
for (const auto& trust_proxy : trustProxies) {
188+
if (hv_wildcard_match(host, trust_proxy.c_str())) {
189+
trust = true;
190+
break;
191+
}
192+
}
193+
}
194+
if (noProxies.size() != 0) {
195+
for (const auto& no_proxy : noProxies) {
196+
if (hv_wildcard_match(host, no_proxy.c_str())) {
197+
trust = false;
198+
break;
199+
}
200+
}
201+
}
202+
return trust;
203+
}
204+
182205
void HttpService::AllowCORS() {
183206
Use(HttpMiddleware::CORS);
184207
}

http/server/HttpService.h

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ struct HV_EXPORT HttpService {
194194
// proxy
195195
void AddTrustProxy(const char* host);
196196
void AddNoProxy(const char* host);
197+
bool IsTrustProxy(const char* host);
197198
// forward proxy
198199
void EnableForwardProxy() { enable_forward_proxy = 1; }
199200
// reverse proxy

unittest/hbase_test.c

+5
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ int main(int argc, char* argv[]) {
88
assert(hv_getboolean("1"));
99
assert(hv_getboolean("yes"));
1010

11+
assert(hv_wildcard_match("www.example.com", "www.example.com"));
12+
assert(hv_wildcard_match("www.example.com", "*.example.com"));
13+
assert(hv_wildcard_match("www.example.com", "www.*.com"));
14+
assert(hv_wildcard_match("www.example.com", "www.example.*"));
15+
1116
assert(hv_parse_size("256") == 256);
1217
assert(hv_parse_size("1K") == 1024);
1318
assert(hv_parse_size("1G2M3K4B") ==

0 commit comments

Comments
 (0)