1
1
use actix_files:: NamedFile ;
2
- use actix_web:: { HttpRequest , Responder } ;
2
+ use actix_web:: { HttpRequest , HttpResponse } ;
3
+ use std:: path:: { Path , PathBuf } ;
4
+ use tokio:: fs;
3
5
4
- pub async fn dist ( req : HttpRequest ) -> impl Responder {
5
- let path = req. path ( ) ;
6
- NamedFile :: open_async ( format ! ( "/explore/html/{}" , path) )
7
- . await
8
- . unwrap_or ( NamedFile :: open_async ( "/explore/html/index.html" ) . await . unwrap ( ) )
9
- . prefer_utf8 ( true )
10
- . use_etag ( true )
11
- . use_last_modified ( true )
6
+ pub async fn dist ( req : HttpRequest ) -> HttpResponse {
7
+ let base = Path :: new ( "/explore/html" ) ;
8
+ let request_path = req. path ( ) . trim_matches ( '/' ) ;
9
+ let file_path = resolve_file_path ( base, request_path) . await ;
10
+ match NamedFile :: open_async ( & file_path) . await {
11
+ Ok ( named_file) => {
12
+ named_file
13
+ . prefer_utf8 ( true )
14
+ . use_etag ( true )
15
+ . use_last_modified ( true )
16
+ . into_response ( & req)
17
+ }
18
+ Err ( _) => {
19
+ NamedFile :: open_async ( base. join ( "index.html" ) )
20
+ . await
21
+ . map ( |f| f. into_response ( & req) )
22
+ . unwrap_or_else ( |_|
23
+ HttpResponse :: NotFound ( )
24
+ . content_type ( "text/html" )
25
+ . body ( "<h1>404 Not Found</h1>" )
26
+ )
27
+ }
28
+ }
29
+ }
30
+
31
+ async fn resolve_file_path ( base : & Path , request_path : & str ) -> PathBuf {
32
+ if request_path. is_empty ( ) {
33
+ return base. join ( "index.html" ) ;
34
+ }
35
+ let full_path = base. join ( request_path) ;
36
+ if let Ok ( metadata) = fs:: metadata ( & full_path) . await {
37
+ if metadata. is_dir ( ) {
38
+ return full_path. join ( "index.html" ) ;
39
+ }
40
+ }
41
+ full_path
12
42
}
0 commit comments