Skip to content

Commit 6cffbe2

Browse files
committed
outbound-networking: Add doc comments
Plus a couple of collateral error tweaks. Signed-off-by: Lann Martin <[email protected]>
1 parent af59cd1 commit 6cffbe2

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

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

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<F: Fn(&str, &str) + Send + Sync> DisallowedHostHandler for F {
100100
}
101101
}
102102

103-
/// An address is a url-like string that contains a host, a port, and an optional scheme
103+
/// Represents a single `allowed_outbound_hosts` item.
104104
#[derive(Eq, Debug, Clone)]
105105
pub struct AllowedHostConfig {
106106
original: String,
@@ -110,10 +110,7 @@ pub struct AllowedHostConfig {
110110
}
111111

112112
impl AllowedHostConfig {
113-
/// Try to parse the address.
114-
///
115-
/// If the parsing fails, the address is prepended with the scheme and parsing
116-
/// is tried again.
113+
/// Parses the given string as an `allowed_hosts_config` item.
117114
pub fn parse(url: impl Into<String>) -> anyhow::Result<Self> {
118115
let original = url.into();
119116
let url = original.trim();
@@ -154,12 +151,15 @@ impl AllowedHostConfig {
154151
&self.port
155152
}
156153

154+
/// Returns true if the given URL is allowed.
157155
fn allows(&self, url: &OutboundUrl) -> bool {
158156
self.scheme.allows(&url.scheme)
159157
&& self.host.allows(&url.host)
160158
&& self.port.allows(url.port, &url.scheme)
161159
}
162160

161+
/// Returns true if relative ("self") requests to any of the given schemes
162+
/// are allowed.
163163
fn allows_relative(&self, schemes: &[&str]) -> bool {
164164
schemes.iter().any(|s| self.scheme.allows(s)) && self.host.allows_relative()
165165
}
@@ -177,34 +177,39 @@ impl std::fmt::Display for AllowedHostConfig {
177177
}
178178
}
179179

180+
/// Represents the scheme part of an allowed_outbound_hosts item.
180181
#[derive(PartialEq, Eq, Debug, Clone)]
181182
pub enum SchemeConfig {
183+
/// Any scheme is allowed: `*://`
182184
Any,
185+
/// Any scheme is allowed: `*://`
183186
List(Vec<String>),
184187
}
185188

186189
impl SchemeConfig {
190+
/// Parses the scheme part of an allowed_outbound_hosts item.
187191
fn parse(scheme: &str) -> anyhow::Result<Self> {
188192
if scheme == "*" {
189193
return Ok(Self::Any);
190194
}
191195

192196
if scheme.starts_with('{') {
193-
// TODO:
194-
bail!("scheme lists are not yet supported")
197+
anyhow::bail!("scheme lists are not supported")
195198
}
196199

197200
if scheme.chars().any(|c| !c.is_alphabetic()) {
198-
anyhow::bail!(" scheme {scheme:?} contains non alphabetic character");
201+
anyhow::bail!("scheme {scheme:?} contains non alphabetic character");
199202
}
200203

201204
Ok(Self::List(vec![scheme.into()]))
202205
}
203206

207+
/// Returns true if any scheme is allowed (i.e. `*://`).
204208
pub fn allows_any(&self) -> bool {
205209
matches!(self, Self::Any)
206210
}
207211

212+
/// Returns true if the given scheme is allowed.
208213
fn allows(&self, scheme: &str) -> bool {
209214
match self {
210215
SchemeConfig::Any => true,
@@ -213,6 +218,7 @@ impl SchemeConfig {
213218
}
214219
}
215220

221+
/// Represents the host part of an allowed_outbound_hosts item.
216222
#[derive(Debug, PartialEq, Eq, Clone)]
217223
pub enum HostConfig {
218224
Any,
@@ -223,6 +229,7 @@ pub enum HostConfig {
223229
}
224230

225231
impl HostConfig {
232+
/// Parses the host part of an allowed_outbound_hosts item.
226233
fn parse(mut host: &str) -> anyhow::Result<Self> {
227234
host = host.trim();
228235
if host == "*" {
@@ -263,6 +270,7 @@ impl HostConfig {
263270
Ok(Self::List(vec![host.into()]))
264271
}
265272

273+
/// Returns true if the given host is allowed.
266274
fn allows(&self, host: &str) -> bool {
267275
match self {
268276
HostConfig::Any => true,
@@ -278,18 +286,21 @@ impl HostConfig {
278286
}
279287
}
280288

289+
/// Returns true if relative ("self") requests are allowed.
281290
fn allows_relative(&self) -> bool {
282291
matches!(self, Self::Any | Self::ToSelf)
283292
}
284293
}
285294

295+
/// Represents the port part of an allowed_outbound_hosts item.
286296
#[derive(Debug, PartialEq, Eq, Clone)]
287297
pub enum PortConfig {
288298
Any,
289299
List(Vec<IndividualPortConfig>),
290300
}
291301

292302
impl PortConfig {
303+
/// Parses the port part of an allowed_outbound_hosts item.
293304
fn parse(port: &str, scheme: &str) -> anyhow::Result<PortConfig> {
294305
if port.is_empty() {
295306
return well_known_port(scheme)
@@ -310,6 +321,7 @@ impl PortConfig {
310321
Ok(Self::List(vec![port]))
311322
}
312323

324+
/// Returns true if the given port (or scheme-default port) is allowed.
313325
fn allows(&self, port: Option<u16>, scheme: &str) -> bool {
314326
match self {
315327
PortConfig::Any => true,
@@ -324,13 +336,15 @@ impl PortConfig {
324336
}
325337
}
326338

339+
/// Represents a single port specifier in an allowed_outbound_hosts item.
327340
#[derive(Debug, PartialEq, Eq, Clone)]
328341
pub enum IndividualPortConfig {
329342
Port(u16),
330343
Range(Range<u16>),
331344
}
332345

333346
impl IndividualPortConfig {
347+
/// Parses the a single port specifier in an allowed_outbound_hosts item.
334348
fn parse(port: &str) -> anyhow::Result<Self> {
335349
if let Some((start, end)) = port.split_once("..") {
336350
let start = start
@@ -346,6 +360,7 @@ impl IndividualPortConfig {
346360
})?))
347361
}
348362

363+
/// Returns true if the given port is allowed.
349364
fn allows(&self, port: u16) -> bool {
350365
match self {
351366
IndividualPortConfig::Port(p) => p == &port,
@@ -354,6 +369,7 @@ impl IndividualPortConfig {
354369
}
355370
}
356371

372+
/// Returns a well-known default port for the given URL scheme.
357373
fn well_known_port(scheme: &str) -> Option<u16> {
358374
match scheme {
359375
"postgres" => Some(5432),
@@ -366,12 +382,15 @@ fn well_known_port(scheme: &str) -> Option<u16> {
366382
}
367383
}
368384

385+
/// Holds a single allowed_outbound_hosts item, either parsed or as an
386+
/// unresolved template.
369387
enum PartialAllowedHostConfig {
370388
Exact(AllowedHostConfig),
371389
Unresolved(spin_expressions::Template),
372390
}
373391

374392
impl PartialAllowedHostConfig {
393+
/// Returns this config, resolving any template with the given resolver.
375394
fn resolve(
376395
self,
377396
resolver: &spin_expressions::PreparedResolver,
@@ -383,13 +402,16 @@ impl PartialAllowedHostConfig {
383402
}
384403
}
385404

405+
/// Represents an allowed_outbound_hosts config.
386406
#[derive(PartialEq, Eq, Debug, Clone)]
387407
pub enum AllowedHostsConfig {
388408
All,
389409
SpecificHosts(Vec<AllowedHostConfig>),
390410
}
391411

392412
impl AllowedHostsConfig {
413+
/// Parses the given allowed_outbound_hosts values, resolving any templates
414+
/// with the given resolver.
393415
pub fn parse<S: AsRef<str>>(
394416
hosts: &[S],
395417
resolver: &spin_expressions::PreparedResolver,
@@ -402,13 +424,15 @@ impl AllowedHostsConfig {
402424
Ok(Self::SpecificHosts(allowed))
403425
}
404426

427+
/// Validate the given allowed_outbound_hosts values. Templated values are
428+
/// only validated against template syntax.
405429
pub fn validate<S: AsRef<str>>(hosts: &[S]) -> anyhow::Result<()> {
406430
_ = Self::parse_partial(hosts)?;
407431
Ok(())
408432
}
409433

410-
// Parses literals but defers templates. This is pulled out so that `validate`
411-
// doesn't have to deal with resolving templates.
434+
/// Parse the given allowed_outbound_hosts values with deferred parsing of
435+
/// templated values.
412436
fn parse_partial<S: AsRef<str>>(hosts: &[S]) -> anyhow::Result<Vec<PartialAllowedHostConfig>> {
413437
if hosts.len() == 1 && hosts[0].as_ref() == "insecure:allow-all" {
414438
bail!("'insecure:allow-all' is not allowed - use '*://*:*' instead if you really want to allow all outbound traffic'")
@@ -427,14 +451,16 @@ impl AllowedHostsConfig {
427451
Ok(allowed)
428452
}
429453

430-
/// Determine if the supplied url is allowed
454+
/// Returns true if the given url is allowed.
431455
pub fn allows(&self, url: &OutboundUrl) -> bool {
432456
match self {
433457
AllowedHostsConfig::All => true,
434458
AllowedHostsConfig::SpecificHosts(hosts) => hosts.iter().any(|h| h.allows(url)),
435459
}
436460
}
437461

462+
/// Returns true if relative ("self") requests to any of the given schemes
463+
/// are allowed.
438464
pub fn allows_relative_url(&self, schemes: &[&str]) -> bool {
439465
match self {
440466
AllowedHostsConfig::All => true,
@@ -461,7 +487,7 @@ pub struct OutboundUrl {
461487
}
462488

463489
impl OutboundUrl {
464-
/// Parse a URL.
490+
/// Parses a URL.
465491
///
466492
/// If parsing `url` fails, `{scheme}://` is prepended to `url` and parsing is tried again.
467493
pub fn parse(url: impl Into<String>, scheme: &str) -> anyhow::Result<Self> {

0 commit comments

Comments
 (0)