Skip to content

Commit 04712a3

Browse files
authored
fix: fix RequestExt.payload() for content-type with charset (#255)
* fix: fix RequestExt.payload() for content-type with charset * fix: cargo fmt
1 parent 0009201 commit 04712a3

File tree

1 file changed

+55
-6
lines changed

1 file changed

+55
-6
lines changed

lambda-http/src/ext.rs

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -236,12 +236,19 @@ impl RequestExt for http::Request<Body> {
236236
self.headers()
237237
.get(http::header::CONTENT_TYPE)
238238
.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+
}
245252
_ => Ok(None),
246253
})
247254
.unwrap_or_else(|| Ok(None))
@@ -322,6 +329,48 @@ mod tests {
322329
);
323330
}
324331

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+
325374
#[test]
326375
fn requests_omiting_content_types_do_not_support_parseable_payloads() {
327376
#[derive(Deserialize, PartialEq, Debug)]

0 commit comments

Comments
 (0)