@@ -4,12 +4,13 @@ use async_std::io::{self, BufReader, Read, Write};
44use async_std:: prelude:: * ;
55use async_std:: task:: { Context , Poll } ;
66use futures_core:: ready;
7+ use http_types:: { ensure, ensure_eq, format_err} ;
78use http_types:: {
89 headers:: { HeaderName , HeaderValue , CONTENT_LENGTH , DATE , TRANSFER_ENCODING } ,
910 Body , Request , Response , StatusCode ,
1011} ;
11- use http_types:: { Error , ErrorKind } ;
1212
13+ use std:: convert:: TryFrom ;
1314use std:: pin:: Pin ;
1415use std:: str:: FromStr ;
1516
@@ -50,7 +51,7 @@ impl Encoder {
5051}
5152
5253/// Opens an HTTP/1.1 connection to a remote host.
53- pub async fn connect < RW > ( mut stream : RW , req : Request ) -> Result < Response , Error >
54+ pub async fn connect < RW > ( mut stream : RW , req : Request ) -> http_types :: Result < Response >
5455where
5556 RW : Read + Write + Send + Sync + Unpin + ' static ,
5657{
6768
6869/// Encode an HTTP request on the client.
6970#[ doc( hidden) ]
70- async fn encode ( req : Request ) -> Result < Encoder , Error > {
71+ async fn encode ( req : Request ) -> http_types :: Result < Encoder > {
7172 let mut buf: Vec < u8 > = vec ! [ ] ;
7273
7374 let mut url = req. url ( ) . path ( ) . to_owned ( ) ;
@@ -86,13 +87,8 @@ async fn encode(req: Request) -> Result<Encoder, Error> {
8687
8788 // Insert Host header
8889 // Insert host
89- let host = req. url ( ) . host_str ( ) . ok_or_else ( || {
90- Error :: from_str (
91- ErrorKind :: InvalidInput ,
92- "missing hostname" ,
93- StatusCode :: BadRequest ,
94- )
95- } ) ?;
90+ let host = req. url ( ) . host_str ( ) ;
91+ let host = host. ok_or_else ( || format_err ! ( "Missing hostname" ) ) ?;
9692 let val = if let Some ( port) = req. url ( ) . port ( ) {
9793 format ! ( "host: {}:{}\r \n " , host, port)
9894 } else {
@@ -135,7 +131,7 @@ async fn encode(req: Request) -> Result<Encoder, Error> {
135131
136132/// Decode an HTTP response on the client.
137133#[ doc( hidden) ]
138- pub async fn decode < R > ( reader : R ) -> Result < Response , Error >
134+ pub async fn decode < R > ( reader : R ) -> http_types :: Result < Response >
139135where
140136 R : Read + Unpin + Send + Sync + ' static ,
141137{
@@ -148,9 +144,7 @@ where
148144 loop {
149145 let bytes_read = reader. read_until ( b'\n' , & mut buf) . await ?;
150146 // No more bytes are yielded from the stream.
151- if bytes_read == 0 {
152- panic ! ( "empty response" ) ;
153- }
147+ assert ! ( bytes_read != 0 , "Empty response" ) ; // TODO: ensure?
154148
155149 // We've hit the end delimiter of the stream.
156150 let idx = buf. len ( ) - 1 ;
@@ -161,37 +155,16 @@ where
161155
162156 // Convert our header buf into an httparse instance, and validate.
163157 let status = httparse_res. parse ( & buf) ?;
164- if status. is_partial ( ) {
165- return Err ( Error :: from_str (
166- ErrorKind :: InvalidData ,
167- "Malformed HTTP head" ,
168- StatusCode :: BadRequest ,
169- ) ) ;
170- }
171- let code = httparse_res. code . ok_or_else ( || {
172- Error :: from_str (
173- ErrorKind :: InvalidData ,
174- "No status code found" ,
175- StatusCode :: BadRequest ,
176- )
177- } ) ?;
178-
179- // Convert httparse headers + body into a `http::Response` type.
180- let version = httparse_res. version . ok_or_else ( || {
181- Error :: from_str (
182- ErrorKind :: InvalidData ,
183- "No version found" ,
184- StatusCode :: BadRequest ,
185- )
186- } ) ?;
187- if version != 1 {
188- return Err ( Error :: from_str (
189- ErrorKind :: InvalidData ,
190- "Unsupported HTTP version" ,
191- StatusCode :: BadRequest ,
192- ) ) ;
193- }
194- use std:: convert:: TryFrom ;
158+ ensure ! ( !status. is_partial( ) , "Malformed HTTP head" ) ;
159+
160+ let code = httparse_res. code ;
161+ let code = code. ok_or_else ( || format_err ! ( "No status code found" ) ) ?;
162+
163+ // Convert httparse headers + body into a `http_types::Response` type.
164+ let version = httparse_res. version ;
165+ let version = version. ok_or_else ( || format_err ! ( "No version found" ) ) ?;
166+ ensure_eq ! ( version, 1 , "Unsupported HTTP version" ) ;
167+
195168 let mut res = Response :: new ( StatusCode :: try_from ( code) ?) ;
196169 for header in httparse_res. headers . iter ( ) {
197170 let name = HeaderName :: from_str ( header. name ) ?;
@@ -207,24 +180,18 @@ where
207180 let content_length = res. header ( & CONTENT_LENGTH ) ;
208181 let transfer_encoding = res. header ( & TRANSFER_ENCODING ) ;
209182
210- if content_length. is_some ( ) && transfer_encoding. is_some ( ) {
211- // This is always an error.
212- return Err ( Error :: from_str (
213- ErrorKind :: InvalidData ,
214- "Unexpected Content-Length header" ,
215- StatusCode :: BadRequest ,
216- ) ) ;
217- }
183+ ensure ! (
184+ content_length. is_none( ) || transfer_encoding. is_none( ) ,
185+ "Unexpected Content-Length header"
186+ ) ;
218187
219188 // Check for Transfer-Encoding
220189 match transfer_encoding {
221190 Some ( encoding) if !encoding. is_empty ( ) => {
222191 if encoding. last ( ) . unwrap ( ) . as_str ( ) == "chunked" {
223192 let trailers_sender = res. send_trailers ( ) ;
224- res. set_body ( Body :: from_reader (
225- BufReader :: new ( ChunkedDecoder :: new ( reader, trailers_sender) ) ,
226- None ,
227- ) ) ;
193+ let reader = BufReader :: new ( ChunkedDecoder :: new ( reader, trailers_sender) ) ;
194+ res. set_body ( Body :: from_reader ( reader, None ) ) ;
228195 return Ok ( res) ;
229196 }
230197 // Fall through to Content-Length
0 commit comments