aliyunoss 0.1.3 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.byebug_history +15 -0
- data/.gitignore +2 -1
- data/Gemfile +2 -0
- data/README.md +250 -42
- data/lib/aliyunoss.rb +5 -0
- data/lib/aliyunoss/api.rb +74 -5
- data/lib/aliyunoss/bucket.rb +26 -3
- data/lib/aliyunoss/config.rb +11 -9
- data/lib/aliyunoss/extension.rb +4 -4
- data/lib/aliyunoss/oss_request.rb +16 -1
- data/lib/aliyunoss/version.rb +1 -1
- data/spec/aliyunoss/bucket_spec.rb +2 -1
- data/spec/aliyunoss/config_spec.rb +1 -4
- metadata +4 -4
- data/lib/aliyunoss/#oss_request.rb# +0 -154
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5cc87c05e0eb083f64578345b86b05f6734f6bca
|
4
|
+
data.tar.gz: 2f38f52a10c1c692d9d91c5466eb2690f75167f1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6bf9a1f3732ab56243a38a98d74f03d6eabad29b81aa928440c764613cb4a4e76da598a6a11859567b944c6310ab22387e40fb5d31b1c2c39ac7b325dbd918a7
|
7
|
+
data.tar.gz: 5a0b80b464be4ce629fbe9eccfa543c41b916c68cfddaffa7d34c05026e9701e70cc9f828cee93a60e50ed198756b19506ce365c5fc1adc197884931df476ba1
|
data/.byebug_history
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
q
|
2
|
+
Aliyun::Oss.config[:logger].info 'xxxx'
|
3
|
+
Aliyun::Oss.config[:logger]
|
4
|
+
Aliyun::Oss.config
|
5
|
+
Aliyun::Oss.logger
|
6
|
+
Aliyun::Oss.configure(logger: Logger.new(STDOUT))
|
7
|
+
Aliyun::Oss.logger
|
8
|
+
Aliyun::Oss.configure.logger
|
9
|
+
Aliyun::Oss.configure.log
|
10
|
+
q
|
11
|
+
@config[:logger]
|
12
|
+
c
|
13
|
+
@config[:logger]
|
14
|
+
c
|
15
|
+
@config[:logger]
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,29 @@
|
|
2
2
|
|
3
3
|
Ruby gem for [Aliyun Open Storage Service (OSS)][1]. This gem implemented API from [references of Aliyun OSS-API][2].
|
4
4
|
|
5
|
-
##
|
5
|
+
## Table of Contents
|
6
|
+
|
7
|
+
* [Installation](#installation)
|
8
|
+
* [Usage](#usage)
|
9
|
+
* [Load Access Key ID and Access Key Secrete](#load)
|
10
|
+
* [Get Log Messages](#setlog)
|
11
|
+
* [Using Bucket API](#highlevel)
|
12
|
+
* [List Buckets](#listbuckets)
|
13
|
+
* [Create a Bucket](#newbucket)
|
14
|
+
* [Open a Bucket](#openbucket)
|
15
|
+
* [List Files In Bucket](#listfiles)
|
16
|
+
* [Upload a File to Bucket](#uploadfile)
|
17
|
+
* [Download a File from Bucket](#downloadfile)
|
18
|
+
* [Share a File in Bucket](#sharefile)
|
19
|
+
* [Delete a File in Bucket](#deletefile)
|
20
|
+
* [Upload a Large File in Multipart Way](#uploadlargefile)
|
21
|
+
* [Delete a bucket](#deletebucket)
|
22
|
+
* [Enable/Disable Logging for bucket](#logging)
|
23
|
+
* [Using Primitive API](#lowlevel)
|
24
|
+
* [Test](#test)
|
25
|
+
* [Contribute](#contribute)
|
26
|
+
|
27
|
+
## <a name="installation"></a>Installation
|
6
28
|
|
7
29
|
Add this line to your application's Gemfile:
|
8
30
|
|
@@ -12,73 +34,258 @@ gem 'aliyunoss'
|
|
12
34
|
|
13
35
|
And then execute:
|
14
36
|
|
15
|
-
|
37
|
+
```ruby
|
38
|
+
$ bundle
|
39
|
+
```
|
16
40
|
|
17
41
|
Or install it yourself as:
|
18
42
|
|
19
|
-
|
43
|
+
```ruby
|
44
|
+
$ gem install aliyunoss
|
45
|
+
```
|
20
46
|
|
21
|
-
## Usage
|
47
|
+
## <a name="usage"></a>Usage
|
22
48
|
|
23
|
-
This gem provides
|
49
|
+
This gem provides Bucket API which are built around class Bucket and Primitive API which are wrappers for [OSS API][2]. Most of time using Bucket API is OK except you find OSS API that I didn't implement.
|
24
50
|
|
25
|
-
### Load Access Key ID and Access Key Secret
|
51
|
+
### <a name="load"></a>Load Access Key ID and Access Key Secret
|
26
52
|
|
27
53
|
Specify you access key and access secret before calling methods provided in this gem:
|
28
54
|
|
29
|
-
|
55
|
+
```ruby
|
56
|
+
Aliyun::Oss::configure(:access_key_id => 'access key id from aliyun', :access_key_secret => 'access secret from aliyun')
|
57
|
+
```
|
58
|
+
|
59
|
+
When using this gem in a rails project, you can create a file named 'aliyunoss_key.rb' in RAILS\_ROOT/config/initializers, whose content is:
|
30
60
|
|
31
|
-
|
61
|
+
```ruby
|
62
|
+
Aliyun::Oss::configure(:access_key_id => 'access key id from aliyun', :access_key_secret => 'access secret from aliyun')
|
63
|
+
```
|
64
|
+
|
65
|
+
Then you can use the following APIs anywhere.
|
32
66
|
|
33
|
-
|
67
|
+
### <a name="setlog"></a>Get Log Messages
|
34
68
|
|
35
|
-
|
69
|
+
Log message is prohibited by default, you can pass a logger instace to enable it:
|
36
70
|
|
37
|
-
|
71
|
+
```ruby
|
72
|
+
Aliyun::Oss::configure(:logger => Logger.new(STDOUT))
|
73
|
+
```
|
38
74
|
|
39
|
-
|
75
|
+
### <a name="highlevel"></a>Bucket API
|
40
76
|
|
41
|
-
|
77
|
+
Bucket API are built around class Bucket. You create a new bucket, and upload, download or delete files in it. When needed, responses are parsed to array, hash or object etc, thus more meaningful. Exceptions will be raised when request failed.
|
42
78
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
79
|
+
```ruby
|
80
|
+
# Create a bucket in OSS server
|
81
|
+
bucket = Aliyun::Oss::Bucket.create('aliyun-oss-gem-api-test','oss-cn-hangzhou')
|
82
|
+
|
83
|
+
# Upload a file
|
84
|
+
filename = '/some/file'
|
85
|
+
bucket.upload( IO.read(filename) )
|
86
|
+
|
87
|
+
# List all files in this bucket, returns a Hash array containing files info
|
88
|
+
files = bucket.list_files
|
89
|
+
|
90
|
+
# Download a file, returns raw data
|
91
|
+
data = bucket.download( '/some/path' )
|
92
|
+
```
|
93
|
+
|
94
|
+
#### <a name="listbuckets"></a>List all buckets
|
47
95
|
|
48
|
-
|
96
|
+
After correctly configuring your access key and secret, you can list all buckets:
|
49
97
|
|
50
|
-
|
51
|
-
|
52
|
-
|
98
|
+
```ruby
|
99
|
+
Aliyun::Oss::Bucket.all
|
100
|
+
```
|
53
101
|
|
54
|
-
|
102
|
+
The result is a Bucket array. Class Bucket has some simple attributes :
|
55
103
|
|
56
|
-
|
104
|
+
```ruby
|
105
|
+
class Bucket
|
106
|
+
attr_accessor :location, :name, :creation_date, :domain, :extranet_endpoint, :intranet_endpoint
|
107
|
+
# ...
|
108
|
+
end
|
109
|
+
```
|
57
110
|
|
58
|
-
|
111
|
+
#### <a name="newbucket"></a>Create a new bucket
|
59
112
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
bucket.upload( IO.read(filename) )
|
66
|
-
|
67
|
-
# List all files in this bucket, returns a Hash array containing files info
|
68
|
-
files = bucket.list_files
|
113
|
+
You can create a new bucket using class method *create* of Bucket:
|
114
|
+
|
115
|
+
```ruby
|
116
|
+
bucket = Aliyun::Oss::Bucket.create(bucket_name, bucket_location)
|
117
|
+
```
|
69
118
|
|
70
|
-
|
71
|
-
|
119
|
+
Where *bucket_name* is a string, and *bucket_location* is an optional string parameter which defaults to 'oss-cn-hangzhou'. Other available bucket locations can be referenced [here][5]. This method return a new Bucket instance if success.
|
120
|
+
|
121
|
+
#### <a name="openbucket"></a>Open a bucket
|
122
|
+
|
123
|
+
There is no such opeartion as opening a bucket, but you can create a Bucket instance by:
|
124
|
+
|
125
|
+
```ruby
|
126
|
+
Aliyun::Oss::Bucket.new(name: 'bucket-name', location: 'oss-cn-beijing')
|
127
|
+
```
|
128
|
+
|
129
|
+
So you can continue to download or upload files using this Bucket instance.
|
130
|
+
|
131
|
+
#### <a name="listfiles"></a>List all files in an bucket
|
132
|
+
|
133
|
+
You can list all files in an bucket using instance method *list\_files* of a bucket:
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
files = bucket.list_files
|
137
|
+
```
|
138
|
+
|
139
|
+
The result is a array consisted of file objects which are parsed from xml reponse, eg.
|
140
|
+
|
141
|
+
```ruby
|
142
|
+
[
|
143
|
+
{ "key"=>"100f1a845046c189944dc8fd57bffbe390b90e3a.png",
|
144
|
+
"last_modified"=>"2015-12-14T03:04:37.000Z",
|
145
|
+
"e_tag"=>"\"B9072ECBBF4B06962517B3FD4090538E\"",
|
146
|
+
"type"=>"Normal",
|
147
|
+
"size"=>"49509",
|
148
|
+
"storage_class"=>"Standard" },
|
149
|
+
|
150
|
+
{ "key"=>"11c5db2a88648d25da889a1d20687ec535a50905.jpg",
|
151
|
+
"last_modified"=>"2015-12-14T08:03:54.000Z",
|
152
|
+
"e_tag"=>"\"77618F54695C08E278ACBD7D9C63E521\"",
|
153
|
+
"type"=>"Normal",
|
154
|
+
"size"=>"491133",
|
155
|
+
"storage_class"=>"Standard" }
|
156
|
+
]
|
157
|
+
```
|
158
|
+
|
159
|
+
#### <a name="uploadfile"></a>Upload a file to bucket
|
160
|
+
|
161
|
+
You can upload a file using instance method *upload* of a bucket, eg.
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
data = IO.read('/local/path/of/file')
|
165
|
+
bucket.upload(data, '/remote/path/of/file')
|
166
|
+
```
|
167
|
+
|
168
|
+
This will raise an exception unless success. A file in remote bucket can include some meta data, eg. when serving images, we often want Aliyun OSS server to return *Content-Type* header for http GET request. To acheive this effect, we have to add additional paramters when uploading file, eg.
|
169
|
+
|
170
|
+
```ruby
|
171
|
+
image = IO.read('/local/image')
|
172
|
+
bucket.upload(image, '/remote/image', 'Content-Type'=>'image/png')
|
173
|
+
```
|
174
|
+
|
175
|
+
#### <a name="downloadfile"></a>Download file from bucket
|
176
|
+
|
177
|
+
You can read content of a remote file using instance method *download* of a bucket, eg.
|
178
|
+
|
179
|
+
```ruby
|
180
|
+
raw_data = bucket.download('/remote/path/of/file')
|
181
|
+
```
|
182
|
+
|
183
|
+
where *raw_data* is body of a Net::HTTPResponse object.
|
184
|
+
|
185
|
+
#### <a name="sharefile"></a>Generate a sharing url of a remote file
|
186
|
+
|
187
|
+
If you set your bucket private for reading, others cannot access content of files in your bucket without valid access key and secret. But you won't give them access key or secret, instead you generate a sharing url for them to access your file:
|
188
|
+
|
189
|
+
```ruby
|
190
|
+
public_url = bucket.share('/remote/file')
|
191
|
+
```
|
72
192
|
|
73
|
-
|
193
|
+
This will generate a public url that can access some remote file. By default this url is only valid for 1 hour, you can change this behavior by adding the second paramter:
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
public_url = bucket.share('/remote/file', 60 * 60 * 24)
|
197
|
+
```
|
198
|
+
|
199
|
+
where unit used is second, so that will be 1 day long.
|
200
|
+
|
201
|
+
#### <a name="deletefile"></a>Delete a file in the bucket
|
202
|
+
|
203
|
+
You can delete a remote file using instance method *delete* of a bucket, eg:
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
bucket.delete('/remote/path/of/file')
|
207
|
+
```
|
74
208
|
|
75
|
-
|
209
|
+
It will return an Net::HTTPNoContent if file is deleted successfully OR file not found.
|
210
|
+
|
211
|
+
#### <a name="uploadlargefile"></a>Upload a large file in multipart way
|
212
|
+
|
213
|
+
When uploading a large file, using multipart way is preffered due to unreliable network condition. An multipart task consist of a sequence operations: *multipart\_upload\_initiate*, *multipart\_upload* and *multipart_upload_compelete*:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
bucket.multipart_upload_initiate('/remote/path/of/a/large/file')
|
217
|
+
|
218
|
+
10.times do
|
219
|
+
bucket.multipart_upload( Random.new.bytes(1024 * rand(100..300)) )
|
220
|
+
end
|
221
|
+
|
222
|
+
bucket.multipart_upload_complete
|
223
|
+
```
|
224
|
+
|
225
|
+
#### <a name="deletebucket"></a>Delete a bucket
|
226
|
+
|
227
|
+
You can delete a bucket using instance method *delete!* of a bucket, eg:
|
228
|
+
|
229
|
+
```ruby
|
230
|
+
bucket.delete!
|
231
|
+
```
|
232
|
+
|
233
|
+
Exception will be raised unless bucket is empty.
|
234
|
+
|
235
|
+
#### <a name="logging"></a>Enable/Disable logging for a bucket
|
236
|
+
|
237
|
+
OSS can record access log for a bucket, you can toggle this function by:
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
bucket.enable_logging('/remote/file/of/log', 'log_prefix')
|
241
|
+
```
|
242
|
+
|
243
|
+
Then all access log is recorded with prefix you specified with the second paramter, and stored in the path you specified by the first parameter.
|
244
|
+
|
245
|
+
Disable this function by:
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
bucket.disable_logging
|
249
|
+
```
|
250
|
+
|
251
|
+
### <a name="lowlevel"></a>Primitive API
|
252
|
+
|
253
|
+
Primitive API are simple http wrappers for [OSS API][2], you send requests with specified parameters and receive responses with a Net::HTTPResponse object. All parameters listed in [OSS API][2] are needed for every request, and context information between requests is maintained by yourself. In order to tell whether a a request is success, check code and body of returned Net::HTTPResponse object.
|
254
|
+
|
255
|
+
All [OSS API][2] listed are implemented except [Post Object][3] and [CORS APIs][4].
|
256
|
+
|
257
|
+
List all the buckets:
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
Aliyun::Oss::API.list_bucket
|
261
|
+
```
|
262
|
+
|
263
|
+
Upload data to specified bucket:
|
264
|
+
|
265
|
+
```ruby
|
266
|
+
bucket = Aliyun::Oss::Bucket.new(:name => 'bucket-name', :location => 'oss-cn-beijing')
|
267
|
+
path = '/test.dat'
|
268
|
+
data = Random.new.bytes(1024 * rand(100..300))
|
269
|
+
Aliyun::Oss::API.put_object(bucket, path, data)
|
270
|
+
```
|
271
|
+
|
272
|
+
Download data from specified bucket:
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
bucket = Bucket.new(:name => 'bucket-name', :location => 'oss-cn-beijing')
|
276
|
+
path = '/test.dat'
|
277
|
+
Aliyun::Oss::API.get_object(bucket, path)
|
278
|
+
```
|
279
|
+
|
280
|
+
For more usage, see API documentation generated by rdoc.
|
281
|
+
|
282
|
+
## <a name="test"></a>Testing
|
76
283
|
|
77
284
|
This gem use rspec for testing. Most of testing needs a valid access key id and access key secret, you should get these info from Aliyun.
|
78
285
|
|
79
286
|
Create a file named aliyun-config.yml in path rspec/aliyunoss/config, fill in valid access key id and access key secret and cotinue to test.
|
80
287
|
|
81
|
-
## Contributing
|
288
|
+
## <a name="contribute"></a>Contributing
|
82
289
|
|
83
290
|
1. Fork it ( https://github.com/yijiecc/aliyunoss/fork )
|
84
291
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
@@ -86,7 +293,8 @@ Create a file named aliyun-config.yml in path rspec/aliyunoss/config, fill in va
|
|
86
293
|
4. Push to the branch (`git push origin my-new-feature`)
|
87
294
|
5. Create a new Pull Request
|
88
295
|
|
89
|
-
[1]:
|
90
|
-
[2]:
|
91
|
-
[3]:
|
92
|
-
[4]:
|
296
|
+
[1]: https://www.aliyun.com/product/oss?spm=5176.doc31870.416540.44.QdQVwH
|
297
|
+
[2]: https://help.aliyun.com/document_detail/31827.html?spm=5176.doc31817.6.564.Px1zOr
|
298
|
+
[3]: https://help.aliyun.com/document_detail/31849.html?spm=5176.doc31827.6.581.XDg3ZS
|
299
|
+
[4]: https://help.aliyun.com/document_detail/31870.html?spm=5176.87240.400427.34.vFnPt8
|
300
|
+
[5]: https://help.aliyun.com/document_detail/31837.html?spm=5176.doc31959.2.1.EpUpfD
|
data/lib/aliyunoss.rb
CHANGED
data/lib/aliyunoss/api.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
module Aliyun
|
2
2
|
module Oss
|
3
3
|
|
4
|
+
# Reference
|
5
|
+
# http://docs-aliyun-com-cn-b.oss-cn-hangzhou.aliyuncs.com/oss/pdf/oss_api-reference.pdf
|
4
6
|
module API
|
5
7
|
extend self
|
6
8
|
|
7
|
-
# Reference
|
8
|
-
# http://docs-aliyun-com-cn-b.oss-cn-hangzhou.aliyuncs.com/oss/pdf/oss_api-reference.pdf
|
9
9
|
|
10
|
+
#
|
10
11
|
# List all buckets
|
12
|
+
#
|
11
13
|
def list_bucket(params = {})
|
12
14
|
Aliyun::Oss::OssRequest.new(nil, '/', nil, {}, {}).get
|
13
15
|
end
|
14
16
|
alias :get_service :list_bucket
|
15
17
|
|
18
|
+
#
|
16
19
|
# Create a new bucket
|
20
|
+
#
|
17
21
|
def put_bucket(name, location = 'oss-cn-hangzhou')
|
18
22
|
bucket = Bucket.new(name: name, location: location)
|
19
23
|
request = Aliyun::Oss::OssRequest.new(bucket, '/')
|
@@ -27,54 +31,74 @@ HERE
|
|
27
31
|
end
|
28
32
|
alias :create_bucket :put_bucket
|
29
33
|
|
34
|
+
#
|
30
35
|
# Delete a bucket
|
36
|
+
#
|
31
37
|
def delete_bucket(bucket)
|
32
38
|
Aliyun::Oss::OssRequest.new(bucket, '/').delete
|
33
39
|
end
|
34
|
-
|
40
|
+
|
41
|
+
#
|
35
42
|
# Delete bucket logging
|
43
|
+
#
|
36
44
|
def delete_logging(bucket)
|
37
45
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'logging'=>nil).delete
|
38
46
|
end
|
39
47
|
|
48
|
+
#
|
40
49
|
# Delete bucket website
|
50
|
+
#
|
41
51
|
def delete_website(bucket)
|
42
52
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'website'=>nil).delete
|
43
53
|
end
|
44
54
|
alias :disable_website :delete_website
|
45
55
|
|
56
|
+
#
|
46
57
|
# List objects in bucket
|
58
|
+
#
|
47
59
|
def list_object(bucket, queries = {})
|
48
60
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, queries).get
|
49
61
|
end
|
50
62
|
|
63
|
+
#
|
51
64
|
# Get bucket acl
|
65
|
+
#
|
52
66
|
def get_bucket_acl(bucket)
|
53
67
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'acl'=>nil).get
|
54
68
|
end
|
55
69
|
|
70
|
+
#
|
56
71
|
# Get bucket location
|
72
|
+
#
|
57
73
|
def get_bucket_location(bucket)
|
58
74
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'location'=>nil).get
|
59
75
|
end
|
60
76
|
|
77
|
+
#
|
61
78
|
# Query bucket logging status
|
79
|
+
#
|
62
80
|
def get_bucket_logging(bucket)
|
63
81
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'logging'=>nil).get
|
64
82
|
end
|
65
83
|
|
84
|
+
#
|
66
85
|
# Query bucket website status
|
86
|
+
#
|
67
87
|
def get_bucket_website(bucket)
|
68
88
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'website'=>nil).get
|
69
89
|
end
|
70
90
|
|
91
|
+
#
|
71
92
|
# Set bucket acl permission
|
93
|
+
#
|
72
94
|
def put_bucket_acl(bucket, permission)
|
73
95
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, {}, 'x-oss-acl'=> permission).put
|
74
96
|
end
|
75
97
|
alias :set_bucket_acl :put_bucket_acl
|
76
98
|
|
77
|
-
#
|
99
|
+
#
|
100
|
+
# Enable bucket logging
|
101
|
+
#
|
78
102
|
def enable_bucket_logging(bucket, bucket_name_for_logging, log_prefix)
|
79
103
|
request = Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'logging'=>nil)
|
80
104
|
request.body = <<HERE
|
@@ -90,6 +114,9 @@ HERE
|
|
90
114
|
request.put
|
91
115
|
end
|
92
116
|
|
117
|
+
#
|
118
|
+
# Disable bucket logging
|
119
|
+
#
|
93
120
|
def disable_bucket_logging(bucket)
|
94
121
|
request = Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'logging'=>nil)
|
95
122
|
request.body = <<HERE
|
@@ -101,7 +128,9 @@ HERE
|
|
101
128
|
request.put
|
102
129
|
end
|
103
130
|
|
131
|
+
#
|
104
132
|
# Set bucket website access
|
133
|
+
#
|
105
134
|
def put_bucket_website(bucket, index_page, error_page)
|
106
135
|
request = Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'website'=>nil)
|
107
136
|
request.body = <<HERE
|
@@ -119,19 +148,25 @@ HERE
|
|
119
148
|
request.put
|
120
149
|
end
|
121
150
|
alias :set_bucket_website :put_bucket_website
|
122
|
-
|
151
|
+
|
152
|
+
#
|
123
153
|
# Copy Object
|
154
|
+
#
|
124
155
|
def copy_object(source_bucket, source_path, target_bucket, target_path, headers = {})
|
125
156
|
headers = headers.merge({'x-oss-copy-source'=> "/" + source_bucket.name + source_path})
|
126
157
|
Aliyun::Oss::OssRequest.new(target_bucket, target_path, nil, {}, headers).put
|
127
158
|
end
|
128
159
|
|
160
|
+
#
|
129
161
|
# Delete Object
|
162
|
+
#
|
130
163
|
def delete_object(bucket, path)
|
131
164
|
Aliyun::Oss::OssRequest.new(bucket, path).delete
|
132
165
|
end
|
133
166
|
|
167
|
+
#
|
134
168
|
# Delete Multiple Object
|
169
|
+
#
|
135
170
|
def delete_multiple_objects(bucket, objects, quiet_mode = false)
|
136
171
|
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
137
172
|
xml << '<Delete>'
|
@@ -143,48 +178,70 @@ HERE
|
|
143
178
|
request.post
|
144
179
|
end
|
145
180
|
|
181
|
+
#
|
146
182
|
# Get Object
|
183
|
+
#
|
147
184
|
def get_object(bucket, path, headers = {})
|
148
185
|
Aliyun::Oss::OssRequest.new(bucket, path, nil, {}, headers).get
|
149
186
|
end
|
150
187
|
|
188
|
+
#
|
151
189
|
# Head Object
|
190
|
+
#
|
152
191
|
def head_object(bucket, path, headers = {})
|
153
192
|
Aliyun::Oss::OssRequest.new(bucket, path, nil, {}, headers).head
|
154
193
|
end
|
155
194
|
|
195
|
+
#
|
156
196
|
# Put Object
|
197
|
+
#
|
157
198
|
def put_object(bucket, path, data, headers = {})
|
158
199
|
request = Aliyun::Oss::OssRequest.new(bucket, path, nil, {}, headers)
|
159
200
|
request.body = data
|
160
201
|
request.put
|
161
202
|
end
|
162
203
|
|
204
|
+
#
|
163
205
|
# get share url for specified object
|
206
|
+
#
|
164
207
|
def generate_share_url(bucket, path, expires_in = 3600)
|
165
208
|
Aliyun::Oss::OssRequest.new(bucket, path).url_for_sharing(expires_in)
|
166
209
|
end
|
167
210
|
|
211
|
+
#
|
168
212
|
# Post Object
|
213
|
+
#
|
169
214
|
# Not implemented
|
170
215
|
|
216
|
+
#
|
171
217
|
# Post Policy
|
218
|
+
#
|
172
219
|
# Not implemented
|
173
220
|
|
221
|
+
#
|
174
222
|
# Post signature
|
223
|
+
#
|
175
224
|
# Not implemented
|
176
225
|
|
226
|
+
#
|
177
227
|
# Multipart Initiate
|
228
|
+
#
|
178
229
|
def multipart_upload_initiate(bucket, path)
|
179
230
|
Aliyun::Oss::OssRequest.new(bucket, path, nil, 'uploads'=>nil).post
|
180
231
|
end
|
181
232
|
|
233
|
+
#
|
234
|
+
# Multipart upload part
|
235
|
+
#
|
182
236
|
def multipart_upload_part(bucket, path, upload_id, data, part_number)
|
183
237
|
request = Aliyun::Oss::OssRequest.new(bucket, path, nil, 'partNumber'=> part_number.to_s, 'uploadId'=> upload_id)
|
184
238
|
request.body = data
|
185
239
|
request.put
|
186
240
|
end
|
187
241
|
|
242
|
+
#
|
243
|
+
# Multipart upload from copy
|
244
|
+
#
|
188
245
|
def multipart_upload_from_copy(upload_id, source_bucket, source_path, target_bucket, target_path, part_number, part_size, range = nil)
|
189
246
|
request = Aliyun::Oss::OssRequest.new(target_bucket, target_path, nil, 'partNumber'=> part_number.to_s, 'uploadId'=> upload_id)
|
190
247
|
request['Content-Length'] = part_size
|
@@ -193,6 +250,9 @@ HERE
|
|
193
250
|
request.put
|
194
251
|
end
|
195
252
|
|
253
|
+
#
|
254
|
+
# Complete an multipart upload.
|
255
|
+
#
|
196
256
|
def multipart_upload_complete(bucket, path, upload_id, part_list)
|
197
257
|
request = Aliyun::Oss::OssRequest.new(bucket, path, nil, 'uploadId'=> upload_id)
|
198
258
|
xml = '<?xml version="1.0" encoding="UTF-8"?>'
|
@@ -203,14 +263,23 @@ HERE
|
|
203
263
|
request.post
|
204
264
|
end
|
205
265
|
|
266
|
+
#
|
267
|
+
# Abort an upload task
|
268
|
+
#
|
206
269
|
def multipart_upload_abort(bucket, path, upload_id)
|
207
270
|
Aliyun::Oss::OssRequest.new(bucket, path, nil, 'uploadId'=> upload_id).delete
|
208
271
|
end
|
209
272
|
|
273
|
+
#
|
274
|
+
# List finished multipart parts
|
275
|
+
#
|
210
276
|
def multipart_upload_finished_parts(bucket, path, upload_id)
|
211
277
|
Aliyun::Oss::OssRequest.new(bucket, path, nil, 'uploadId'=> upload_id).get
|
212
278
|
end
|
213
279
|
|
280
|
+
#
|
281
|
+
# List all unfinished multipart task
|
282
|
+
#
|
214
283
|
def multipart_upload_unfinished_task(bucket)
|
215
284
|
Aliyun::Oss::OssRequest.new(bucket, '/', nil, 'uploads'=>nil).get
|
216
285
|
end
|
data/lib/aliyunoss/bucket.rb
CHANGED
@@ -12,40 +12,61 @@ module Aliyun
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
15
|
+
#
|
16
|
+
# Class method - List all buckets in my account
|
17
|
+
#
|
16
18
|
def self.all
|
17
19
|
Aliyun::Oss::API.list_bucket.raise_unless(Net::HTTPOK).to_buckets
|
18
20
|
end
|
19
21
|
|
22
|
+
#
|
23
|
+
# Class method - Create a new bucket
|
24
|
+
#
|
20
25
|
def self.create(name, location = 'oss-cn-hangzhou')
|
21
26
|
Aliyun::Oss::API.put_bucket(name, location).raise_unless(Net::HTTPOK)
|
22
27
|
Bucket.new(:name => name, :location=> location, :creation_date => Time.now)
|
23
28
|
end
|
24
29
|
|
25
|
-
#
|
30
|
+
#
|
31
|
+
# List all files in an bucket
|
32
|
+
#
|
26
33
|
def list_files(options = {})
|
27
34
|
Aliyun::Oss::API.list_object(self, options).raise_unless(Net::HTTPOK).to_objects
|
28
35
|
end
|
29
36
|
|
37
|
+
#
|
38
|
+
# Upload data to bucket
|
39
|
+
#
|
30
40
|
def upload(data, path, options = {})
|
31
41
|
Aliyun::Oss::API.put_object(self, path, data, options).raise_unless(Net::HTTPOK)
|
32
42
|
end
|
33
43
|
|
44
|
+
#
|
45
|
+
# Download file from remote server
|
46
|
+
#
|
34
47
|
def download(path, options = {})
|
35
48
|
Aliyun::Oss::API.get_object(self, path, options)
|
36
49
|
.raise_unless(Net::HTTPOK)
|
37
50
|
.body
|
38
51
|
end
|
39
52
|
|
53
|
+
#
|
54
|
+
# Generate a url that can be shared to others
|
55
|
+
#
|
40
56
|
def share(path, expires_in = 3600)
|
41
57
|
Aliyun::Oss::API.generate_share_url(self, path, expires_in)
|
42
58
|
end
|
43
59
|
|
60
|
+
#
|
61
|
+
# Delete remote file
|
62
|
+
#
|
44
63
|
def delete(path)
|
45
64
|
Aliyun::Oss::API.delete_object(self, path).raise_unless(Net::HTTPNoContent)
|
46
65
|
end
|
47
66
|
|
67
|
+
#
|
48
68
|
# Multipart upload and copy
|
69
|
+
#
|
49
70
|
def multipart_pending
|
50
71
|
Aliyun::Oss::API.multipart_upload_unfinished_task(self)
|
51
72
|
.raise_unless(Net::HTTPOK)
|
@@ -95,7 +116,9 @@ module Aliyun
|
|
95
116
|
@multipart_path = nil
|
96
117
|
end
|
97
118
|
|
98
|
-
#
|
119
|
+
#
|
120
|
+
# delete this bucket
|
121
|
+
#
|
99
122
|
def delete!
|
100
123
|
Aliyun::Oss::API.delete_bucket(self).raise_unless(Net::HTTPNoContent)
|
101
124
|
end
|
data/lib/aliyunoss/config.rb
CHANGED
@@ -1,22 +1,28 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'logger'
|
3
3
|
|
4
|
+
class NullLogger < Logger
|
5
|
+
def initialize(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def add(*args, &block)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
|
4
13
|
module Aliyun
|
5
14
|
module Oss
|
6
15
|
|
7
16
|
@config = {
|
8
|
-
:
|
17
|
+
:logger => nil,
|
9
18
|
:host => 'aliyuncs.com',
|
10
19
|
:access_key_id => nil,
|
11
20
|
:access_key_secret => nil
|
12
21
|
}
|
13
22
|
|
14
|
-
@_logger = nil
|
15
|
-
|
16
23
|
@valid_config_keys = @config.keys
|
17
24
|
|
18
25
|
def self.configure(opts = {})
|
19
|
-
@_logger = nil
|
20
26
|
opts.each {|k,v| @config[k.to_sym] = v if @valid_config_keys.include?(k.to_sym)}
|
21
27
|
end
|
22
28
|
|
@@ -36,11 +42,7 @@ module Aliyun
|
|
36
42
|
end
|
37
43
|
|
38
44
|
def self.logger
|
39
|
-
|
40
|
-
@_logger ||= Logger.new(STDOUT)
|
41
|
-
@_logger.level = Logger.const_get(@config[:log_level].upcase) rescue Logger::INFO
|
42
|
-
end
|
43
|
-
@_logger
|
45
|
+
@config[:logger] or (@null_logger ||= NullLogger.new)
|
44
46
|
end
|
45
47
|
|
46
48
|
end
|
data/lib/aliyunoss/extension.rb
CHANGED
@@ -25,10 +25,10 @@ class String
|
|
25
25
|
# Convert CamelCase to ruby_case
|
26
26
|
def underscore
|
27
27
|
self.gsub(/::/, '/').
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
29
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
30
|
+
tr("-", "_").
|
31
|
+
downcase
|
32
32
|
end
|
33
33
|
|
34
34
|
end
|
@@ -9,7 +9,10 @@ module Aliyun
|
|
9
9
|
|
10
10
|
include ConfigHelper
|
11
11
|
attr_accessor :bucket, :path, :body, :queris, :domain
|
12
|
-
|
12
|
+
|
13
|
+
#
|
14
|
+
# Create a new oss request, parameters will be sent to methods of Net::HTTP later.
|
15
|
+
#
|
13
16
|
def initialize(bucket, path, domain = nil, queries = {}, headers = {})
|
14
17
|
@bucket = bucket
|
15
18
|
@path = path
|
@@ -18,6 +21,9 @@ module Aliyun
|
|
18
21
|
@headers = {"Content-Type" => "", "Content-MD5" => "", "Date" => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')}.merge(headers)
|
19
22
|
end
|
20
23
|
|
24
|
+
#
|
25
|
+
# Get complete url for this request
|
26
|
+
#
|
21
27
|
def get_uri
|
22
28
|
if @domain
|
23
29
|
uri = URI("http://#{domain}/")
|
@@ -68,6 +74,9 @@ module Aliyun
|
|
68
74
|
add_operation :head
|
69
75
|
add_operation :post
|
70
76
|
|
77
|
+
#
|
78
|
+
# Get sharing url for this request, pass _expires_in_ as parameter.
|
79
|
+
#
|
71
80
|
def url_for_sharing(expires_in)
|
72
81
|
uri = get_uri
|
73
82
|
request = Net::HTTP::Get.new(uri)
|
@@ -80,10 +89,16 @@ module Aliyun
|
|
80
89
|
uri.to_s
|
81
90
|
end
|
82
91
|
|
92
|
+
#
|
93
|
+
# Get http header value by attribute
|
94
|
+
#
|
83
95
|
def [](key)
|
84
96
|
@headers[key]
|
85
97
|
end
|
86
98
|
|
99
|
+
#
|
100
|
+
# Set http header value by attribute
|
101
|
+
#
|
87
102
|
def []=(key, value)
|
88
103
|
@headers[key] = value
|
89
104
|
end
|
data/lib/aliyunoss/version.rb
CHANGED
@@ -6,6 +6,7 @@ describe Aliyun::Oss::Bucket do
|
|
6
6
|
|
7
7
|
before :all do
|
8
8
|
Aliyun::Oss.configure_with('spec/aliyunoss/config/aliyun-config.yml')
|
9
|
+
Aliyun::Oss.configure(logger: Logger.new(STDOUT))
|
9
10
|
@bucket_name = "aliyunoss-gem-test-#{rand.to_s.delete('0.')}"
|
10
11
|
@location = 'oss-cn-beijing'
|
11
12
|
@bucket = Aliyun::Oss::Bucket.new( location: @location, name: @bucket_name)
|
@@ -119,7 +120,7 @@ describe Aliyun::Oss::Bucket do
|
|
119
120
|
end
|
120
121
|
|
121
122
|
@bucket.delete!
|
122
|
-
expect {Bucket.new(:name=> 'bucket_not_exist').delete!}.to raise_error
|
123
|
+
expect {Aliyun::Oss::Bucket.new(:name=> 'bucket_not_exist').delete!}.to raise_error(SocketError)
|
123
124
|
end
|
124
125
|
|
125
126
|
end
|
@@ -6,25 +6,22 @@ describe 'Aliyun::Oss Configuration' do
|
|
6
6
|
|
7
7
|
before :each do
|
8
8
|
config = Aliyun::Oss.config
|
9
|
-
config[:log_level] = 'info'
|
10
9
|
config[:access_key_id] = nil
|
11
10
|
config[:access_key_secret] = nil
|
12
11
|
end
|
13
12
|
|
14
13
|
it 'should load default options' do
|
15
14
|
default_config = Aliyun::Oss.config
|
16
|
-
expect(default_config).to include(:log_level)
|
17
15
|
expect(default_config).to include(:access_key_id)
|
18
16
|
end
|
19
17
|
|
20
18
|
it 'should accept configuration from #configure' do
|
21
19
|
url = "http://bucket_name.region.aliyuncs.com"
|
22
20
|
access_key = "access_key_from_aliyun"
|
23
|
-
Aliyun::Oss.configure(:
|
21
|
+
Aliyun::Oss.configure(:access_key_id => access_key, :not_used_para => "not used")
|
24
22
|
config = Aliyun::Oss.config
|
25
23
|
expect(config.keys).not_to include(:not_used_para)
|
26
24
|
expect(config[:access_key_id]).to eq(access_key)
|
27
|
-
expect(config[:log_level]).to eq('debug')
|
28
25
|
end
|
29
26
|
|
30
27
|
it 'should load yaml config file if specified' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aliyunoss
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- yijiecc
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nokogiri
|
@@ -73,6 +73,7 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
+
- ".byebug_history"
|
76
77
|
- ".gitignore"
|
77
78
|
- Gemfile
|
78
79
|
- LICENSE.txt
|
@@ -80,7 +81,6 @@ files:
|
|
80
81
|
- Rakefile
|
81
82
|
- aliyunoss.gemspec
|
82
83
|
- lib/aliyunoss.rb
|
83
|
-
- lib/aliyunoss/#oss_request.rb#
|
84
84
|
- lib/aliyunoss/api.rb
|
85
85
|
- lib/aliyunoss/bucket.rb
|
86
86
|
- lib/aliyunoss/config.rb
|
@@ -120,7 +120,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
120
|
version: '0'
|
121
121
|
requirements: []
|
122
122
|
rubyforge_project:
|
123
|
-
rubygems_version: 2.
|
123
|
+
rubygems_version: 2.6.14.1
|
124
124
|
signing_key:
|
125
125
|
specification_version: 4
|
126
126
|
summary: A gem for accessing Aliyun Open Storage Service.
|
@@ -1,154 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
require 'base64'
|
3
|
-
require 'openssl'
|
4
|
-
|
5
|
-
module Aliyun
|
6
|
-
module Oss
|
7
|
-
|
8
|
-
class OssRequest
|
9
|
-
|
10
|
-
include ConfigHelper
|
11
|
-
attr_accessor :bucket, :path, :body, :queris, :domain
|
12
|
-
|
13
|
-
def initialize(bucket, path, domain = nil, queries = {}, headers = {})
|
14
|
-
@bucket = bucket
|
15
|
-
@path = path
|
16
|
-
@queries = queries
|
17
|
-
@domain = domain
|
18
|
-
@headers = {"Content-Type" => "", "Content-MD5" => "", "Date" => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S GMT')}.merge(headers)
|
19
|
-
end
|
20
|
-
|
21
|
-
def get_uri
|
22
|
-
if @domain
|
23
|
-
uri = URI("http://#{domain}/")
|
24
|
-
else
|
25
|
-
if @bucket
|
26
|
-
uri = URI("http://#{bucket.name}.#{bucket.location}.#{host}")
|
27
|
-
else
|
28
|
-
uri = URI("http://oss.#{host}")
|
29
|
-
end
|
30
|
-
end
|
31
|
-
uri.path = @path
|
32
|
-
uri.query = @queries.to_query_string if @queries.count > 0
|
33
|
-
uri
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.add_operation(verb)
|
37
|
-
define_method(verb) do
|
38
|
-
uri = get_uri
|
39
|
-
|
40
|
-
request = Net::HTTP.send(:const_get, verb.to_s.capitalize).new(uri)
|
41
|
-
|
42
|
-
@headers.each_pair {|k,v| request[k] = v}
|
43
|
-
|
44
|
-
if @body
|
45
|
-
request.body = @body
|
46
|
-
digest = OpenSSL::Digest::MD5.digest(@body)
|
47
|
-
request['Content-MD5'] = Base64.encode64(digest).strip
|
48
|
-
request['Content-Length'] = @body.bytesize
|
49
|
-
end
|
50
|
-
|
51
|
-
request['Authorization'] = 'OSS ' + access_key_id + ':' +
|
52
|
-
signature(request)
|
53
|
-
|
54
|
-
logger.info(verb.to_s.upcase + ' ' + uri.to_s + ' ' + request.to_hash.to_s)
|
55
|
-
|
56
|
-
response = nil
|
57
|
-
Net::HTTP.start(uri.host, uri.port) do |http|
|
58
|
-
response = http.request(request)
|
59
|
-
logger.info(response.code.to_s + ' ' + response.message)
|
60
|
-
end
|
61
|
-
response
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
add_operation :get
|
66
|
-
add_operation :put
|
67
|
-
add_operation :delete
|
68
|
-
add_operation :head
|
69
|
-
add_operation :post
|
70
|
-
|
71
|
-
def url_for_sharing(expires_in)
|
72
|
-
uri = get_uri
|
73
|
-
request = Net::HTTP::Get.new(uri)
|
74
|
-
@headers.each_pair {|k,v| request[k] = v}
|
75
|
-
expires_at = (Time.now + expires_in).utc.to_i
|
76
|
-
request["Date"] = expires_at
|
77
|
-
uri.query = URI.encode_www_form({"OSSAccessKeyId" => access_key_id,
|
78
|
-
"Expires" => expires_at,
|
79
|
-
"Signature" => signature(request)})
|
80
|
-
uri.to_s
|
81
|
-
end
|
82
|
-
|
83
|
-
def [](key)
|
84
|
-
@headers[key]
|
85
|
-
end
|
86
|
-
|
87
|
-
def []=(key, value)
|
88
|
-
@headers[key] = value
|
89
|
-
end
|
90
|
-
|
91
|
-
private
|
92
|
-
def signature(req)
|
93
|
-
verb = req.class.to_s.gsub(/Net::HTTP::/, '').upcase
|
94
|
-
data = verb + "\n" + req["Content-MD5"] + "\n" +
|
95
|
-
req["Content-Type"] + "\n" + req["Date"] + "\n" +
|
96
|
-
canonicalized_oss_headers(req) +
|
97
|
-
canonicalized_resource()
|
98
|
-
|
99
|
-
digest = OpenSSL::Digest.new('sha1')
|
100
|
-
hmac = OpenSSL::HMAC.digest(digest, access_key_secret, data)
|
101
|
-
Base64.encode64(hmac).strip
|
102
|
-
end
|
103
|
-
|
104
|
-
# oss api 20140828.pdf - 4.2
|
105
|
-
# 1) 将所有以“x-oss-”为前缀的 HTTP 请求头的名字转换成小写字母。如 ’X-OSS-Meta-Name: TaoBao’
|
106
|
-
# 转换成 ’x-oss-meta-name: TaoBao’ 。
|
107
|
-
# 2) 将上一步得到的所有 HTTP 请求头按照字典序进行升序排列。
|
108
|
-
# 3) 如果有相同名字的请求头,则根据标准 RFC 2616, 4.2 章进行合并(两个值之间只用逗号分隔)。
|
109
|
-
# 如有两个名为’x-oss-meta-name’的请求头,对应的值分别为’TaoBao’和’Alipay’,则合并后
|
110
|
-
# 为: ’x-oss-meta-name:TaoBao,Alipay’ 。
|
111
|
-
# 4) 删除请求头和内容之间分隔符两端出现的任何空格。
|
112
|
-
# 如 ’x-oss-meta-name: TaoBao,Alipay’ 转换成: ’x-oss-meta-name:TaoBao,Alipay’ 。
|
113
|
-
# 5) 将所有的头和内容用 ’\n’ 分隔符分隔拼成最后的 CanonicalizedOSSHeader 。
|
114
|
-
def canonicalized_oss_headers(req)
|
115
|
-
hash = Hash.new
|
116
|
-
req.each_header do |header|
|
117
|
-
header = header.downcase
|
118
|
-
next unless header.start_with?('x-oss-')
|
119
|
-
if hash.has_key?(header)
|
120
|
-
hash[header] = hash[header] + "," + req[header].strip
|
121
|
-
else
|
122
|
-
hash[header] = req[header].strip
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
return "" if hash.count == 0
|
127
|
-
hash.keys.sort.map{|k| "#{k}:#{hash[k]}"}.join("\n") << "\n"
|
128
|
-
end
|
129
|
-
|
130
|
-
# oss api 20140828.pdf - 4.2
|
131
|
-
# 1) 将 CanonicalizedResource 置成空字符串( “” );
|
132
|
-
# 2) 放入要访问的 OSS 资源:“ /BucketName/ObjectName ”(无 ObjectName 则不填)
|
133
|
-
# 3) 如果请求的资源包括子资源 (sub-resource) ,那么将所有的子资源按照字典序,从小到大排列并
|
134
|
-
# 以 ’&’ 为分隔符生成子资源字符串。在 CanonicalizedResource 字符串尾添加“?”和子资源字
|
135
|
-
# 符串。此时的 CanonicalizedResource 例子如: /BucketName/ObjectName?acl &uploadId=UploadId
|
136
|
-
# 4) 如果用户请求在查询字符串 (query string) 中指定了要重写 (override) 返回请求的 header,那么将这
|
137
|
-
# 些查询字符串及其请求值按照字典序,从小到大排列,以 ’&’ 为分隔符,按参数的字典序添加到
|
138
|
-
# CanonicalizedResource 中。此时的 CanonicalizedResource 例子:
|
139
|
-
# /BucketName/ObjectName?acl&response-content-type=ContentType & uploadId =UploadId
|
140
|
-
def canonicalized_resource()
|
141
|
-
return @path unless @bucket
|
142
|
-
return "/#{@bucket.name}#{@path}" if @queries.count == 0
|
143
|
-
|
144
|
-
array = @queries.keys.sort.map do |k|
|
145
|
-
if @queries[k] then "#{k}=#{@queries[k]}" else "#{k}" end
|
146
|
-
end
|
147
|
-
|
148
|
-
"/#{@bucket.name}#{@path}?#{array.sort.join('&')}"
|
149
|
-
end
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
end
|
154
|
-
end
|