@@ -22,6 +22,7 @@ use crate::aws::{
22
22
AwsAuthorizer , AwsCredentialProvider , S3ConditionalPut , S3CopyIfNotExists , COPY_SOURCE_HEADER ,
23
23
STORE , STRICT_PATH_ENCODE_SET , TAGS_HEADER ,
24
24
} ;
25
+ use crate :: client:: builder:: { HttpRequestBuilder , RequestBuilderError } ;
25
26
use crate :: client:: get:: GetClient ;
26
27
use crate :: client:: header:: { get_etag, HeaderConfig } ;
27
28
use crate :: client:: header:: { get_put_result, get_version} ;
@@ -31,7 +32,7 @@ use crate::client::s3::{
31
32
CompleteMultipartUpload , CompleteMultipartUploadResult , CopyPartResult ,
32
33
InitiateMultipartUploadResult , ListResponse , PartMetadata ,
33
34
} ;
34
- use crate :: client:: GetOptionsExt ;
35
+ use crate :: client:: { GetOptionsExt , HttpClient , HttpError , HttpResponse } ;
35
36
use crate :: multipart:: PartId ;
36
37
use crate :: path:: DELIMITER ;
37
38
use crate :: {
@@ -42,17 +43,15 @@ use async_trait::async_trait;
42
43
use base64:: prelude:: BASE64_STANDARD ;
43
44
use base64:: Engine ;
44
45
use bytes:: { Buf , Bytes } ;
45
- use hyper :: header:: {
46
+ use http :: header:: {
46
47
CACHE_CONTROL , CONTENT_DISPOSITION , CONTENT_ENCODING , CONTENT_LANGUAGE , CONTENT_LENGTH ,
47
48
CONTENT_TYPE ,
48
49
} ;
49
- use hyper:: http:: HeaderName ;
50
- use hyper:: { http, HeaderMap } ;
50
+ use http:: { HeaderMap , HeaderName , Method } ;
51
51
use itertools:: Itertools ;
52
52
use md5:: { Digest , Md5 } ;
53
53
use percent_encoding:: { utf8_percent_encode, PercentEncode } ;
54
54
use quick_xml:: events:: { self as xml_events} ;
55
- use reqwest:: { Client as ReqwestClient , Method , RequestBuilder , Response } ;
56
55
use ring:: digest;
57
56
use ring:: digest:: Context ;
58
57
use serde:: { Deserialize , Serialize } ;
@@ -67,7 +66,9 @@ const ALGORITHM: &str = "x-amz-checksum-algorithm";
67
66
#[ derive( Debug , thiserror:: Error ) ]
68
67
pub ( crate ) enum Error {
69
68
#[ error( "Error performing DeleteObjects request: {}" , source) ]
70
- DeleteObjectsRequest { source : crate :: client:: retry:: Error } ,
69
+ DeleteObjectsRequest {
70
+ source : crate :: client:: retry:: RetryError ,
71
+ } ,
71
72
72
73
#[ error(
73
74
"DeleteObjects request failed for key {}: {} (code: {})" ,
@@ -82,30 +83,32 @@ pub(crate) enum Error {
82
83
} ,
83
84
84
85
#[ error( "Error getting DeleteObjects response body: {}" , source) ]
85
- DeleteObjectsResponse { source : reqwest :: Error } ,
86
+ DeleteObjectsResponse { source : HttpError } ,
86
87
87
88
#[ error( "Got invalid DeleteObjects response: {}" , source) ]
88
89
InvalidDeleteObjectsResponse {
89
90
source : Box < dyn std:: error:: Error + Send + Sync + ' static > ,
90
91
} ,
91
92
92
93
#[ error( "Error performing list request: {}" , source) ]
93
- ListRequest { source : crate :: client:: retry:: Error } ,
94
+ ListRequest {
95
+ source : crate :: client:: retry:: RetryError ,
96
+ } ,
94
97
95
98
#[ error( "Error getting list response body: {}" , source) ]
96
- ListResponseBody { source : reqwest :: Error } ,
99
+ ListResponseBody { source : HttpError } ,
97
100
98
101
#[ error( "Error getting create multipart response body: {}" , source) ]
99
- CreateMultipartResponseBody { source : reqwest :: Error } ,
102
+ CreateMultipartResponseBody { source : HttpError } ,
100
103
101
104
#[ error( "Error performing complete multipart request: {}: {}" , path, source) ]
102
105
CompleteMultipartRequest {
103
- source : crate :: client:: retry:: Error ,
106
+ source : crate :: client:: retry:: RetryError ,
104
107
path : String ,
105
108
} ,
106
109
107
110
#[ error( "Error getting complete multipart response body: {}" , source) ]
108
- CompleteMultipartResponseBody { source : reqwest :: Error } ,
111
+ CompleteMultipartResponseBody { source : HttpError } ,
109
112
110
113
#[ error( "Got invalid list response: {}" , source) ]
111
114
InvalidListResponse { source : quick_xml:: de:: DeError } ,
@@ -272,7 +275,7 @@ pub enum RequestError {
272
275
273
276
#[ error( "Retry" ) ]
274
277
Retry {
275
- source : crate :: client:: retry:: Error ,
278
+ source : crate :: client:: retry:: RetryError ,
276
279
path : String ,
277
280
} ,
278
281
}
@@ -290,7 +293,7 @@ impl From<RequestError> for crate::Error {
290
293
pub ( crate ) struct Request < ' a > {
291
294
path : & ' a Path ,
292
295
config : & ' a S3Config ,
293
- builder : RequestBuilder ,
296
+ builder : HttpRequestBuilder ,
294
297
payload_sha256 : Option < digest:: Digest > ,
295
298
payload : Option < PutPayload > ,
296
299
use_session_creds : bool ,
@@ -307,8 +310,8 @@ impl Request<'_> {
307
310
308
311
pub ( crate ) fn header < K > ( self , k : K , v : & str ) -> Self
309
312
where
310
- HeaderName : TryFrom < K > ,
311
- < HeaderName as TryFrom < K > > :: Error : Into < http :: Error > ,
313
+ K : TryInto < HeaderName > ,
314
+ K :: Error : Into < RequestBuilderError > ,
312
315
{
313
316
let builder = self . builder . header ( k, v) ;
314
317
Self { builder, ..self }
@@ -408,7 +411,7 @@ impl Request<'_> {
408
411
self
409
412
}
410
413
411
- pub ( crate ) async fn send ( self ) -> Result < Response , RequestError > {
414
+ pub ( crate ) async fn send ( self ) -> Result < HttpResponse , RequestError > {
412
415
let credential = match self . use_session_creds {
413
416
true => self . config . get_session_credential ( ) . await ?,
414
417
false => SessionCredential {
@@ -446,13 +449,12 @@ impl Request<'_> {
446
449
#[ derive( Debug ) ]
447
450
pub ( crate ) struct S3Client {
448
451
pub config : S3Config ,
449
- pub client : ReqwestClient ,
452
+ pub client : HttpClient ,
450
453
}
451
454
452
455
impl S3Client {
453
- pub ( crate ) fn new ( config : S3Config ) -> Result < Self > {
454
- let client = config. client_options . client ( ) ?;
455
- Ok ( Self { config, client } )
456
+ pub ( crate ) fn new ( config : S3Config , client : HttpClient ) -> Self {
457
+ Self { config, client }
456
458
}
457
459
458
460
pub ( crate ) fn request < ' a > ( & ' a self , method : Method , path : & ' a Path ) -> Request < ' a > {
@@ -544,6 +546,7 @@ impl S3Client {
544
546
. send_retry ( & self . config . retry_config )
545
547
. await
546
548
. map_err ( |source| Error :: DeleteObjectsRequest { source } ) ?
549
+ . into_body ( )
547
550
. bytes ( )
548
551
. await
549
552
. map_err ( |source| Error :: DeleteObjectsResponse { source } ) ?;
@@ -641,6 +644,7 @@ impl S3Client {
641
644
. idempotent ( true )
642
645
. send ( )
643
646
. await ?
647
+ . into_body ( )
644
648
. bytes ( )
645
649
. await
646
650
. map_err ( |source| Error :: CreateMultipartResponseBody { source } ) ?;
@@ -683,17 +687,17 @@ impl S3Client {
683
687
// If SSE-C is used, we must include the encryption headers in every upload request.
684
688
request = request. with_encryption_headers ( ) ;
685
689
}
686
- let response = request. send ( ) . await ?;
687
- let checksum_sha256 = response
688
- . headers ( )
690
+ let ( parts , body ) = request. send ( ) . await ?. into_parts ( ) ;
691
+ let checksum_sha256 = parts
692
+ . headers
689
693
. get ( SHA256_CHECKSUM )
690
694
. and_then ( |v| v. to_str ( ) . ok ( ) )
691
695
. map ( |v| v. to_string ( ) ) ;
692
696
693
697
let e_tag = match is_copy {
694
- false => get_etag ( response . headers ( ) ) . map_err ( |source| Error :: Metadata { source } ) ?,
698
+ false => get_etag ( & parts . headers ) . map_err ( |source| Error :: Metadata { source } ) ?,
695
699
true => {
696
- let response = response
700
+ let response = body
697
701
. bytes ( )
698
702
. await
699
703
. map_err ( |source| Error :: CreateMultipartResponseBody { source } ) ?;
@@ -756,7 +760,7 @@ impl S3Client {
756
760
757
761
let request = self
758
762
. client
759
- . request ( Method :: POST , url)
763
+ . post ( url)
760
764
. query ( & [ ( "uploadId" , upload_id) ] )
761
765
. body ( body)
762
766
. with_aws_sigv4 ( credential. authorizer ( ) , None ) ;
@@ -781,6 +785,7 @@ impl S3Client {
781
785
. map_err ( |source| Error :: Metadata { source } ) ?;
782
786
783
787
let data = response
788
+ . into_body ( )
784
789
. bytes ( )
785
790
. await
786
791
. map_err ( |source| Error :: CompleteMultipartResponseBody { source } ) ?;
@@ -795,7 +800,7 @@ impl S3Client {
795
800
}
796
801
797
802
#[ cfg( test) ]
798
- pub ( crate ) async fn get_object_tagging ( & self , path : & Path ) -> Result < Response > {
803
+ pub ( crate ) async fn get_object_tagging ( & self , path : & Path ) -> Result < HttpResponse > {
799
804
let credential = self . config . get_session_credential ( ) . await ?;
800
805
let url = format ! ( "{}?tagging" , self . config. path_url( path) ) ;
801
806
let response = self
@@ -821,7 +826,7 @@ impl GetClient for S3Client {
821
826
} ;
822
827
823
828
/// Make an S3 GET request <https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html>
824
- async fn get_request ( & self , path : & Path , options : GetOptions ) -> Result < Response > {
829
+ async fn get_request ( & self , path : & Path , options : GetOptions ) -> Result < HttpResponse > {
825
830
let credential = self . config . get_session_credential ( ) . await ?;
826
831
let url = self . config . path_url ( path) ;
827
832
let method = match options. head {
@@ -895,6 +900,7 @@ impl ListClient for Arc<S3Client> {
895
900
. send_retry ( & self . config . retry_config )
896
901
. await
897
902
. map_err ( |source| Error :: ListRequest { source } ) ?
903
+ . into_body ( )
898
904
. bytes ( )
899
905
. await
900
906
. map_err ( |source| Error :: ListResponseBody { source } ) ?;
0 commit comments