1
1
#![ warn( clippy:: all, rust_2018_idioms) ]
2
2
3
- extern crate base64;
4
- extern crate chrono;
5
- extern crate openssl;
6
- extern crate reqwest;
7
-
8
3
use base64:: encode;
9
4
use chrono:: prelude:: Utc ;
5
+ use openssl:: error:: ErrorStack ;
10
6
use openssl:: hash:: MessageDigest ;
11
7
use openssl:: pkey:: PKey ;
12
8
use openssl:: sign:: Signer ;
13
- use reqwest:: header;
9
+ use reqwest:: { header, Body , Client , Response } ;
10
+
11
+ mod error;
12
+ pub use error:: Error ;
14
13
15
14
#[ derive( Clone , Debug ) ]
16
15
pub struct Bucket {
@@ -40,20 +39,20 @@ impl Bucket {
40
39
41
40
pub fn put < R : std:: io:: Read + Send + ' static > (
42
41
& self ,
43
- client : & reqwest :: Client ,
42
+ client : & Client ,
44
43
path : & str ,
45
44
content : R ,
46
45
content_length : u64 ,
47
46
content_type : & str ,
48
47
extra_headers : header:: HeaderMap ,
49
- ) -> reqwest :: Result < reqwest :: Response > {
48
+ ) -> Result < Response , Error > {
50
49
let path = if path. starts_with ( '/' ) {
51
50
& path[ 1 ..]
52
51
} else {
53
52
path
54
53
} ;
55
54
let date = Utc :: now ( ) . to_rfc2822 ( ) ;
56
- let auth = self . auth ( "PUT" , & date, path, "" , content_type) ;
55
+ let auth = self . auth ( "PUT" , & date, path, "" , content_type) ? ;
57
56
let url = self . url ( path) ;
58
57
59
58
client
@@ -62,23 +61,20 @@ impl Bucket {
62
61
. header ( header:: CONTENT_TYPE , content_type)
63
62
. header ( header:: DATE , date)
64
63
. headers ( extra_headers)
65
- . body ( reqwest :: Body :: sized ( content, content_length) )
64
+ . body ( Body :: sized ( content, content_length) )
66
65
. send ( ) ?
67
66
. error_for_status ( )
67
+ . map_err ( Into :: into)
68
68
}
69
69
70
- pub fn delete (
71
- & self ,
72
- client : & reqwest:: Client ,
73
- path : & str ,
74
- ) -> reqwest:: Result < reqwest:: Response > {
70
+ pub fn delete ( & self , client : & Client , path : & str ) -> Result < Response , Error > {
75
71
let path = if path. starts_with ( '/' ) {
76
72
& path[ 1 ..]
77
73
} else {
78
74
path
79
75
} ;
80
76
let date = Utc :: now ( ) . to_rfc2822 ( ) ;
81
- let auth = self . auth ( "DELETE" , & date, path, "" , "" ) ;
77
+ let auth = self . auth ( "DELETE" , & date, path, "" , "" ) ? ;
82
78
let url = self . url ( path) ;
83
79
84
80
client
@@ -87,6 +83,7 @@ impl Bucket {
87
83
. header ( header:: AUTHORIZATION , auth)
88
84
. send ( ) ?
89
85
. error_for_status ( )
86
+ . map_err ( Into :: into)
90
87
}
91
88
92
89
pub fn host ( & self ) -> String {
@@ -101,7 +98,14 @@ impl Bucket {
101
98
)
102
99
}
103
100
104
- fn auth ( & self , verb : & str , date : & str , path : & str , md5 : & str , content_type : & str ) -> String {
101
+ fn auth (
102
+ & self ,
103
+ verb : & str ,
104
+ date : & str ,
105
+ path : & str ,
106
+ md5 : & str ,
107
+ content_type : & str ,
108
+ ) -> Result < String , ErrorStack > {
105
109
let string = format ! (
106
110
"{verb}\n {md5}\n {ty}\n {date}\n {headers}{resource}" ,
107
111
verb = verb,
@@ -112,12 +116,12 @@ impl Bucket {
112
116
resource = format!( "/{}/{}" , self . name, path)
113
117
) ;
114
118
let signature = {
115
- let key = PKey :: hmac ( self . secret_key . as_bytes ( ) ) . unwrap ( ) ;
116
- let mut signer = Signer :: new ( MessageDigest :: sha1 ( ) , & key) . unwrap ( ) ;
117
- signer. update ( string. as_bytes ( ) ) . unwrap ( ) ;
118
- encode ( & signer. sign_to_vec ( ) . unwrap ( ) [ ..] )
119
+ let key = PKey :: hmac ( self . secret_key . as_bytes ( ) ) ? ;
120
+ let mut signer = Signer :: new ( MessageDigest :: sha1 ( ) , & key) ? ;
121
+ signer. update ( string. as_bytes ( ) ) ? ;
122
+ encode ( & signer. sign_to_vec ( ) ? [ ..] )
119
123
} ;
120
- format ! ( "AWS {}:{}" , self . access_key, signature)
124
+ Ok ( format ! ( "AWS {}:{}" , self . access_key, signature) )
121
125
}
122
126
123
127
fn url ( & self , path : & str ) -> String {
0 commit comments