@@ -8,6 +8,8 @@ use super::static_files::{STATIC_FILES, StaticFiles};
88use crate :: externalfiles:: ExternalHtml ;
99use crate :: html:: render:: { StylePath , ensure_trailing_slash} ;
1010
11+ #[ cfg( test) ]
12+ mod tests;
1113pub ( crate ) struct Layout {
1214 pub ( crate ) logo : String ,
1315 pub ( crate ) favicon : String ,
@@ -69,24 +71,9 @@ struct PageLayout<'a> {
6971}
7072
7173impl PageLayout < ' _ > {
72- /// Conservatively determines if [`Self::static_root_path`] is relative to the current origin,
73- /// so that `crossorigin` may be safely removed from `<link>` elements.
74+ /// See [`may_remove_crossorigin`].
7475 fn static_root_path_may_remove_crossorigin ( & self ) -> bool {
75- let href = & * self . static_root_path ;
76- // Reject scheme-relative URLs (`//example.com/`).
77- if href. starts_with ( "//" ) {
78- return false ;
79- }
80- // URL is interpreted as having a scheme iff: it starts with an ascii alpha, and only
81- // contains ascii alphanumeric or `+` `-` `.` up to the `:`.
82- // https://url.spec.whatwg.org/#url-parsing
83- let has_scheme = href. split_once ( ':' ) . is_some_and ( |( scheme, _rest) | {
84- let mut chars = scheme. chars ( ) ;
85- chars. next ( ) . is_some_and ( |c| c. is_ascii_alphabetic ( ) )
86- && chars. all ( |c| c. is_ascii_alphanumeric ( ) || c == '+' || c == '-' || c == '.' )
87- } ) ;
88- // Reject anything with a scheme (`http:`, etc.).
89- !has_scheme
76+ may_remove_crossorigin ( & self . static_root_path )
9077 }
9178}
9279
@@ -156,3 +143,22 @@ pub(crate) fn redirect(url: &str) -> String {
156143</html>"## ,
157144 )
158145}
146+
147+ /// Conservatively determines if `href` is relative to the current origin,
148+ /// so that `crossorigin` may be safely removed from `<link>` elements.
149+ pub ( crate ) fn may_remove_crossorigin ( href : & str ) -> bool {
150+ // Reject scheme-relative URLs (`//example.com/`).
151+ if href. starts_with ( "//" ) {
152+ return false ;
153+ }
154+ // URL is interpreted as having a scheme iff: it starts with an ascii alpha, and only
155+ // contains ascii alphanumeric or `+` `-` `.` up to the `:`.
156+ // https://url.spec.whatwg.org/#url-parsing
157+ let has_scheme = href. split_once ( ':' ) . is_some_and ( |( scheme, _rest) | {
158+ let mut chars = scheme. chars ( ) ;
159+ chars. next ( ) . is_some_and ( |c| c. is_ascii_alphabetic ( ) )
160+ && chars. all ( |c| c. is_ascii_alphanumeric ( ) || c == '+' || c == '-' || c == '.' )
161+ } ) ;
162+ // Reject anything with a scheme (`http:`, etc.).
163+ !has_scheme
164+ }
0 commit comments