@@ -23,6 +23,8 @@ use std::borrow::Cow;
23
23
use std:: future:: ready;
24
24
use std:: { fmt, future:: Future , pin:: Pin } ;
25
25
26
+ const X_LAMBDA_HTTP_CONTENT_ENCODING : & str = "x-lambda-http-content-encoding" ;
27
+
26
28
/// Representation of Lambda response
27
29
#[ doc( hidden) ]
28
30
#[ derive( Serialize , Debug ) ]
@@ -181,7 +183,7 @@ where
181
183
return convert_to_binary ( self ) ;
182
184
}
183
185
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 ) {
185
187
value. to_str ( ) . unwrap_or_default ( )
186
188
} else {
187
189
// Content-Type and Content-Encoding not set, passthrough as utf8 text
@@ -199,6 +201,12 @@ where
199
201
return convert_to_text ( self , content_type) ;
200
202
}
201
203
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
+
202
210
convert_to_binary ( self )
203
211
}
204
212
}
@@ -242,14 +250,16 @@ pub type BodyFuture = Pin<Box<dyn Future<Output = Body>>>;
242
250
243
251
#[ cfg( test) ]
244
252
mod tests {
245
- use super :: { Body , IntoResponse , LambdaResponse , RequestOrigin } ;
253
+ use super :: { Body , IntoResponse , LambdaResponse , RequestOrigin , X_LAMBDA_HTTP_CONTENT_ENCODING } ;
246
254
use http:: {
247
255
header:: { CONTENT_ENCODING , CONTENT_TYPE } ,
248
256
Response ,
249
257
} ;
250
258
use hyper:: Body as HyperBody ;
251
259
use serde_json:: { self , json} ;
252
260
261
+ const SVG_LOGO : & str = include_str ! ( "../tests/data/svg_logo.svg" ) ;
262
+
253
263
#[ tokio:: test]
254
264
async fn json_into_response ( ) {
255
265
let response = json ! ( { "hello" : "lambda" } ) . into_response ( ) . await ;
@@ -388,4 +398,52 @@ mod tests {
388
398
json
389
399
)
390
400
}
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
+ }
391
449
}
0 commit comments