diff --git a/crates/factor-outbound-http/src/wasi.rs b/crates/factor-outbound-http/src/wasi.rs index 6a4dc1d635..686efe8045 100644 --- a/crates/factor-outbound-http/src/wasi.rs +++ b/crates/factor-outbound-http/src/wasi.rs @@ -152,7 +152,12 @@ async fn send_request_impl( let host = request.uri().host().unwrap_or_default(); let tls_client_config = component_tls_configs.get_client_config(host).clone(); - if request.uri().authority().is_some() { + let is_self_request = request + .uri() + .authority() + .is_some_and(|a| a.host() == "self.alt"); + + if request.uri().authority().is_some() && !is_self_request { // Absolute URI let is_allowed = outbound_allowed_hosts .check_url(&request.uri().to_string(), "https") diff --git a/crates/factor-outbound-networking/src/config.rs b/crates/factor-outbound-networking/src/config.rs index d8f1ceb8b0..4b963bc692 100644 --- a/crates/factor-outbound-networking/src/config.rs +++ b/crates/factor-outbound-networking/src/config.rs @@ -200,7 +200,7 @@ impl HostConfig { return Ok(Self::Any); } - if host == "self" { + if host == "self" || host == "self.alt" { return Ok(Self::ToSelf); } diff --git a/tests/integration.rs b/tests/integration.rs index 6c6bb84e18..15529bb563 100644 --- a/tests/integration.rs +++ b/tests/integration.rs @@ -372,6 +372,11 @@ mod integration_tests { Request::new(Method::Get, "/outbound-allowed"), Response::new_with_body(200, "Hello, Fermyon!\n"), )?; + assert_spin_request( + spin, + Request::new(Method::Get, "/outbound-allowed-alt"), + Response::new_with_body(200, "Hello, Fermyon!\n"), + )?; assert_spin_request( spin, diff --git a/tests/test-components/components/outbound-http/src/lib.rs b/tests/test-components/components/outbound-http/src/lib.rs index d9155ab843..02244bd4d6 100644 --- a/tests/test-components/components/outbound-http/src/lib.rs +++ b/tests/test-components/components/outbound-http/src/lib.rs @@ -7,6 +7,7 @@ use spin_sdk::{ /// Send an HTTP request and return the response. #[http_component] async fn send_outbound(_req: Request) -> Result { + // Test self-request via relative URL let mut res: http::Response = spin_sdk::http::send( http::Request::builder() .method("GET") @@ -14,7 +15,21 @@ async fn send_outbound(_req: Request) -> Result { .body(())?, ) .await?; + + // Test self-request via self.alt + let res_alt: http::Response = spin_sdk::http::send( + http::Request::builder() + .method("GET") + .uri("http://self.alt/hello") + .body(())?, + ) + .await?; + + assert_eq!(res.body(), res_alt.body()); + assert_eq!(res.status(), res_alt.status()); + res.headers_mut() .insert("spin-component", "outbound-http-component".try_into()?); + Ok(res) } diff --git a/tests/testcases/outbound-http-to-same-app/spin.toml b/tests/testcases/outbound-http-to-same-app/spin.toml index 8f241d7e63..32f6b4cafa 100644 --- a/tests/testcases/outbound-http-to-same-app/spin.toml +++ b/tests/testcases/outbound-http-to-same-app/spin.toml @@ -18,6 +18,13 @@ allowed_http_hosts = ["self"] [component.trigger] route = "/outbound-allowed/..." +[[component]] +id = "outbound-http-allowed-alt" +source = "%{source=outbound-http}" +allowed_http_hosts = ["self.alt"] +[component.trigger] +route = "/outbound-allowed-alt/..." + [[component]] id = "outbound-http-not-allowed" source = "%{source=outbound-http}"