mirror of https://github.com/fafhrd91/actix-net
ResourceDef: end match in a segment boundary
This commit is contained in:
parent
c65e8524b2
commit
9ee6457802
|
@ -628,12 +628,12 @@ impl ResourceDef {
|
||||||
PatternType::Prefix(prefix) if is_strict_prefix(prefix, path) => Some(prefix.len()),
|
PatternType::Prefix(prefix) if is_strict_prefix(prefix, path) => Some(prefix.len()),
|
||||||
PatternType::Prefix(_) => None,
|
PatternType::Prefix(_) => None,
|
||||||
|
|
||||||
PatternType::Dynamic(re, _) => re.find(path).map(|m| m.end()),
|
PatternType::Dynamic(re, _) => Some(re.captures(path)?[1].len()),
|
||||||
|
|
||||||
PatternType::DynamicSet(re, params) => {
|
PatternType::DynamicSet(re, params) => {
|
||||||
let idx = re.matches(path).into_iter().next()?;
|
let idx = re.matches(path).into_iter().next()?;
|
||||||
let (ref pattern, _) = params[idx];
|
let (ref pattern, _) = params[idx];
|
||||||
pattern.find(path).map(|m| m.end())
|
Some(pattern.captures(path)?[1].len())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,7 +659,7 @@ impl ResourceDef {
|
||||||
/// assert_eq!(path.unprocessed(), "");
|
/// assert_eq!(path.unprocessed(), "");
|
||||||
/// ```
|
/// ```
|
||||||
pub fn capture_match_info<T: ResourcePath>(&self, path: &mut Path<T>) -> bool {
|
pub fn capture_match_info<T: ResourcePath>(&self, path: &mut Path<T>) -> bool {
|
||||||
profile_method!(is_path_match);
|
profile_method!(capture_match_info);
|
||||||
self.capture_match_info_fn(path, &|_, _| true, &None::<()>)
|
self.capture_match_info_fn(path, &|_, _| true, &None::<()>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -712,7 +712,7 @@ impl ResourceDef {
|
||||||
T: ResourcePath,
|
T: ResourcePath,
|
||||||
F: Fn(&R, &Option<U>) -> bool,
|
F: Fn(&R, &Option<U>) -> bool,
|
||||||
{
|
{
|
||||||
profile_method!(is_path_match_fn);
|
profile_method!(capture_match_info_fn);
|
||||||
|
|
||||||
let mut segments = <[PathItem; MAX_DYNAMIC_SEGMENTS]>::default();
|
let mut segments = <[PathItem; MAX_DYNAMIC_SEGMENTS]>::default();
|
||||||
let path = resource.resource_path();
|
let path = resource.resource_path();
|
||||||
|
@ -756,7 +756,7 @@ impl ResourceDef {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
(captures[0].len(), Some(names))
|
(captures[1].len(), Some(names))
|
||||||
}
|
}
|
||||||
|
|
||||||
PatternType::DynamicSet(re, params) => {
|
PatternType::DynamicSet(re, params) => {
|
||||||
|
@ -782,7 +782,7 @@ impl ResourceDef {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
(captures[0].len(), Some(names))
|
(captures[1].len(), Some(names))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1045,8 +1045,16 @@ impl ResourceDef {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !is_prefix && !has_tail_segment {
|
// Store pattern in capture group #1 to have segment-boundary match oustide it
|
||||||
|
let mut re = format!("({})", re);
|
||||||
|
|
||||||
|
if has_tail_segment {
|
||||||
|
();
|
||||||
|
} else if !is_prefix {
|
||||||
re.push('$');
|
re.push('$');
|
||||||
|
} else if is_prefix && !pattern.ends_with('/') {
|
||||||
|
// make sure that match ends in a segment boundary
|
||||||
|
re.push_str(r"(/|$)");
|
||||||
}
|
}
|
||||||
|
|
||||||
let re = match Regex::new(&re) {
|
let re = match Regex::new(&re) {
|
||||||
|
@ -1478,10 +1486,6 @@ mod tests {
|
||||||
assert_eq!(&path[0], "test2");
|
assert_eq!(&path[0], "test2");
|
||||||
assert_eq!(path.unprocessed(), "subpath1/subpath2/index.html");
|
assert_eq!(path.unprocessed(), "subpath1/subpath2/index.html");
|
||||||
|
|
||||||
let resource = ResourceDef::prefix(r"/id/{id:\d{3}}");
|
|
||||||
assert!(resource.is_match("/id/1234"));
|
|
||||||
assert_eq!(resource.find_match("/id/1234"), Some(7));
|
|
||||||
|
|
||||||
let resource = ResourceDef::prefix("/user");
|
let resource = ResourceDef::prefix("/user");
|
||||||
// input string shorter than prefix
|
// input string shorter than prefix
|
||||||
assert!(resource.find_match("/foo").is_none());
|
assert!(resource.find_match("/foo").is_none());
|
||||||
|
@ -1554,6 +1558,21 @@ mod tests {
|
||||||
assert!(path.get("uid").is_some());
|
assert!(path.get("uid").is_some());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn dynamic_prefix_proper_segmentation() {
|
||||||
|
let resource = ResourceDef::prefix(r"/id/{id:\d{3}}");
|
||||||
|
|
||||||
|
assert!(resource.is_match("/id/123"));
|
||||||
|
assert!(resource.is_match("/id/123/foo"));
|
||||||
|
assert!(!resource.is_match("/id/1234"));
|
||||||
|
assert!(!resource.is_match("/id/123a"));
|
||||||
|
|
||||||
|
assert_eq!(resource.find_match("/id/123"), Some(7));
|
||||||
|
assert_eq!(resource.find_match("/id/123/foo"), Some(7));
|
||||||
|
assert_eq!(resource.find_match("/id/1234"), None);
|
||||||
|
assert_eq!(resource.find_match("/id/123a"), None);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn build_path_map() {
|
fn build_path_map() {
|
||||||
let resource = ResourceDef::new("/user/{item1}/{item2}/");
|
let resource = ResourceDef::new("/user/{item1}/{item2}/");
|
||||||
|
|
Loading…
Reference in New Issue