Skip to content

Commit 99002e0

Browse files
authored
Merge pull request #2822 from fermyon/improved-logging-networking
Improve the logs and docs in outbound networking factor
2 parents 30f2e1e + 42513f3 commit 99002e0

File tree

3 files changed

+33
-19
lines changed

3 files changed

+33
-19
lines changed

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,6 @@ pub type Request = http::Request<wasmtime_wasi_http::body::HyperOutgoingBody>;
128128
pub type Response = http::Response<wasmtime_wasi_http::body::HyperIncomingBody>;
129129

130130
/// SelfRequestOrigin indicates the base URI to use for "self" requests.
131-
///
132-
/// This is meant to be set on [`Request::extensions_mut`] in appropriate
133-
/// contexts such as an incoming request handler.
134131
#[derive(Clone, Debug)]
135132
pub struct SelfRequestOrigin {
136133
pub scheme: Scheme,

crates/factor-outbound-networking/src/config.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,7 @@ impl Default for AllowedHostsConfig {
356356
}
357357
}
358358

359+
/// A parsed URL used for outbound networking.
359360
#[derive(Debug, Clone)]
360361
pub struct OutboundUrl {
361362
scheme: String,
@@ -365,6 +366,9 @@ pub struct OutboundUrl {
365366
}
366367

367368
impl OutboundUrl {
369+
/// Parse a URL.
370+
///
371+
/// If parsing `url` fails, `{scheme}://` is prepended to `url` and parsing is tried again.
368372
pub fn parse(url: impl Into<String>, scheme: &str) -> anyhow::Result<Self> {
369373
let mut url = url.into();
370374
let original = url.clone();

crates/factor-outbound-networking/src/lib.rs

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,20 @@ impl Factor for OutboundNetworkingFactor {
111111
wasi_builder.outbound_socket_addr_check(move |addr, addr_use| {
112112
let allowed_hosts = allowed_hosts.clone();
113113
async move {
114-
// TODO: validate against existing spin-core behavior
115114
let scheme = match addr_use {
116115
SocketAddrUse::TcpBind => return false,
117116
SocketAddrUse::TcpConnect => "tcp",
118-
SocketAddrUse::UdpBind | SocketAddrUse::UdpConnect | SocketAddrUse::UdpOutgoingDatagram => "udp",
117+
SocketAddrUse::UdpBind
118+
| SocketAddrUse::UdpConnect
119+
| SocketAddrUse::UdpOutgoingDatagram => "udp",
119120
};
120-
allowed_hosts.check_url(&addr.to_string(), scheme).await.unwrap_or_else(|err| {
121-
// TODO: should this trap (somehow)?
122-
tracing::error!(%err, "allowed_outbound_hosts variable resolution failed");
123-
false
124-
})
121+
allowed_hosts
122+
.check_url(&addr.to_string(), scheme)
123+
.await
124+
.unwrap_or(
125+
// TODO: should this trap (somehow)?
126+
false,
127+
)
125128
}
126129
});
127130
}
@@ -174,7 +177,7 @@ impl FactorInstanceBuilder for InstanceBuilder {
174177
}
175178
}
176179

177-
// TODO: Refactor w/ spin-outbound-networking crate to simplify
180+
/// A check for whether a URL is allowed by the outbound networking configuration.
178181
#[derive(Clone)]
179182
pub struct OutboundAllowedHosts {
180183
allowed_hosts_future: SharedFutureResult<AllowedHostsConfig>,
@@ -184,31 +187,41 @@ pub struct OutboundAllowedHosts {
184187
impl OutboundAllowedHosts {
185188
/// Checks address against allowed hosts
186189
///
187-
/// Calls the [`DisallowedHostCallback`] if set and URL is disallowed.
190+
/// Calls the [`DisallowedHostHandler`] if set and URL is disallowed.
191+
/// If `url` cannot be parsed, `{scheme}://` is prepended to `url` and retried.
188192
pub async fn check_url(&self, url: &str, scheme: &str) -> anyhow::Result<bool> {
189-
let Ok(url) = OutboundUrl::parse(url, scheme) else {
190-
tracing::warn!(
191-
"A component tried to make a request to a url that could not be parsed: {url}",
192-
);
193-
return Ok(false);
193+
tracing::debug!("Checking outbound networking request to '{url}'");
194+
let url = match OutboundUrl::parse(url, scheme) {
195+
Ok(url) => url,
196+
Err(err) => {
197+
tracing::warn!(%err,
198+
"A component tried to make a request to a url that could not be parsed: {url}",
199+
);
200+
return Ok(false);
201+
}
194202
};
195203

196204
let allowed_hosts = self.resolve().await?;
197205
let is_allowed = allowed_hosts.allows(&url);
198206
if !is_allowed {
207+
tracing::debug!("Disallowed outbound networking request to '{url}'");
199208
self.report_disallowed_host(url.scheme(), &url.authority());
200209
}
201210
Ok(is_allowed)
202211
}
203212

204213
/// Checks if allowed hosts permit relative requests
205214
///
206-
/// Calls the [`DisallowedHostCallback`] if set and relative requests are
215+
/// Calls the [`DisallowedHostHandler`] if set and relative requests are
207216
/// disallowed.
208217
pub async fn check_relative_url(&self, schemes: &[&str]) -> anyhow::Result<bool> {
218+
tracing::debug!("Checking relative outbound networking request with schemes {schemes:?}");
209219
let allowed_hosts = self.resolve().await?;
210220
let is_allowed = allowed_hosts.allows_relative_url(schemes);
211221
if !is_allowed {
222+
tracing::debug!(
223+
"Disallowed relative outbound networking request with schemes {schemes:?}"
224+
);
212225
let scheme = schemes.first().unwrap_or(&"");
213226
self.report_disallowed_host(scheme, "self");
214227
}
@@ -217,7 +230,7 @@ impl OutboundAllowedHosts {
217230

218231
async fn resolve(&self) -> anyhow::Result<Arc<AllowedHostsConfig>> {
219232
self.allowed_hosts_future.clone().await.map_err(|err| {
220-
tracing::error!("Error resolving allowed_outbound_hosts variables: {err}");
233+
tracing::error!(%err, "Error resolving variables when checking request against allowed outbound hosts");
221234
anyhow::Error::msg(err)
222235
})
223236
}

0 commit comments

Comments
 (0)