@@ -515,9 +515,15 @@ impl DomainMatcher {
515515 fn contains ( & self , domain : & str ) -> bool {
516516 let domain_len = domain. len ( ) ;
517517 for d in & self . 0 {
518- if d == domain || d. strip_prefix ( '.' ) == Some ( domain) {
518+ if d. eq_ignore_ascii_case ( domain)
519+ || d. strip_prefix ( '.' )
520+ . map_or ( false , |s| s. eq_ignore_ascii_case ( domain) )
521+ {
519522 return true ;
520- } else if domain. ends_with ( d) {
523+ } else if domain
524+ . get ( domain_len. saturating_sub ( d. len ( ) ) ..)
525+ . map_or ( false , |s| s. eq_ignore_ascii_case ( d) )
526+ {
521527 if d. starts_with ( '.' ) {
522528 // If the first character of d is a dot, that means the first character of domain
523529 // must also be a dot, so we are looking at a subdomain of d and that matches
@@ -698,13 +704,19 @@ mod tests {
698704
699705 // domains match with leading `.`
700706 assert ! ( matcher. contains( "foo.bar" ) ) ;
707+ assert ! ( matcher. contains( "FOO.BAR" ) ) ;
708+
701709 // subdomains match with leading `.`
702710 assert ! ( matcher. contains( "www.foo.bar" ) ) ;
711+ assert ! ( matcher. contains( "WWW.FOO.BAR" ) ) ;
703712
704713 // domains match with no leading `.`
705714 assert ! ( matcher. contains( "bar.foo" ) ) ;
715+ assert ! ( matcher. contains( "Bar.foo" ) ) ;
716+
706717 // subdomains match with no leading `.`
707718 assert ! ( matcher. contains( "www.bar.foo" ) ) ;
719+ assert ! ( matcher. contains( "WWW.BAR.FOO" ) ) ;
708720
709721 // non-subdomain string prefixes don't match
710722 assert ! ( !matcher. contains( "notfoo.bar" ) ) ;
@@ -866,4 +878,48 @@ mod tests {
866878
867879 assert ! ( m. intercept( & "http://rick.roll" . parse( ) . unwrap( ) ) . is_none( ) ) ;
868880 }
881+
882+ #[ test]
883+ fn test_domain_matcher_case_insensitive ( ) {
884+ let domains = vec ! [ ".foo.bar" . into( ) ] ;
885+ let matcher = DomainMatcher ( domains) ;
886+
887+ assert ! ( matcher. contains( "foo.bar" ) ) ;
888+ assert ! ( matcher. contains( "FOO.BAR" ) ) ;
889+ assert ! ( matcher. contains( "Foo.Bar" ) ) ;
890+
891+ assert ! ( matcher. contains( "www.foo.bar" ) ) ;
892+ assert ! ( matcher. contains( "WWW.FOO.BAR" ) ) ;
893+ assert ! ( matcher. contains( "Www.Foo.Bar" ) ) ;
894+ }
895+
896+ #[ test]
897+ fn test_no_proxy_case_insensitive ( ) {
898+ let p = p ! {
899+ all = "http://proxy.local" ,
900+ no = ".example.com" ,
901+ } ;
902+
903+ // should bypass proxy (case insensitive match)
904+ assert ! ( p
905+ . intercept( & "http://example.com" . parse( ) . unwrap( ) )
906+ . is_none( ) ) ;
907+ assert ! ( p
908+ . intercept( & "http://EXAMPLE.COM" . parse( ) . unwrap( ) )
909+ . is_none( ) ) ;
910+ assert ! ( p
911+ . intercept( & "http://Example.com" . parse( ) . unwrap( ) )
912+ . is_none( ) ) ;
913+
914+ // subdomain should bypass proxy (case insensitive match)
915+ assert ! ( p
916+ . intercept( & "http://www.example.com" . parse( ) . unwrap( ) )
917+ . is_none( ) ) ;
918+ assert ! ( p
919+ . intercept( & "http://WWW.EXAMPLE.COM" . parse( ) . unwrap( ) )
920+ . is_none( ) ) ;
921+ assert ! ( p
922+ . intercept( & "http://Www.Example.Com" . parse( ) . unwrap( ) )
923+ . is_none( ) ) ;
924+ }
869925}
0 commit comments