@@ -139,6 +139,8 @@ fn prepare_header_key(key: &str) -> String {
139139#[ cfg( test) ]
140140mod tests {
141141 use super :: * ;
142+ use anyhow:: Result ;
143+ use spin_http:: routes:: Router ;
142144
143145 #[ test]
144146 fn test_spin_header_keys ( ) {
@@ -155,4 +157,175 @@ mod tests {
155157 "spin-raw-component-route" . to_string( )
156158 ) ;
157159 }
160+
161+ #[ test]
162+ fn test_default_headers ( ) -> Result < ( ) > {
163+ let scheme = "https" ;
164+ let host = "fermyon.dev" ;
165+ let trigger_route = "/foo/..." ;
166+ let component_path = "/foo" ;
167+ let path_info = "/bar" ;
168+ let client_addr: SocketAddr = "127.0.0.1:8777" . parse ( ) . unwrap ( ) ;
169+
170+ let req_uri = format ! (
171+ "{}://{}{}{}?key1=value1&key2=value2" ,
172+ scheme, host, component_path, path_info
173+ ) ;
174+
175+ let req = http:: Request :: builder ( )
176+ . method ( "POST" )
177+ . uri ( req_uri)
178+ . body ( "" ) ?;
179+
180+ let ( router, _) = Router :: build ( "/" , [ ( "DUMMY" , & trigger_route. into ( ) ) ] ) ?;
181+ let route_match = router. route ( "/foo/bar" ) ?;
182+
183+ let default_headers = compute_default_headers ( req. uri ( ) , host, & route_match, client_addr) ?;
184+
185+ assert_eq ! (
186+ search( & FULL_URL , & default_headers) . unwrap( ) ,
187+ "https://fermyon.dev/foo/bar?key1=value1&key2=value2" . to_string( )
188+ ) ;
189+ assert_eq ! (
190+ search( & PATH_INFO , & default_headers) . unwrap( ) ,
191+ "/bar" . to_string( )
192+ ) ;
193+ assert_eq ! (
194+ search( & MATCHED_ROUTE , & default_headers) . unwrap( ) ,
195+ "/foo/..." . to_string( )
196+ ) ;
197+ assert_eq ! (
198+ search( & BASE_PATH , & default_headers) . unwrap( ) ,
199+ "/" . to_string( )
200+ ) ;
201+ assert_eq ! (
202+ search( & RAW_COMPONENT_ROUTE , & default_headers) . unwrap( ) ,
203+ "/foo/..." . to_string( )
204+ ) ;
205+ assert_eq ! (
206+ search( & COMPONENT_ROUTE , & default_headers) . unwrap( ) ,
207+ "/foo" . to_string( )
208+ ) ;
209+ assert_eq ! (
210+ search( & CLIENT_ADDR , & default_headers) . unwrap( ) ,
211+ "127.0.0.1:8777" . to_string( )
212+ ) ;
213+
214+ Ok ( ( ) )
215+ }
216+
217+ #[ test]
218+ fn test_default_headers_with_named_wildcards ( ) -> Result < ( ) > {
219+ let scheme = "https" ;
220+ let host = "fermyon.dev" ;
221+ let trigger_route = "/foo/:userid/..." ;
222+ let component_path = "/foo" ;
223+ let path_info = "/bar" ;
224+ let client_addr: SocketAddr = "127.0.0.1:8777" . parse ( ) . unwrap ( ) ;
225+
226+ let req_uri = format ! (
227+ "{}://{}{}/42{}?key1=value1&key2=value2" ,
228+ scheme, host, component_path, path_info
229+ ) ;
230+
231+ let req = http:: Request :: builder ( )
232+ . method ( "POST" )
233+ . uri ( req_uri)
234+ . body ( "" ) ?;
235+
236+ let ( router, _) = Router :: build ( "/" , [ ( "DUMMY" , & trigger_route. into ( ) ) ] ) ?;
237+ let route_match = router. route ( "/foo/42/bar" ) ?;
238+
239+ let default_headers = compute_default_headers ( req. uri ( ) , host, & route_match, client_addr) ?;
240+
241+ assert_eq ! (
242+ search( & FULL_URL , & default_headers) . unwrap( ) ,
243+ "https://fermyon.dev/foo/42/bar?key1=value1&key2=value2" . to_string( )
244+ ) ;
245+ assert_eq ! (
246+ search( & PATH_INFO , & default_headers) . unwrap( ) ,
247+ "/bar" . to_string( )
248+ ) ;
249+ assert_eq ! (
250+ search( & MATCHED_ROUTE , & default_headers) . unwrap( ) ,
251+ "/foo/:userid/..." . to_string( )
252+ ) ;
253+ assert_eq ! (
254+ search( & BASE_PATH , & default_headers) . unwrap( ) ,
255+ "/" . to_string( )
256+ ) ;
257+ assert_eq ! (
258+ search( & RAW_COMPONENT_ROUTE , & default_headers) . unwrap( ) ,
259+ "/foo/:userid/..." . to_string( )
260+ ) ;
261+ assert_eq ! (
262+ search( & COMPONENT_ROUTE , & default_headers) . unwrap( ) ,
263+ "/foo/:userid" . to_string( )
264+ ) ;
265+ assert_eq ! (
266+ search( & CLIENT_ADDR , & default_headers) . unwrap( ) ,
267+ "127.0.0.1:8777" . to_string( )
268+ ) ;
269+
270+ assert_eq ! (
271+ search(
272+ & [ "SPIN_PATH_MATCH_USERID" , "X_PATH_MATCH_USERID" ] ,
273+ & default_headers
274+ )
275+ . unwrap( ) ,
276+ "42" . to_string( )
277+ ) ;
278+
279+ Ok ( ( ) )
280+ }
281+
282+ #[ test]
283+ fn forbidden_headers_are_removed ( ) {
284+ let mut req = Request :: get ( "http://test.spin.internal" )
285+ . header ( "Host" , "test.spin.internal" )
286+ . header ( "accept" , "text/plain" )
287+ . body ( Default :: default ( ) )
288+ . unwrap ( ) ;
289+
290+ strip_forbidden_headers ( & mut req) ;
291+
292+ assert_eq ! ( 1 , req. headers( ) . len( ) ) ;
293+ assert ! ( req. headers( ) . get( "Host" ) . is_none( ) ) ;
294+
295+ let mut req = Request :: get ( "http://test.spin.internal" )
296+ . header ( "Host" , "test.spin.internal:1234" )
297+ . header ( "accept" , "text/plain" )
298+ . body ( Default :: default ( ) )
299+ . unwrap ( ) ;
300+
301+ strip_forbidden_headers ( & mut req) ;
302+
303+ assert_eq ! ( 1 , req. headers( ) . len( ) ) ;
304+ assert ! ( req. headers( ) . get( "Host" ) . is_none( ) ) ;
305+ }
306+
307+ #[ test]
308+ fn non_forbidden_headers_are_not_removed ( ) {
309+ let mut req = Request :: get ( "http://test.example.com" )
310+ . header ( "Host" , "test.example.org" )
311+ . header ( "accept" , "text/plain" )
312+ . body ( Default :: default ( ) )
313+ . unwrap ( ) ;
314+
315+ strip_forbidden_headers ( & mut req) ;
316+
317+ assert_eq ! ( 2 , req. headers( ) . len( ) ) ;
318+ assert ! ( req. headers( ) . get( "Host" ) . is_some( ) ) ;
319+ }
320+
321+ fn search ( keys : & [ & str ; 2 ] , headers : & [ ( [ String ; 2 ] , String ) ] ) -> Option < String > {
322+ let mut res: Option < String > = None ;
323+ for ( k, v) in headers {
324+ if k[ 0 ] == keys[ 0 ] && k[ 1 ] == keys[ 1 ] {
325+ res = Some ( v. clone ( ) ) ;
326+ }
327+ }
328+
329+ res
330+ }
158331}
0 commit comments