@@ -33,13 +33,41 @@ impl ServeStaticFiles {
3333 /// Creates a new HTTP server that serves static files from a directory.
3434 /// Note: This server is only available for testing purposes.
3535 pub fn from ( static_path : impl Into < PathBuf > ) -> Result < Self , HttpServerError > {
36+ Self :: from_impl ( static_path, None )
37+ }
38+
39+ /// Same as [`Self::from`], but requires `Authorization: Bearer <token>` on every request.
40+ /// Note: This server is only available for testing purposes.
41+ pub fn from_with_bearer (
42+ static_path : impl Into < PathBuf > ,
43+ token : impl Into < String > ,
44+ ) -> Result < Self , HttpServerError > {
45+ Self :: from_impl ( static_path, Some ( token. into ( ) ) )
46+ }
47+
48+ /// Internal helper to keep the original implementation effectively intact.
49+ fn from_impl (
50+ static_path : impl Into < PathBuf > ,
51+ token : Option < String > ,
52+ ) -> Result < Self , HttpServerError > {
3653 let static_path = static_path. into ( ) ;
54+
3755 let server = Server :: new ( "127.0.0.1:0" , move |request| {
56+ if let Some ( token) = token. as_ref ( ) {
57+ if !request
58+ . header ( "Authorization" )
59+ . map ( |h| h == format ! ( "Bearer {}" , token) )
60+ . unwrap_or ( false )
61+ {
62+ return rouille:: Response :: text ( "Unauthorized" ) . with_status_code ( 401 ) ;
63+ }
64+ }
3865 match_assets ( request, & static_path)
3966 } )
4067 . map_err ( |e| HttpServerError {
4168 error : e. to_string ( ) ,
4269 } ) ?;
70+
4371 let port = server. server_addr ( ) . port ( ) ;
4472 let ( _, kill_switch) = server. stoppable ( ) ;
4573 Ok ( Self { kill_switch, port } )
@@ -93,4 +121,27 @@ mod tests {
93121 assert ! ( result. is_err( ) ) ;
94122 assert ! ( matches!( result. unwrap_err( ) , ureq:: Error :: Status ( 404 , _) ) ) ;
95123 }
124+
125+ #[ test]
126+ fn test_http_server_with_bearer_auth ( ) {
127+ let token = "token" ;
128+ let server = ServeStaticFiles :: from_with_bearer ( "tests/test_data" , token) . unwrap ( ) ;
129+
130+ let resp = ureq:: get ( & server. relative_path_to_url ( "file_a.yaml" ) ) . call ( ) ;
131+ assert ! ( resp. is_err( ) ) ;
132+ assert ! ( matches!( resp. unwrap_err( ) , ureq:: Error :: Status ( 401 , _) ) ) ;
133+
134+ let resp = ureq:: get ( & server. relative_path_to_url ( "file_a.yaml" ) )
135+ . set ( "Authorization" , "wrong_token" )
136+ . call ( ) ;
137+ assert ! ( resp. is_err( ) ) ;
138+ assert ! ( matches!( resp. unwrap_err( ) , ureq:: Error :: Status ( 401 , _) ) ) ;
139+
140+ let content = ureq:: get ( & server. relative_path_to_url ( "file_a.yaml" ) )
141+ . set ( "Authorization" , & format ! ( "Bearer {}" , token) )
142+ . call ( )
143+ . unwrap ( ) ;
144+ assert_eq ! ( content. status( ) , 200 ) ;
145+ assert_eq ! ( content. into_string( ) . unwrap( ) , "file: A" ) ;
146+ }
96147}
0 commit comments