@@ -4,12 +4,13 @@ use async_std::io::{self, BufReader, Read, Write};
4
4
use async_std:: prelude:: * ;
5
5
use async_std:: task:: { Context , Poll } ;
6
6
use futures_core:: ready;
7
+ use http_types:: { ensure, ensure_eq, format_err} ;
7
8
use http_types:: {
8
9
headers:: { HeaderName , HeaderValue , CONTENT_LENGTH , DATE , TRANSFER_ENCODING } ,
9
10
Body , Request , Response , StatusCode ,
10
11
} ;
11
- use http_types:: { Error , ErrorKind } ;
12
12
13
+ use std:: convert:: TryFrom ;
13
14
use std:: pin:: Pin ;
14
15
use std:: str:: FromStr ;
15
16
@@ -50,7 +51,7 @@ impl Encoder {
50
51
}
51
52
52
53
/// 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 >
54
55
where
55
56
RW : Read + Write + Send + Sync + Unpin + ' static ,
56
57
{
67
68
68
69
/// Encode an HTTP request on the client.
69
70
#[ doc( hidden) ]
70
- async fn encode ( req : Request ) -> Result < Encoder , Error > {
71
+ async fn encode ( req : Request ) -> http_types :: Result < Encoder > {
71
72
let mut buf: Vec < u8 > = vec ! [ ] ;
72
73
73
74
let mut url = req. url ( ) . path ( ) . to_owned ( ) ;
@@ -86,13 +87,8 @@ async fn encode(req: Request) -> Result<Encoder, Error> {
86
87
87
88
// Insert Host header
88
89
// 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" ) ) ?;
96
92
let val = if let Some ( port) = req. url ( ) . port ( ) {
97
93
format ! ( "host: {}:{}\r \n " , host, port)
98
94
} else {
@@ -135,7 +131,7 @@ async fn encode(req: Request) -> Result<Encoder, Error> {
135
131
136
132
/// Decode an HTTP response on the client.
137
133
#[ 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 >
139
135
where
140
136
R : Read + Unpin + Send + Sync + ' static ,
141
137
{
@@ -148,9 +144,7 @@ where
148
144
loop {
149
145
let bytes_read = reader. read_until ( b'\n' , & mut buf) . await ?;
150
146
// 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?
154
148
155
149
// We've hit the end delimiter of the stream.
156
150
let idx = buf. len ( ) - 1 ;
@@ -161,37 +155,16 @@ where
161
155
162
156
// Convert our header buf into an httparse instance, and validate.
163
157
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
+
195
168
let mut res = Response :: new ( StatusCode :: try_from ( code) ?) ;
196
169
for header in httparse_res. headers . iter ( ) {
197
170
let name = HeaderName :: from_str ( header. name ) ?;
@@ -207,24 +180,18 @@ where
207
180
let content_length = res. header ( & CONTENT_LENGTH ) ;
208
181
let transfer_encoding = res. header ( & TRANSFER_ENCODING ) ;
209
182
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
+ ) ;
218
187
219
188
// Check for Transfer-Encoding
220
189
match transfer_encoding {
221
190
Some ( encoding) if !encoding. is_empty ( ) => {
222
191
if encoding. last ( ) . unwrap ( ) . as_str ( ) == "chunked" {
223
192
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 ) ) ;
228
195
return Ok ( res) ;
229
196
}
230
197
// Fall through to Content-Length
0 commit comments