@@ -187,6 +187,9 @@ impl HostConfig {
187
187
bail ! ( "Invalid allowed host {host}: wildcards are allowed only as subdomains" ) ;
188
188
}
189
189
190
+ // Remove trailing slashes
191
+ host = host. trim_end_matches ( '/' ) ;
192
+
190
193
Ok ( Self :: List ( vec ! [ host. into( ) ] ) )
191
194
}
192
195
@@ -502,6 +505,37 @@ mod test {
502
505
use super :: * ;
503
506
use std:: net:: { Ipv4Addr , Ipv6Addr } ;
504
507
508
+ #[ test]
509
+ fn test_allowed_hosts_accepts_url_without_port ( ) {
510
+ assert_eq ! (
511
+ AllowedHostConfig :: new(
512
+ SchemeConfig :: new( "http" ) ,
513
+ HostConfig :: new( "spin.fermyon.dev" ) ,
514
+ PortConfig :: new( 80 )
515
+ ) ,
516
+ AllowedHostConfig :: parse( "http://spin.fermyon.dev" ) . unwrap( )
517
+ ) ;
518
+
519
+ assert_eq ! (
520
+ AllowedHostConfig :: new(
521
+ SchemeConfig :: new( "http" ) ,
522
+ // Trailing slash is removed
523
+ HostConfig :: new( "spin.fermyon.dev" ) ,
524
+ PortConfig :: new( 80 )
525
+ ) ,
526
+ AllowedHostConfig :: parse( "http://spin.fermyon.dev/" ) . unwrap( )
527
+ ) ;
528
+
529
+ assert_eq ! (
530
+ AllowedHostConfig :: new(
531
+ SchemeConfig :: new( "https" ) ,
532
+ HostConfig :: new( "spin.fermyon.dev" ) ,
533
+ PortConfig :: new( 443 )
534
+ ) ,
535
+ AllowedHostConfig :: parse( "https://spin.fermyon.dev" ) . unwrap( )
536
+ ) ;
537
+ }
538
+
505
539
#[ test]
506
540
fn test_allowed_hosts_accepts_url_with_port ( ) {
507
541
assert_eq ! (
@@ -667,6 +701,9 @@ mod test {
667
701
668
702
#[ test]
669
703
fn test_allowed_hosts_rejects_path ( ) {
704
+ // An empty path is allowed
705
+ assert ! ( AllowedHostConfig :: parse( "http://spin.fermyon.dev/" ) . is_ok( ) ) ;
706
+ // All other paths are not allowed
670
707
assert ! ( AllowedHostConfig :: parse( "http://spin.fermyon.dev/a" ) . is_err( ) ) ;
671
708
assert ! ( AllowedHostConfig :: parse( "http://spin.fermyon.dev:6666/a/b" ) . is_err( ) ) ;
672
709
assert ! ( AllowedHostConfig :: parse( "http://*.fermyon.dev/a" ) . is_err( ) ) ;
@@ -700,13 +737,23 @@ mod test {
700
737
assert ! (
701
738
allowed. allows( & OutboundUrl :: parse( "http://example.com:8383/foo/bar" , "http" ) . unwrap( ) )
702
739
) ;
740
+ // Allow urls with and without a trailing slash
741
+ assert ! ( allowed. allows( & OutboundUrl :: parse( "https://spin.fermyon.dev" , "https" ) . unwrap( ) ) ) ;
703
742
assert ! ( allowed. allows( & OutboundUrl :: parse( "https://spin.fermyon.dev/" , "https" ) . unwrap( ) ) ) ;
704
743
assert ! ( !allowed. allows( & OutboundUrl :: parse( "http://example.com/" , "http" ) . unwrap( ) ) ) ;
705
744
assert ! ( !allowed. allows( & OutboundUrl :: parse( "http://google.com/" , "http" ) . unwrap( ) ) ) ;
706
745
assert ! ( allowed. allows( & OutboundUrl :: parse( "spin.fermyon.dev:443" , "https" ) . unwrap( ) ) ) ;
707
746
assert ! ( allowed. allows( & OutboundUrl :: parse( "example.com:8383" , "http" ) . unwrap( ) ) ) ;
708
747
}
709
748
749
+ #[ test]
750
+ fn test_allowed_hosts_with_trailing_slash ( ) {
751
+ let allowed =
752
+ AllowedHostsConfig :: parse ( & [ "https://my.api.com/" ] , & dummy_resolver ( ) ) . unwrap ( ) ;
753
+ assert ! ( allowed. allows( & OutboundUrl :: parse( "https://my.api.com" , "https" ) . unwrap( ) ) ) ;
754
+ assert ! ( allowed. allows( & OutboundUrl :: parse( "https://my.api.com/" , "https" ) . unwrap( ) ) ) ;
755
+ }
756
+
710
757
#[ test]
711
758
fn test_allowed_hosts_can_be_subdomain_wildcards ( ) {
712
759
let allowed = AllowedHostsConfig :: parse (
0 commit comments