@@ -133,9 +133,11 @@ pub mod error;
133133mod parser;
134134
135135pub use error:: InlineError ;
136+ use std:: borrow:: Cow ;
136137use std:: collections:: HashMap ;
137138use std:: fs:: File ;
138139use std:: io:: { Read , Write } ;
140+ pub use url:: { ParseError , Url } ;
139141
140142#[ derive( Debug ) ]
141143struct Rule < ' i > {
@@ -161,7 +163,7 @@ pub struct InlineOptions {
161163 /// Remove "style" tags after inlining
162164 pub remove_style_tags : bool ,
163165 /// Used for loading external stylesheets via relative URLs
164- pub base_url : Option < String > ,
166+ pub base_url : Option < Url > ,
165167 /// Whether remote stylesheets should be loaded or not
166168 pub load_remote_stylesheets : bool ,
167169}
@@ -245,7 +247,7 @@ impl CSSInliner {
245247 {
246248 if let Some ( href) = & link_tag. attributes . borrow ( ) . get ( "href" ) {
247249 let url = self . get_full_url ( href) ;
248- let css = self . load_external ( url. as_str ( ) ) ?;
250+ let css = self . load_external ( url. as_ref ( ) ) ?;
249251 process_css ( & document, css. as_str ( ) ) ?;
250252 }
251253 }
@@ -254,20 +256,24 @@ impl CSSInliner {
254256 Ok ( ( ) )
255257 }
256258
257- fn get_full_url ( & self , href : & str ) -> String {
258- if href. starts_with ( "//" ) {
259- if let Some ( base_url) = & self . options . base_url {
260- if base_url. starts_with ( "https://" ) {
261- format ! ( "https:{}" , href)
262- } else {
263- format ! ( "http:{}" , href)
264- }
259+ fn get_full_url < ' u > ( & self , href : & ' u str ) -> Cow < ' u , str > {
260+ // Valid absolute URL
261+ if Url :: parse ( href) . is_ok ( ) {
262+ return Cow :: Borrowed ( href) ;
263+ } ;
264+ if let Some ( base_url) = & self . options . base_url {
265+ // Use the same scheme as the base URL
266+ if href. starts_with ( "//" ) {
267+ return Cow :: Owned ( format ! ( "{}:{}" , base_url. scheme( ) , href) ) ;
265268 } else {
266- format ! ( "http:{}" , href)
269+ // Not a URL, then it is a relative URL
270+ if let Ok ( new_url) = base_url. join ( href) {
271+ return Cow :: Owned ( new_url. to_string ( ) ) ;
272+ }
267273 }
268- } else {
269- href . to_string ( )
270- }
274+ } ;
275+ // If it is not a valid URL and there is no base URL specified, we assume a local path
276+ Cow :: Borrowed ( href )
271277 }
272278
273279 fn load_external ( & self , url : & str ) -> Result < String , InlineError > {
0 commit comments