@@ -4,9 +4,14 @@ use crate::http::fields::header_map_from_wasi;
44use crate :: io:: { AsyncInputStream , AsyncOutputStream , AsyncRead , AsyncWrite , Cursor , Empty } ;
55use crate :: runtime:: AsyncPollable ;
66use core:: fmt;
7- use http:: header:: { CONTENT_LENGTH , TRANSFER_ENCODING } ;
7+ use http:: header:: CONTENT_LENGTH ;
88use wasi:: http:: types:: IncomingBody as WasiIncomingBody ;
99
10+ #[ cfg( feature = "json" ) ]
11+ use serde:: de:: DeserializeOwned ;
12+ #[ cfg( feature = "json" ) ]
13+ use serde_json;
14+
1015pub use super :: {
1116 error:: { Error , ErrorVariant } ,
1217 HeaderMap ,
@@ -26,8 +31,6 @@ impl BodyKind {
2631 . parse :: < u64 > ( )
2732 . map_err ( |_| InvalidContentLength ) ?;
2833 Ok ( BodyKind :: Fixed ( content_length) )
29- } else if headers. contains_key ( TRANSFER_ENCODING ) {
30- Ok ( BodyKind :: Chunked )
3134 } else {
3235 Ok ( BodyKind :: Chunked )
3336 }
@@ -176,6 +179,40 @@ impl IncomingBody {
176179
177180 Ok ( trailers)
178181 }
182+
183+ /// Try to deserialize the incoming body as JSON. The optional
184+ /// `json` feature is required.
185+ ///
186+ /// Fails whenever the response body is not in JSON format,
187+ /// or it cannot be properly deserialized to target type `T`. For more
188+ /// details please see [`serde_json::from_reader`].
189+ ///
190+ /// [`serde_json::from_reader`]: https://docs.serde.rs/serde_json/fn.from_reader.html
191+ #[ cfg( feature = "json" ) ]
192+ #[ cfg_attr( docsrs, doc( cfg( feature = "json" ) ) ) ]
193+ pub async fn json < T : DeserializeOwned > ( & mut self ) -> Result < T , Error > {
194+ let buf = self . bytes ( ) . await ?;
195+ serde_json:: from_slice ( & buf) . map_err ( |e| ErrorVariant :: Other ( e. to_string ( ) ) . into ( ) )
196+ }
197+
198+ /// Get the full response body as `Vec<u8>`.
199+ pub async fn bytes ( & mut self ) -> Result < Vec < u8 > , Error > {
200+ let mut buf = match self . kind {
201+ BodyKind :: Fixed ( l) => {
202+ if l > ( usize:: MAX as u64 ) {
203+ return Err ( ErrorVariant :: Other (
204+ "incoming body is too large to allocate and buffer in memory" . to_string ( ) ,
205+ )
206+ . into ( ) ) ;
207+ } else {
208+ Vec :: with_capacity ( l as usize )
209+ }
210+ }
211+ BodyKind :: Chunked => Vec :: with_capacity ( 4096 ) ,
212+ } ;
213+ self . read_to_end ( & mut buf) . await ?;
214+ Ok ( buf)
215+ }
179216}
180217
181218impl AsyncRead for IncomingBody {
0 commit comments