@@ -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 ) ]
105105pub struct AllowedHostConfig {
106106 original : String ,
@@ -110,10 +110,7 @@ pub struct AllowedHostConfig {
110110}
111111
112112impl 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 ) ]
181182pub enum SchemeConfig {
183+ /// Any scheme is allowed: `*://`
182184 Any ,
185+ /// Any scheme is allowed: `*://`
183186 List ( Vec < String > ) ,
184187}
185188
186189impl 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 ) ]
217223pub enum HostConfig {
218224 Any ,
@@ -223,6 +229,7 @@ pub enum HostConfig {
223229}
224230
225231impl 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 ) ]
287297pub enum PortConfig {
288298 Any ,
289299 List ( Vec < IndividualPortConfig > ) ,
290300}
291301
292302impl 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 ) ]
328341pub enum IndividualPortConfig {
329342 Port ( u16 ) ,
330343 Range ( Range < u16 > ) ,
331344}
332345
333346impl 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.
357373fn 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.
369387enum PartialAllowedHostConfig {
370388 Exact ( AllowedHostConfig ) ,
371389 Unresolved ( spin_expressions:: Template ) ,
372390}
373391
374392impl 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 ) ]
387407pub enum AllowedHostsConfig {
388408 All ,
389409 SpecificHosts ( Vec < AllowedHostConfig > ) ,
390410}
391411
392412impl 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
463489impl 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