mirror of https://github.com/rwf2/Rocket.git
Eagerly read JSON data for deserialization.
Issue #547 identified a performance issue when serde's 'from_reader' is used to deserialize incoming data. Using 'from_str' resolves the issue. This commit swaps a use of 'from_reader' in favor of 'from_str' in rocket_contrib's 'Json' implementation. Additionally, this commit ensures that un-deserialized JSON data is discarded as long as it is within the JSON data limit. Closes #562.
This commit is contained in:
parent
d0f002c3d7
commit
6b608797a2
|
@ -15,6 +15,22 @@ use serde_json;
|
|||
pub use serde_json::Value;
|
||||
pub use serde_json::error::Error as SerdeError;
|
||||
|
||||
/// Like [`from_reader`] but eagerly reads the content of the reader to a string
|
||||
/// and delegates to `from_str`.
|
||||
///
|
||||
/// [`from_reader`]: https://docs.serde.rs/serde_json/fn.from_reader.html
|
||||
fn from_reader_eager<R, T>(mut reader: R) -> serde_json::Result<T>
|
||||
where R: Read, T: DeserializeOwned
|
||||
{
|
||||
let mut s = String::new();
|
||||
if let Err(io_err) = reader.read_to_string(&mut s) {
|
||||
// Error::io is private to serde_json. Do not use outside of Rocket.
|
||||
return Err(SerdeError::io(io_err));
|
||||
}
|
||||
|
||||
serde_json::from_str(&s)
|
||||
}
|
||||
|
||||
/// The JSON type: implements `FromData` and `Responder`, allowing you to easily
|
||||
/// consume and respond with JSON.
|
||||
///
|
||||
|
@ -98,7 +114,7 @@ impl<T: DeserializeOwned> FromData for Json<T> {
|
|||
}
|
||||
|
||||
let size_limit = request.limits().get("json").unwrap_or(LIMIT);
|
||||
serde_json::from_reader(data.open().take(size_limit))
|
||||
from_reader_eager(data.open().take(size_limit))
|
||||
.map(|val| Json(val))
|
||||
.map_err(|e| { error_!("Couldn't parse JSON body: {:?}", e); e })
|
||||
.into_outcome(Status::BadRequest)
|
||||
|
|
Loading…
Reference in New Issue