Skip to content
This repository has been archived by the owner on Feb 22, 2024. It is now read-only.

Commit

Permalink
Merge pull request #91 from Mossaka/jiazho/host_wildcard
Browse files Browse the repository at this point in the history
Fix integration tests and Added wildcard to allow all domains
  • Loading branch information
Mossaka authored May 9, 2022
2 parents a82ae3d + a4e1ee1 commit 9a143fa
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 16 deletions.
66 changes: 58 additions & 8 deletions crates/wasi-experimental-http-wasmtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use url::Url;
use wasmtime::*;

const MEMORY: &str = "memory";
const ALLOW_ALL_HOSTS: &str = "insecure:allow-all";

pub type WasiHttpHandle = u32;

Expand Down Expand Up @@ -481,7 +482,7 @@ impl HttpState {
};

let ctx = caller.as_context_mut();
let http_ctx = get_cx(&mut ctx.data());
let http_ctx = get_cx(ctx.data());

match HostCalls::req(
st.clone(),
Expand Down Expand Up @@ -619,13 +620,18 @@ fn is_allowed(url: &str, allowed_hosts: Option<&[String]>) -> Result<bool, HttpE
.to_owned();
match allowed_hosts {
Some(domains) => {
let allowed: Result<Vec<_>, _> = domains.iter().map(|d| Url::parse(d)).collect();
let allowed = allowed.map_err(|_| HttpError::InvalidUrl)?;

Ok(allowed
.iter()
.map(|u| u.host_str().unwrap())
.any(|x| x == url_host.as_str()))
// check domains has any "insecure:allow-all" wildcard
if domains.iter().any(|domain| domain == ALLOW_ALL_HOSTS) {
Ok(true)
} else {
let allowed: Result<Vec<_>, _> = domains.iter().map(|d| Url::parse(d)).collect();
let allowed = allowed.map_err(|_| HttpError::InvalidUrl)?;

Ok(allowed
.iter()
.map(|u| u.host_str().unwrap())
.any(|x| x == url_host.as_str()))
}
}
None => Ok(false),
}
Expand Down Expand Up @@ -711,3 +717,47 @@ fn test_allowed_domains() {
is_allowed("https://test.brigade.sh", Some(allowed_domains.as_ref())).unwrap()
);
}

#[test]
#[allow(clippy::bool_assert_comparison)]
fn test_allowed_domains_with_wildcard() {
let allowed_domains = vec![
"https://example.com".to_string(),
ALLOW_ALL_HOSTS.to_string(),
"http://192.168.0.1".to_string(),
];

assert_eq!(
true,
is_allowed(
"https://api.brigade.sh/healthz",
Some(allowed_domains.as_ref())
)
.unwrap()
);
assert_eq!(
true,
is_allowed(
"https://example.com/some/path/with/more/paths",
Some(allowed_domains.as_ref())
)
.unwrap()
);
assert_eq!(
true,
is_allowed("http://192.168.0.1/login", Some(allowed_domains.as_ref())).unwrap()
);
assert_eq!(
true,
is_allowed("https://test.brigade.sh", Some(allowed_domains.as_ref())).unwrap()
);
}

#[test]
#[should_panic]
#[allow(clippy::bool_assert_comparison)]
fn test_url_parsing() {
let allowed_domains = vec![ALLOW_ALL_HOSTS.to_string()];

is_allowed("not even a url", Some(allowed_domains.as_ref())).unwrap();
}
4 changes: 2 additions & 2 deletions tests/as/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function post(): void {
}

export function get(): void {
let res = new RequestBuilder("https://api.brigade.sh/healthz")
let res = new RequestBuilder("https://some-random-api.ml/facts/dog")
.method(Method.GET)
.send();

Expand All @@ -37,7 +37,7 @@ export function concurrent(): void {
}

function makeReq(): Response {
return new RequestBuilder("https://api.brigade.sh/healthz")
return new RequestBuilder("https://some-random-api.ml/facts/dog")
.method(Method.GET)
.send();
}
Expand Down
18 changes: 15 additions & 3 deletions tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ mod tests {
use wasmtime_wasi::sync::WasiCtxBuilder;
use wasmtime_wasi::*;

const ALLOW_ALL_HOSTS: &str = "insecure:allow-all";

// We run the same test in a Tokio and non-Tokio environment
// in order to make sure both scenarios are working.

Expand Down Expand Up @@ -38,7 +40,7 @@ mod tests {
fn test_with_allowed_domains() {
setup_tests(
Some(vec![
"https://api.brigade.sh".to_string(),
"https://some-random-api.ml".to_string(),
"https://postman-echo.com".to_string(),
]),
None,
Expand All @@ -49,13 +51,23 @@ mod tests {
async fn test_async_with_allowed_domains() {
setup_tests(
Some(vec![
"https://api.brigade.sh".to_string(),
"https://some-random-api.ml".to_string(),
"https://postman-echo.com".to_string(),
]),
None,
);
}

#[test]
fn test_with_wildcard_domain() {
setup_tests(Some(vec![ALLOW_ALL_HOSTS.to_string()]), None);
}

#[tokio::test(flavor = "multi_thread")]
async fn test_async_with_wildcard_domain() {
setup_tests(Some(vec![ALLOW_ALL_HOSTS.to_string()]), None);
}

#[test]
#[should_panic]
fn test_concurrent_requests_rust() {
Expand All @@ -80,7 +92,7 @@ mod tests {
let func = "concurrent";
let (instance, mut store) = create_instance(
module,
Some(vec!["https://api.brigade.sh".to_string()]),
Some(vec!["https://some-random-api.ml".to_string()]),
Some(2),
)
.unwrap();
Expand Down
6 changes: 3 additions & 3 deletions tests/rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use bytes::Bytes;

#[no_mangle]
pub extern "C" fn get() {
let url = "https://api.brigade.sh/healthz".to_string();
let url = "https://some-random-api.ml/facts/dog".to_string();
let req = http::request::Builder::new().uri(&url).body(None).unwrap();
let mut res = wasi_experimental_http::request(req).expect("cannot make get request");
let str = std::str::from_utf8(&res.body_read_all().unwrap())
.unwrap()
.to_string();
assert_eq!(str, r#""#);
assert_eq!(str.is_empty(), false);
assert_eq!(res.status_code, 200);
assert!(!res
.header_get("content-type".to_string())
Expand Down Expand Up @@ -47,7 +47,7 @@ pub extern "C" fn post() {
#[allow(unused_variables)]
#[no_mangle]
pub extern "C" fn concurrent() {
let url = "https://api.brigade.sh/healthz".to_string();
let url = "https://some-random-api.ml/facts/dog".to_string();
// the responses are unused to avoid dropping them.
let req1 = make_req(url.clone());
let req2 = make_req(url.clone());
Expand Down

0 comments on commit 9a143fa

Please sign in to comment.