@@ -279,32 +279,27 @@ impl HttpClient {
279
279
}
280
280
}
281
281
282
- if !status. is_ok ( ) {
283
- // TODO: Handle 3xx redirection responses.
284
- return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: NotFound , "not found" ) ) ;
285
- }
286
-
287
282
// Read message body
288
283
let read_limit = MAX_HTTP_MESSAGE_BODY_SIZE - reader. buffer ( ) . len ( ) ;
289
284
reader. get_mut ( ) . set_limit ( read_limit as u64 ) ;
290
- match message_length {
291
- HttpMessageLength :: Empty => { Ok ( Vec :: new ( ) ) } ,
285
+ let contents = match message_length {
286
+ HttpMessageLength :: Empty => { Vec :: new ( ) } ,
292
287
HttpMessageLength :: ContentLength ( length) => {
293
288
if length == 0 || length > MAX_HTTP_MESSAGE_BODY_SIZE {
294
- Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidData , "out of range" ) )
289
+ return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidData , "out of range" ) )
295
290
} else {
296
291
let mut content = vec ! [ 0 ; length] ;
297
292
#[ cfg( feature = "tokio" ) ]
298
293
reader. read_exact ( & mut content[ ..] ) . await ?;
299
294
#[ cfg( not( feature = "tokio" ) ) ]
300
295
reader. read_exact ( & mut content[ ..] ) ?;
301
- Ok ( content)
296
+ content
302
297
}
303
298
} ,
304
299
HttpMessageLength :: TransferEncoding ( coding) => {
305
300
if !coding. eq_ignore_ascii_case ( "chunked" ) {
306
- Err ( std:: io:: Error :: new (
307
- std:: io:: ErrorKind :: InvalidInput , "unsupported transfer coding" ) )
301
+ return Err ( std:: io:: Error :: new (
302
+ std:: io:: ErrorKind :: InvalidInput , "unsupported transfer coding" ) )
308
303
} else {
309
304
let mut content = Vec :: new ( ) ;
310
305
#[ cfg( feature = "tokio" ) ]
@@ -339,17 +334,30 @@ impl HttpClient {
339
334
reader. read_exact ( & mut content[ chunk_offset..] ) . await ?;
340
335
content. resize ( chunk_offset + chunk_size, 0 ) ;
341
336
}
342
- Ok ( content)
337
+ content
343
338
}
344
339
#[ cfg( not( feature = "tokio" ) ) ]
345
340
{
346
341
let mut decoder = chunked_transfer:: Decoder :: new ( reader) ;
347
342
decoder. read_to_end ( & mut content) ?;
348
- Ok ( content)
343
+ content
349
344
}
350
345
}
351
346
} ,
347
+ } ;
348
+
349
+ if !status. is_ok ( ) {
350
+ // TODO: Handle 3xx redirection responses.
351
+ let error_details = match contents. is_ascii ( ) {
352
+ true => String :: from_utf8_lossy ( & contents) . to_string ( ) ,
353
+ false => "binary" . to_string ( )
354
+ } ;
355
+ let error_msg = format ! ( "Errored with status: {} and contents: {}" ,
356
+ status. code, error_details) ;
357
+ return Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , error_msg) ) ;
352
358
}
359
+
360
+ Ok ( contents)
353
361
}
354
362
}
355
363
@@ -720,6 +728,23 @@ pub(crate) mod client_tests {
720
728
}
721
729
}
722
730
731
+ #[ tokio:: test]
732
+ async fn read_error ( ) {
733
+ let response = String :: from (
734
+ "HTTP/1.1 500 Internal Server Error\r \n \
735
+ Content-Length: 10\r \n \r \n test error\r \n ") ;
736
+ let server = HttpServer :: responding_with ( response) ;
737
+
738
+ let mut client = HttpClient :: connect ( & server. endpoint ( ) ) . unwrap ( ) ;
739
+ match client. get :: < JsonResponse > ( "/foo" , "foo.com" ) . await {
740
+ Err ( e) => {
741
+ assert_eq ! ( e. get_ref( ) . unwrap( ) . to_string( ) , "Errored with status: 500 and contents: test error" ) ;
742
+ assert_eq ! ( e. kind( ) , std:: io:: ErrorKind :: Other ) ;
743
+ } ,
744
+ Ok ( _) => panic ! ( "Expected error" ) ,
745
+ }
746
+ }
747
+
723
748
#[ tokio:: test]
724
749
async fn read_empty_message_body ( ) {
725
750
let server = HttpServer :: responding_with_ok :: < String > ( MessageBody :: Empty ) ;
0 commit comments