@@ -236,12 +236,19 @@ impl RequestExt for http::Request<Body> {
236
236
self . headers ( )
237
237
. get ( http:: header:: CONTENT_TYPE )
238
238
. map ( |ct| match ct. to_str ( ) {
239
- Ok ( "application/x-www-form-urlencoded" ) => serde_urlencoded:: from_bytes :: < D > ( self . body ( ) . as_ref ( ) )
240
- . map_err ( PayloadError :: WwwFormUrlEncoded )
241
- . map ( Some ) ,
242
- Ok ( "application/json" ) => serde_json:: from_slice :: < D > ( self . body ( ) . as_ref ( ) )
243
- . map_err ( PayloadError :: Json )
244
- . map ( Some ) ,
239
+ Ok ( content_type) => {
240
+ if content_type. starts_with ( "application/x-www-form-urlencoded" ) {
241
+ return serde_urlencoded:: from_bytes :: < D > ( self . body ( ) . as_ref ( ) )
242
+ . map_err ( PayloadError :: WwwFormUrlEncoded )
243
+ . map ( Some ) ;
244
+ } else if content_type. starts_with ( "application/json" ) {
245
+ return serde_json:: from_slice :: < D > ( self . body ( ) . as_ref ( ) )
246
+ . map_err ( PayloadError :: Json )
247
+ . map ( Some ) ;
248
+ }
249
+
250
+ Ok ( None )
251
+ }
245
252
_ => Ok ( None ) ,
246
253
} )
247
254
. unwrap_or_else ( || Ok ( None ) )
@@ -322,6 +329,48 @@ mod tests {
322
329
) ;
323
330
}
324
331
332
+ #[ test]
333
+ fn requests_match_form_post_content_type_with_charset ( ) {
334
+ #[ derive( Deserialize , PartialEq , Debug ) ]
335
+ struct Payload {
336
+ foo : String ,
337
+ baz : usize ,
338
+ }
339
+ let request = http:: Request :: builder ( )
340
+ . header ( "Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" )
341
+ . body ( Body :: from ( "foo=bar&baz=2" ) )
342
+ . expect ( "failed to build request" ) ;
343
+ let payload: Option < Payload > = request. payload ( ) . unwrap_or_default ( ) ;
344
+ assert_eq ! (
345
+ payload,
346
+ Some ( Payload {
347
+ foo: "bar" . into( ) ,
348
+ baz: 2
349
+ } )
350
+ ) ;
351
+ }
352
+
353
+ #[ test]
354
+ fn requests_match_json_content_type_with_charset ( ) {
355
+ #[ derive( Deserialize , PartialEq , Debug ) ]
356
+ struct Payload {
357
+ foo : String ,
358
+ baz : usize ,
359
+ }
360
+ let request = http:: Request :: builder ( )
361
+ . header ( "Content-Type" , "application/json; charset=UTF-8" )
362
+ . body ( Body :: from ( r#"{"foo":"bar", "baz": 2}"# ) )
363
+ . expect ( "failed to build request" ) ;
364
+ let payload: Option < Payload > = request. payload ( ) . unwrap_or_default ( ) ;
365
+ assert_eq ! (
366
+ payload,
367
+ Some ( Payload {
368
+ foo: "bar" . into( ) ,
369
+ baz: 2
370
+ } )
371
+ ) ;
372
+ }
373
+
325
374
#[ test]
326
375
fn requests_omiting_content_types_do_not_support_parseable_payloads ( ) {
327
376
#[ derive( Deserialize , PartialEq , Debug ) ]
0 commit comments