Skip to content

Commit 28ca31c

Browse files
authored
Merge pull request #3016 from alexcrichton/gate-service-chained-requests
Check allowed hosts before checking the `request_interceptor`
2 parents ee2f691 + 8fc4c03 commit 28ca31c

File tree

3 files changed

+40
-22
lines changed
  • crates/factor-outbound-http/src
  • tests/test-components

3 files changed

+40
-22
lines changed

crates/factor-outbound-http/src/wasi.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -132,23 +132,6 @@ async fn send_request_impl(
132132

133133
spin_telemetry::inject_trace_context(&mut request);
134134

135-
if let Some(interceptor) = request_interceptor {
136-
let intercept_request = std::mem::take(&mut request).into();
137-
match interceptor.intercept(intercept_request).await? {
138-
InterceptOutcome::Continue(req) => {
139-
request = req.into_hyper_request();
140-
}
141-
InterceptOutcome::Complete(resp) => {
142-
let resp = IncomingResponse {
143-
resp,
144-
worker: None,
145-
between_bytes_timeout: config.between_bytes_timeout,
146-
};
147-
return Ok(Ok(resp));
148-
}
149-
}
150-
}
151-
152135
let host = request.uri().host().unwrap_or_default();
153136
let tls_client_config = component_tls_configs.get_client_config(host).clone();
154137

@@ -189,6 +172,23 @@ async fn send_request_impl(
189172
*request.uri_mut() = origin.into_uri(path_and_query);
190173
}
191174

175+
if let Some(interceptor) = request_interceptor {
176+
let intercept_request = std::mem::take(&mut request).into();
177+
match interceptor.intercept(intercept_request).await? {
178+
InterceptOutcome::Continue(req) => {
179+
request = req.into_hyper_request();
180+
}
181+
InterceptOutcome::Complete(resp) => {
182+
let resp = IncomingResponse {
183+
resp,
184+
worker: None,
185+
between_bytes_timeout: config.between_bytes_timeout,
186+
};
187+
return Ok(Ok(resp));
188+
}
189+
}
190+
}
191+
192192
let authority = request.uri().authority().context("authority not set")?;
193193
span.record("server.address", authority.host());
194194
if let Some(port) = authority.port() {

tests/test-components/components/internal-http-front/src/lib.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use anyhow::anyhow;
2-
use helper::{ensure, ensure_eq, ensure_ok, ensure_some};
2+
use helper::{ensure, ensure_eq, ensure_matches, ensure_ok, ensure_some};
33
use spin_sdk::{
44
http::{IntoResponse, Request},
55
http_component,
@@ -32,5 +32,17 @@ async fn handle_front_impl(_req: Request) -> Result<impl IntoResponse, String> {
3232

3333
res.headers_mut()
3434
.append("spin-component", ensure_ok!("internal-http-front-component".try_into()));
35+
36+
// Double-check that we can only send requests to allowed hosts.
37+
ensure_matches!(
38+
spin_sdk::http::send::<_, spin_sdk::http::Response>(spin_sdk::http::Request::new(
39+
spin_sdk::http::Method::Get,
40+
"http://back.spin.internal/hello/from/middle"
41+
))
42+
.await,
43+
Err(spin_sdk::http::SendError::Http(
44+
spin_sdk::http::Error::UnexpectedError(_)
45+
)),
46+
);
3547
Ok(res)
3648
}

tests/test-components/helper/src/lib.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,17 @@ macro_rules! ensure_matches {
159159

160160
#[macro_export]
161161
macro_rules! ensure_eq {
162-
($expr1:expr, $expr2:expr) => {
163-
if $expr1 != $expr2 {
164-
$crate::bail!("`{}` != `{}`", stringify!($expr1), stringify!($expr2));
162+
($expr1:expr, $expr2:expr) => {{
163+
let a = $expr1;
164+
let b = $expr2;
165+
if a != b {
166+
$crate::bail!(
167+
"`{}` != `{}`\n{a:?} != {b:?}",
168+
stringify!($expr1),
169+
stringify!($expr2),
170+
);
165171
}
166-
};
172+
}};
167173
}
168174

169175
#[macro_export]

0 commit comments

Comments
 (0)