@@ -122,7 +122,35 @@ where
122122 let path_with_ext = path. with_extension ( SQL_EXTENSION ) ;
123123 match find_file ( & path_with_ext, SQL_EXTENSION , store) . await ? {
124124 Some ( action) => Ok ( action) ,
125- None => Ok ( Redirect ( append_to_path ( path_and_query, FORWARD_SLASH ) ) ) ,
125+ None => {
126+ // Before redirecting to add trailing slash, check if the result would be a 404
127+ let mut path_with_slash = path. clone ( ) ;
128+ path_with_slash. push ( INDEX ) ;
129+ match find_file ( & path_with_slash, SQL_EXTENSION , store) . await ? {
130+ Some ( _) => {
131+ // There's an index.sql file, so redirect to trailing slash
132+ Ok ( Redirect ( append_to_path ( path_and_query, FORWARD_SLASH ) ) )
133+ }
134+ None => {
135+ // No index.sql file found. Check if this would result in a custom 404
136+ let not_found_result = find_not_found ( & path_with_slash, store) . await ?;
137+ match not_found_result {
138+ CustomNotFound ( _) => {
139+ // There's a custom 404.sql that would handle this, don't redirect
140+ Ok ( not_found_result)
141+ }
142+ NotFound => {
143+ // No custom 404, so redirect to trailing slash for consistency
144+ Ok ( Redirect ( append_to_path ( path_and_query, FORWARD_SLASH ) ) )
145+ }
146+ Execute ( _) | Redirect ( _) | Serve ( _) => {
147+ // These shouldn't happen from find_not_found, but handle them
148+ Ok ( not_found_result)
149+ }
150+ }
151+ }
152+ }
153+ }
126154 }
127155 }
128156}
@@ -332,6 +360,22 @@ mod tests {
332360
333361 assert_eq ! ( expected, actual) ;
334362 }
363+
364+ #[ tokio:: test]
365+ async fn no_extension_path_that_would_result_in_404_does_not_redirect ( ) {
366+ let actual = do_route ( "/nonexistent" , Default , None ) . await ;
367+ let expected = custom_not_found ( "404.sql" ) ;
368+
369+ assert_eq ! ( expected, actual) ;
370+ }
371+
372+ #[ tokio:: test]
373+ async fn no_extension_path_that_would_result_in_404_does_not_redirect_with_site_prefix ( ) {
374+ let actual = do_route ( "/prefix/nonexistent" , Default , Some ( "/prefix/" ) ) . await ;
375+ let expected = custom_not_found ( "404.sql" ) ;
376+
377+ assert_eq ! ( expected, actual) ;
378+ }
335379 }
336380
337381 mod not_found {
@@ -402,8 +446,8 @@ mod tests {
402446 }
403447
404448 mod redirect {
405- use super :: StoreConfig :: Default ;
406- use super :: { do_route, redirect} ;
449+ use super :: StoreConfig :: { Default , Empty } ;
450+ use super :: { custom_not_found , do_route, redirect} ;
407451
408452 #[ tokio:: test]
409453 async fn path_without_site_prefix_redirects_to_site_prefix ( ) {
@@ -414,26 +458,34 @@ mod tests {
414458 }
415459
416460 #[ tokio:: test]
417- async fn no_extension_and_no_corresponding_file_redirects_with_trailing_slash ( ) {
461+ async fn no_extension_and_no_corresponding_file_with_custom_404_does_not_redirect ( ) {
418462 let actual = do_route ( "/folder" , Default , None ) . await ;
419- let expected = redirect ( "/folder/ ") ;
463+ let expected = custom_not_found ( "404.sql ") ;
420464
421465 assert_eq ! ( expected, actual) ;
422466 }
423467
424468 #[ tokio:: test]
425- async fn no_extension_no_corresponding_file_redirects_with_trailing_slash_and_query ( ) {
469+ async fn no_extension_no_corresponding_file_with_custom_404_does_not_redirect_with_query ( ) {
426470 let actual = do_route ( "/folder?misc=1&foo=bar" , Default , None ) . await ;
427- let expected = redirect ( "/folder/?misc=1&foo=bar ") ;
471+ let expected = custom_not_found ( "404.sql ") ;
428472
429473 assert_eq ! ( expected, actual) ;
430474 }
431475
432476 #[ tokio:: test]
433- async fn no_extension_site_prefix_and_no_corresponding_file_redirects_with_trailing_slash ( )
477+ async fn no_extension_site_prefix_and_no_corresponding_file_with_custom_404_does_not_redirect ( )
434478 {
435479 let actual = do_route ( "/prefix/folder" , Default , Some ( "/prefix/" ) ) . await ;
436- let expected = redirect ( "/prefix/folder/" ) ;
480+ let expected = custom_not_found ( "404.sql" ) ;
481+
482+ assert_eq ! ( expected, actual) ;
483+ }
484+
485+ #[ tokio:: test]
486+ async fn no_extension_redirects_when_no_custom_404_available ( ) {
487+ let actual = do_route ( "/folder" , Empty , None ) . await ;
488+ let expected = redirect ( "/folder/" ) ;
437489
438490 assert_eq ! ( expected, actual) ;
439491 }
0 commit comments