Skip to content

Commit

Permalink
Merge pull request #2744 from lann/factors-fix-http-trigger
Browse files Browse the repository at this point in the history
factors: Reorganize some http trigger code
  • Loading branch information
lann authored Aug 22, 2024
2 parents be24451 + 6651646 commit be67f73
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 220 deletions.
173 changes: 173 additions & 0 deletions crates/trigger-http2/src/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ fn prepare_header_key(key: &str) -> String {
#[cfg(test)]
mod tests {
use super::*;
use anyhow::Result;
use spin_http::routes::Router;

#[test]
fn test_spin_header_keys() {
Expand All @@ -155,4 +157,175 @@ mod tests {
"spin-raw-component-route".to_string()
);
}

#[test]
fn test_default_headers() -> Result<()> {
let scheme = "https";
let host = "fermyon.dev";
let trigger_route = "/foo/...";
let component_path = "/foo";
let path_info = "/bar";
let client_addr: SocketAddr = "127.0.0.1:8777".parse().unwrap();

let req_uri = format!(
"{}://{}{}{}?key1=value1&key2=value2",
scheme, host, component_path, path_info
);

let req = http::Request::builder()
.method("POST")
.uri(req_uri)
.body("")?;

let (router, _) = Router::build("/", [("DUMMY", &trigger_route.into())])?;
let route_match = router.route("/foo/bar")?;

let default_headers = compute_default_headers(req.uri(), host, &route_match, client_addr)?;

assert_eq!(
search(&FULL_URL, &default_headers).unwrap(),
"https://fermyon.dev/foo/bar?key1=value1&key2=value2".to_string()
);
assert_eq!(
search(&PATH_INFO, &default_headers).unwrap(),
"/bar".to_string()
);
assert_eq!(
search(&MATCHED_ROUTE, &default_headers).unwrap(),
"/foo/...".to_string()
);
assert_eq!(
search(&BASE_PATH, &default_headers).unwrap(),
"/".to_string()
);
assert_eq!(
search(&RAW_COMPONENT_ROUTE, &default_headers).unwrap(),
"/foo/...".to_string()
);
assert_eq!(
search(&COMPONENT_ROUTE, &default_headers).unwrap(),
"/foo".to_string()
);
assert_eq!(
search(&CLIENT_ADDR, &default_headers).unwrap(),
"127.0.0.1:8777".to_string()
);

Ok(())
}

#[test]
fn test_default_headers_with_named_wildcards() -> Result<()> {
let scheme = "https";
let host = "fermyon.dev";
let trigger_route = "/foo/:userid/...";
let component_path = "/foo";
let path_info = "/bar";
let client_addr: SocketAddr = "127.0.0.1:8777".parse().unwrap();

let req_uri = format!(
"{}://{}{}/42{}?key1=value1&key2=value2",
scheme, host, component_path, path_info
);

let req = http::Request::builder()
.method("POST")
.uri(req_uri)
.body("")?;

let (router, _) = Router::build("/", [("DUMMY", &trigger_route.into())])?;
let route_match = router.route("/foo/42/bar")?;

let default_headers = compute_default_headers(req.uri(), host, &route_match, client_addr)?;

assert_eq!(
search(&FULL_URL, &default_headers).unwrap(),
"https://fermyon.dev/foo/42/bar?key1=value1&key2=value2".to_string()
);
assert_eq!(
search(&PATH_INFO, &default_headers).unwrap(),
"/bar".to_string()
);
assert_eq!(
search(&MATCHED_ROUTE, &default_headers).unwrap(),
"/foo/:userid/...".to_string()
);
assert_eq!(
search(&BASE_PATH, &default_headers).unwrap(),
"/".to_string()
);
assert_eq!(
search(&RAW_COMPONENT_ROUTE, &default_headers).unwrap(),
"/foo/:userid/...".to_string()
);
assert_eq!(
search(&COMPONENT_ROUTE, &default_headers).unwrap(),
"/foo/:userid".to_string()
);
assert_eq!(
search(&CLIENT_ADDR, &default_headers).unwrap(),
"127.0.0.1:8777".to_string()
);

assert_eq!(
search(
&["SPIN_PATH_MATCH_USERID", "X_PATH_MATCH_USERID"],
&default_headers
)
.unwrap(),
"42".to_string()
);

Ok(())
}

#[test]
fn forbidden_headers_are_removed() {
let mut req = Request::get("http://test.spin.internal")
.header("Host", "test.spin.internal")
.header("accept", "text/plain")
.body(Default::default())
.unwrap();

strip_forbidden_headers(&mut req);

assert_eq!(1, req.headers().len());
assert!(req.headers().get("Host").is_none());

let mut req = Request::get("http://test.spin.internal")
.header("Host", "test.spin.internal:1234")
.header("accept", "text/plain")
.body(Default::default())
.unwrap();

strip_forbidden_headers(&mut req);

assert_eq!(1, req.headers().len());
assert!(req.headers().get("Host").is_none());
}

#[test]
fn non_forbidden_headers_are_not_removed() {
let mut req = Request::get("http://test.example.com")
.header("Host", "test.example.org")
.header("accept", "text/plain")
.body(Default::default())
.unwrap();

strip_forbidden_headers(&mut req);

assert_eq!(2, req.headers().len());
assert!(req.headers().get("Host").is_some());
}

fn search(keys: &[&str; 2], headers: &[([String; 2], String)]) -> Option<String> {
let mut res: Option<String> = None;
for (k, v) in headers {
if k[0] == keys[0] && k[1] == keys[1] {
res = Some(v.clone());
}
}

res
}
}
Loading

0 comments on commit be67f73

Please sign in to comment.