@@ -2,7 +2,7 @@ use anyhow::{anyhow, Context, Result};
22use futures:: SinkExt ;
33use http:: {
44 header:: { ACCEPT_ENCODING , CACHE_CONTROL , CONTENT_ENCODING , CONTENT_TYPE , ETAG , IF_NONE_MATCH } ,
5- HeaderName , StatusCode ,
5+ HeaderName , StatusCode , Uri ,
66} ;
77use spin_sdk:: http:: { Fields , IncomingRequest , OutgoingResponse , ResponseOutparam } ;
88use std:: {
@@ -29,6 +29,8 @@ const GZIP_ENCODING: &str = "gzip";
2929const DEFLATE_ENCODING : & str = "deflate" ;
3030/// The path info header.
3131const PATH_INFO_HEADER : & str = "spin-path-info" ;
32+ /// The component route header
33+ const COMPONENT_ROUTE_HEADER : & str = "spin-component-route" ;
3234// Environment variable for the fallback path
3335const FALLBACK_PATH_ENV : & str = "FALLBACK_PATH" ;
3436/// Environment variable for the custom 404 path
@@ -88,19 +90,33 @@ impl ContentEncoding {
8890async fn handle_request ( req : IncomingRequest , res_out : ResponseOutparam ) {
8991 let headers = req. headers ( ) . entries ( ) ;
9092 let enc = ContentEncoding :: best_encoding ( & headers) ;
91-
92- let path = headers
93+ let mut path = headers
9394 . iter ( )
9495 . find_map ( |( k, v) | ( k. to_lowercase ( ) == PATH_INFO_HEADER ) . then_some ( v) )
9596 . expect ( "PATH_INFO header must be set by the Spin runtime" ) ;
9697
98+ let component_route = headers
99+ . iter ( )
100+ . find_map ( |( k, v) | ( k. to_lowercase ( ) == COMPONENT_ROUTE_HEADER ) . then_some ( v) )
101+ . expect ( "COMPONENT_ROUTE header must be set by the Spin runtime" ) ;
102+
103+ let uri = req
104+ . uri ( )
105+ . parse :: < Uri > ( )
106+ . expect ( "URI is invalid" )
107+ . path ( )
108+ . as_bytes ( )
109+ . to_vec ( ) ;
110+ if & uri == component_route && path. is_empty ( ) {
111+ path = & uri;
112+ }
113+
97114 let if_none_match = headers
98115 . iter ( )
99116 . find_map ( |( k, v) | {
100117 ( HeaderName :: from_bytes ( k. as_bytes ( ) ) . ok ( ) ? == IF_NONE_MATCH ) . then_some ( v. as_slice ( ) )
101118 } )
102119 . unwrap_or ( b"" ) ;
103-
104120 match FileServer :: make_response ( path, enc, if_none_match) {
105121 Ok ( ( status, headers, reader) ) => {
106122 let res = OutgoingResponse :: new ( status. into ( ) , & Fields :: new ( & headers) ) ;
0 commit comments