@@ -23,6 +23,8 @@ use std::borrow::Cow;
2323use std:: future:: ready;
2424use std:: { fmt, future:: Future , pin:: Pin } ;
2525
26+ const X_LAMBDA_HTTP_CONTENT_ENCODING : & str = "x-lambda-http-content-encoding" ;
27+
2628/// Representation of Lambda response
2729#[ doc( hidden) ]
2830#[ derive( Serialize , Debug ) ]
@@ -181,7 +183,7 @@ where
181183 return convert_to_binary ( self ) ;
182184 }
183185
184- let content_type = if let Some ( value) = headers. get ( http :: header :: CONTENT_TYPE ) {
186+ let content_type = if let Some ( value) = headers. get ( CONTENT_TYPE ) {
185187 value. to_str ( ) . unwrap_or_default ( )
186188 } else {
187189 // Content-Type and Content-Encoding not set, passthrough as utf8 text
@@ -199,6 +201,12 @@ where
199201 return convert_to_text ( self , content_type) ;
200202 }
201203
204+ if let Some ( value) = headers. get ( X_LAMBDA_HTTP_CONTENT_ENCODING ) {
205+ if value == "text" {
206+ return convert_to_text ( self , content_type) ;
207+ }
208+ }
209+
202210 convert_to_binary ( self )
203211 }
204212}
@@ -242,14 +250,16 @@ pub type BodyFuture = Pin<Box<dyn Future<Output = Body>>>;
242250
243251#[ cfg( test) ]
244252mod tests {
245- use super :: { Body , IntoResponse , LambdaResponse , RequestOrigin } ;
253+ use super :: { Body , IntoResponse , LambdaResponse , RequestOrigin , X_LAMBDA_HTTP_CONTENT_ENCODING } ;
246254 use http:: {
247255 header:: { CONTENT_ENCODING , CONTENT_TYPE } ,
248256 Response ,
249257 } ;
250258 use hyper:: Body as HyperBody ;
251259 use serde_json:: { self , json} ;
252260
261+ const SVG_LOGO : & str = include_str ! ( "../tests/data/svg_logo.svg" ) ;
262+
253263 #[ tokio:: test]
254264 async fn json_into_response ( ) {
255265 let response = json ! ( { "hello" : "lambda" } ) . into_response ( ) . await ;
@@ -388,4 +398,52 @@ mod tests {
388398 json
389399 )
390400 }
401+
402+ #[ tokio:: test]
403+ async fn content_type_xml_as_text ( ) {
404+ // Drive the implementation by using `hyper::Body` instead of
405+ // of `aws_lambda_events::encodings::Body`
406+ let response = Response :: builder ( )
407+ . header ( CONTENT_TYPE , "image/svg+xml" )
408+ . body ( HyperBody :: from ( SVG_LOGO . as_bytes ( ) ) )
409+ . expect ( "unable to build http::Response" ) ;
410+ let response = response. into_response ( ) . await ;
411+
412+ match response. body ( ) {
413+ Body :: Text ( body) => assert_eq ! ( SVG_LOGO , body) ,
414+ _ => panic ! ( "invalid body" ) ,
415+ }
416+ assert_eq ! (
417+ response
418+ . headers( )
419+ . get( CONTENT_TYPE )
420+ . map( |h| h. to_str( ) . expect( "invalid header" ) ) ,
421+ Some ( "image/svg+xml" )
422+ )
423+ }
424+
425+ #[ tokio:: test]
426+ async fn content_type_custom_encoding_as_text ( ) {
427+ // Drive the implementation by using `hyper::Body` instead of
428+ // of `aws_lambda_events::encodings::Body`
429+ let response = Response :: builder ( )
430+ // this CONTENT-TYPE is not standard, and would yield a binary response
431+ . header ( CONTENT_TYPE , "image/svg" )
432+ . header ( X_LAMBDA_HTTP_CONTENT_ENCODING , "text" )
433+ . body ( HyperBody :: from ( SVG_LOGO . as_bytes ( ) ) )
434+ . expect ( "unable to build http::Response" ) ;
435+ let response = response. into_response ( ) . await ;
436+
437+ match response. body ( ) {
438+ Body :: Text ( body) => assert_eq ! ( SVG_LOGO , body) ,
439+ _ => panic ! ( "invalid body" ) ,
440+ }
441+ assert_eq ! (
442+ response
443+ . headers( )
444+ . get( CONTENT_TYPE )
445+ . map( |h| h. to_str( ) . expect( "invalid header" ) ) ,
446+ Some ( "image/svg" )
447+ )
448+ }
391449}
0 commit comments