Skip to content

Commit 7a10d20

Browse files
committed
Rewriting fixes
- fix path regex captures indexes - replace missing optional captures by empty string (instead of panic) - skip first dot in host subdomain regex - force full match on host regex - use cluster https port for custom https redirections Signed-off-by: Eloi DEMOLIS <[email protected]>
1 parent 571cab0 commit 7a10d20

File tree

3 files changed

+33
-31
lines changed

3 files changed

+33
-31
lines changed

lib/src/protocol/kawa_h1/mod.rs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,14 +1318,6 @@ impl<Front: SocketHandler, L: L7ListenerHandler> Http<Front, L> {
13181318

13191319
let host = rewritten_host.as_deref().unwrap_or(host);
13201320
let path = rewritten_path.as_deref().unwrap_or(path);
1321-
let port = rewritten_port.map_or_else(
1322-
|| {
1323-
port.map_or(String::new(), |port| {
1324-
format!(":{}", unsafe { from_utf8_unchecked(port) })
1325-
})
1326-
},
1327-
|port| format!(":{port}"),
1328-
);
13291321
let is_https = matches!(proxy.borrow().kind(), ListenerType::Https);
13301322
let proto = match (redirect_scheme, is_https) {
13311323
(RedirectScheme::UseHttp, _) | (RedirectScheme::UseSame, false) => "http",
@@ -1370,6 +1362,18 @@ impl<Front: SocketHandler, L: L7ListenerHandler> Http<Front, L> {
13701362
}
13711363
};
13721364

1365+
let port = match (
1366+
port,
1367+
rewritten_port,
1368+
https_redirect_port,
1369+
!is_https && https_redirect,
1370+
) {
1371+
(_, Some(port), _, _) => format!(":{port}"),
1372+
(_, _, Some(port), true) => format!(":{port}"),
1373+
(Some(port), _, _, _) => format!(":{}", unsafe { from_utf8_unchecked(port) }),
1374+
_ => String::new(),
1375+
};
1376+
13731377
match (cluster_id, redirect, redirect_template, authorized) {
13741378
(_, RedirectPolicy::Permanent, _, true) => {
13751379
let location = format!("{proto}://{host}{port}{path}");
@@ -1383,9 +1387,6 @@ impl<Front: SocketHandler, L: L7ListenerHandler> Http<Front, L> {
13831387
}
13841388
(Some(cluster_id), RedirectPolicy::Forward, None, true) => {
13851389
if !is_https && https_redirect {
1386-
let port = rewritten_port
1387-
.or_else(|| https_redirect_port.map(|port| port as u16))
1388-
.map_or(String::new(), |port| format!(":{port}"));
13891390
let location = format!("https://{host}{port}{path}");
13901391
self.set_answer(DefaultAnswer::Answer301 { location });
13911392
return Err(RetrieveClusterError::Redirected);

lib/src/router/mod.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ pub enum DomainRule {
393393
}
394394

395395
fn convert_regex_domain_rule(hostname: &str) -> Option<String> {
396-
let mut result = String::new();
396+
let mut result = String::from("\\A");
397397

398398
let s = hostname.as_bytes();
399399
let mut index = 0;
@@ -436,6 +436,7 @@ fn convert_regex_domain_rule(hostname: &str) -> Option<String> {
436436
}
437437

438438
if index == s.len() {
439+
result.push_str("\\z");
439440
return Some(result);
440441
} else if s[index] == b'.' {
441442
result.push_str("\\.");
@@ -962,13 +963,12 @@ impl RouteResult {
962963
PathRule::Prefix(prefix) => {
963964
captures_path.push(unsafe { from_utf8_unchecked(&path[prefix.len()..]) })
964965
}
965-
PathRule::Regex(regex) => captures_path.extend(
966-
regex
967-
.captures(path)
968-
.unwrap()
969-
.iter()
970-
.map(|c| unsafe { from_utf8_unchecked(c.unwrap().as_bytes()) }),
971-
),
966+
PathRule::Regex(regex) => {
967+
captures_path.extend(regex.captures(path).unwrap().iter().skip(1).map(|c| {
968+
c.map(|c| unsafe { from_utf8_unchecked(c.as_bytes()) })
969+
.unwrap_or("")
970+
}))
971+
}
972972
_ => {}
973973
}
974974
}

lib/src/router/pattern_trie.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,8 @@ impl<V: Debug + Clone> TrieNode<V> {
132132
}
133133
}
134134

135-
if let Ok(r) = Regex::new(s) {
135+
let s = format!("\\A{s}\\z");
136+
if let Ok(r) = Regex::new(&s) {
136137
if pos > 0 {
137138
let mut node = TrieNode::root();
138139
let pos = pos - 1;
@@ -300,11 +301,11 @@ impl<V: Debug + Clone> TrieNode<V> {
300301
} else {
301302
//println!("there's still a subdomain, wildcard does not apply");
302303

303-
// let suffix = if suffix[0] == b'.' {
304-
// &suffix[1..]
305-
// } else {
306-
// suffix
307-
// };
304+
let suffix = if suffix[0] == b'.' {
305+
&suffix[1..]
306+
} else {
307+
suffix
308+
};
308309
for (regexp, child) in &self.regexps {
309310
//println!("testing regexp: {} on suffix {}", r.as_str(), str::from_utf8(s).unwrap());
310311

@@ -374,12 +375,12 @@ impl<V: Debug + Clone> TrieNode<V> {
374375
} else {
375376
//println!("there's still a subdomain, wildcard does not apply");
376377

377-
for (ref regexp, ref mut child) in self.regexps.iter_mut() {
378-
let suffix = if suffix[0] == b'.' {
379-
&suffix[1..]
380-
} else {
381-
suffix
382-
};
378+
let suffix = if suffix[0] == b'.' {
379+
&suffix[1..]
380+
} else {
381+
suffix
382+
};
383+
for (regexp, child) in &mut self.regexps {
383384
//println!("testing regexp: {} on suffix {}", r.as_str(), str::from_utf8(s).unwrap());
384385

385386
if regexp.is_match(suffix) {

0 commit comments

Comments
 (0)