fog-aliyun 0.3.7 → 0.3.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +61 -3
- data/fog-aliyun.gemspec +7 -3
- data/lib/fog/aliyun.rb +6 -9
- data/lib/fog/aliyun/models/storage/directories.rb +34 -13
- data/lib/fog/aliyun/models/storage/directory.rb +16 -7
- data/lib/fog/aliyun/models/storage/file.rb +26 -21
- data/lib/fog/aliyun/models/storage/files.rb +104 -77
- data/lib/fog/aliyun/requests/storage/copy_object.rb +3 -5
- data/lib/fog/aliyun/requests/storage/delete_bucket.rb +3 -5
- data/lib/fog/aliyun/requests/storage/delete_container.rb +3 -5
- data/lib/fog/aliyun/requests/storage/delete_object.rb +5 -10
- data/lib/fog/aliyun/requests/storage/get_bucket.rb +43 -32
- data/lib/fog/aliyun/requests/storage/get_container.rb +2 -2
- data/lib/fog/aliyun/requests/storage/get_containers.rb +8 -3
- data/lib/fog/aliyun/requests/storage/get_object.rb +12 -25
- data/lib/fog/aliyun/requests/storage/get_object_http_url.rb +2 -2
- data/lib/fog/aliyun/requests/storage/get_object_https_url.rb +2 -2
- data/lib/fog/aliyun/requests/storage/head_object.rb +3 -5
- data/lib/fog/aliyun/requests/storage/list_buckets.rb +2 -2
- data/lib/fog/aliyun/requests/storage/list_objects.rb +23 -25
- data/lib/fog/aliyun/requests/storage/put_bucket.rb +2 -2
- data/lib/fog/aliyun/requests/storage/put_container.rb +3 -5
- data/lib/fog/aliyun/requests/storage/put_object.rb +24 -42
- data/lib/fog/aliyun/storage.rb +24 -10
- data/lib/fog/aliyun/version.rb +1 -1
- data/lib/fog/bin/aliyun.rb +1 -1
- metadata +61 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c47b8a9b6a56d553d1b0161be29b2d2444671f41f083e8af34707bd1eadc1718
|
4
|
+
data.tar.gz: 17e83f9d11b7ae7b1802941ddb13427346bbd971b563d7ac04436f7d036d7ef7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52060f2e1a3881ccb72ccc6e5fbeddd988bd2820416c419a7409e714c6d4f08fb7b37f5f98ff1e8fc66b47c0f2aa5656349da06e939edfb0c78c4adba05bf1ef
|
7
|
+
data.tar.gz: 30bdcf81e3e78e2983545d391ef2062ebc49975bee90c9d93226f30a631b3eaa7627916b179d15c684b38211bbd2e9e78e84210a2471b8185c5c3d21fbfe3001
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -30,9 +30,9 @@ Since it's a bad practice to have your credentials in source code, you should lo
|
|
30
30
|
|
31
31
|
```
|
32
32
|
default:
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
aliyun_accesskey_id: "<YOUR_ACCESS_KEY_ID>"
|
34
|
+
aliyun_accesskey_secret: "<YOUR_SECRET_ACCESS_KEY>"
|
35
|
+
aliyun_region_id: "<YOUR_TARGET_REGION>"
|
36
36
|
```
|
37
37
|
|
38
38
|
### Connecting to OSS
|
@@ -307,6 +307,64 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
307
307
|
|
308
308
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
309
309
|
|
310
|
+
## Testing
|
311
|
+
|
312
|
+
|
313
|
+
|
314
|
+
To run test suite use the following command:
|
315
|
+
|
316
|
+
```
|
317
|
+
rake spec
|
318
|
+
```
|
319
|
+
|
320
|
+
### Code coverage
|
321
|
+
|
322
|
+
To run test suite with code coverage:
|
323
|
+
|
324
|
+
```
|
325
|
+
export COVERAGE=true
|
326
|
+
rake spec
|
327
|
+
```
|
328
|
+
|
329
|
+
The result will be generated in `coverage` folder.
|
330
|
+
|
331
|
+
### Integration tests
|
332
|
+
|
333
|
+
To run integration tests please prepare a set of AliCloud credentials to be used by integration tests.
|
334
|
+
|
335
|
+
Define the credentials and bucket in `~/.fog` file in using following format:
|
336
|
+
|
337
|
+
```
|
338
|
+
default:
|
339
|
+
aliyun_accesskey_id: "...access key..." # You can create a set of credentials
|
340
|
+
aliyun_accesskey_secret: "...secret..." # using Alicloud console portal
|
341
|
+
aliyun_region_id: "...region name..." # Example: cn-shanghai
|
342
|
+
aliyun_oss_bucket: "...name of the bucket..." # Example: fog-integration-test-bucket
|
343
|
+
```
|
344
|
+
|
345
|
+
WARNING: Do NOT use any productive account credentials and buckets for the testing, it may be harmful to your data!
|
346
|
+
|
347
|
+
The tests are using [https://github.com/aliyun/aliyun-cli#installation](Aliyun CLI) to setup integration bucket and content for tests,
|
348
|
+
please install it locally before running integration tests.
|
349
|
+
|
350
|
+
Aliyun CLI will be configured automatically as part of test execution using the credentials provided for fog connection.
|
351
|
+
|
352
|
+
Then run the test suite with `INTEGRATION` environment variable to activate integration tests:
|
353
|
+
|
354
|
+
```
|
355
|
+
export INTEGRATION=true
|
356
|
+
rake spec
|
357
|
+
```
|
358
|
+
|
359
|
+
### Performance test
|
360
|
+
|
361
|
+
Performance tests are providing memory consumption report for download/upload operations.
|
362
|
+
|
363
|
+
```
|
364
|
+
export PERFORMANCE=true
|
365
|
+
rake spec
|
366
|
+
```
|
367
|
+
|
310
368
|
## License
|
311
369
|
|
312
370
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/fog-aliyun.gemspec
CHANGED
@@ -7,10 +7,10 @@ require 'fog/aliyun/version'
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
8
|
spec.name = 'fog-aliyun'
|
9
9
|
spec.version = Fog::Aliyun::VERSION
|
10
|
-
spec.authors = ['Qinsi Deng, Jianxun Li, Jane Han']
|
11
|
-
spec.email = ['dengqinsi@sina.com']
|
10
|
+
spec.authors = ['Qinsi Deng, Jianxun Li, Jane Han, Guimin He']
|
11
|
+
spec.email = ['dengqinsi@sina.com', 'guimin.hgm@alibaba-inc.com']
|
12
12
|
|
13
|
-
spec.summary = 'Fog provider for
|
13
|
+
spec.summary = 'Fog provider for Alibaba Cloud Web Services.'
|
14
14
|
spec.description = 'As a FOG provider, fog-aliyun support aliyun OSS/ECS. It will support more aliyun services later.'
|
15
15
|
spec.homepage = 'https://github.com/fog/fog-aliyun'
|
16
16
|
spec.license = 'MIT'
|
@@ -26,9 +26,13 @@ Gem::Specification.new do |spec|
|
|
26
26
|
spec.add_development_dependency 'rake'
|
27
27
|
spec.add_development_dependency 'rspec'
|
28
28
|
spec.add_development_dependency 'rubocop'
|
29
|
+
spec.add_development_dependency 'simplecov'
|
30
|
+
spec.add_development_dependency 'memory_profiler'
|
31
|
+
spec.add_development_dependency 'aliyun-sdk'
|
29
32
|
|
30
33
|
spec.add_dependency 'fog-core'
|
31
34
|
spec.add_dependency 'fog-json'
|
32
35
|
spec.add_dependency 'ipaddress', '~> 0.8'
|
33
36
|
spec.add_dependency 'xml-simple', '~> 1.1'
|
37
|
+
spec.add_dependency 'aliyun-sdk'
|
34
38
|
end
|
data/lib/fog/aliyun.rb
CHANGED
@@ -2,19 +2,16 @@
|
|
2
2
|
|
3
3
|
require 'fog/core'
|
4
4
|
require 'fog/json'
|
5
|
-
require '
|
5
|
+
require File.expand_path('../aliyun/version', __FILE__)
|
6
6
|
|
7
7
|
module Fog
|
8
|
-
module Compute
|
9
|
-
autoload :Aliyun, 'fog/aliyun/compute'
|
10
|
-
end
|
11
|
-
|
12
|
-
module Storage
|
13
|
-
autoload :Aliyun, 'fog/aliyun/storage'
|
14
|
-
end
|
15
|
-
|
16
8
|
module Aliyun
|
17
9
|
extend Fog::Provider
|
10
|
+
|
11
|
+
# Services
|
12
|
+
autoload :Compute, File.expand_path('../aliyun/compute', __FILE__)
|
13
|
+
autoload :Storage, File.expand_path('../aliyun/storage', __FILE__)
|
14
|
+
|
18
15
|
service(:compute, 'Compute')
|
19
16
|
service(:storage, 'Storage')
|
20
17
|
end
|
@@ -4,10 +4,10 @@ require 'fog/core/collection'
|
|
4
4
|
require 'fog/aliyun/models/storage/directory'
|
5
5
|
|
6
6
|
module Fog
|
7
|
-
module
|
8
|
-
class
|
7
|
+
module Aliyun
|
8
|
+
class Storage
|
9
9
|
class Directories < Fog::Collection
|
10
|
-
model Fog::Storage::
|
10
|
+
model Fog::Aliyun::Storage::Directory
|
11
11
|
|
12
12
|
def all
|
13
13
|
containers = service.get_containers
|
@@ -30,6 +30,9 @@ module Fog
|
|
30
30
|
# If key is a directory(including /), return an existed or a new one;
|
31
31
|
# If key does not contain /, if bucket, return '', else return an existed or a new one directory;
|
32
32
|
def get(key, options = {})
|
33
|
+
if key.is_a? Array
|
34
|
+
key = key[0]
|
35
|
+
end
|
33
36
|
if !key.nil? && key != '' && key != '.'
|
34
37
|
key = key.chomp('/')
|
35
38
|
if key.include? '/'
|
@@ -37,21 +40,39 @@ module Fog
|
|
37
40
|
ret = service.head_object(dir, options)
|
38
41
|
new(key: key) if ret.data[:status] == 200
|
39
42
|
else
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
43
|
+
remap_attributes(options, {
|
44
|
+
:delimiter => 'delimiter',
|
45
|
+
:marker => 'marker',
|
46
|
+
:max_keys => 'max-keys',
|
47
|
+
:prefix => 'prefix'
|
48
|
+
})
|
49
|
+
data = service.get_bucket(key, options)
|
50
|
+
directory = new(:key => data['Name'], :is_persisted => true)
|
51
|
+
options = {}
|
52
|
+
for k, v in data
|
53
|
+
if ['CommonPrefixes', 'Delimiter', 'IsTruncated', 'Marker', 'MaxKeys', 'Prefix'].include?(k)
|
54
|
+
# Sometimes, the v will be a Array, like "Name"=>["blobstore-droplet1"], "Prefix"=>[{}], "Marker"=>[{}], "MaxKeys"=>["100"], "Delimiter"=>[{}], "IsTruncated"=>["false"]
|
55
|
+
# and there needs to parse them
|
56
|
+
if !v.nil? && (v.is_a? Array) && (v.size > 0)
|
57
|
+
if v[0].is_a? Hash
|
58
|
+
v = nil
|
59
|
+
else
|
60
|
+
v = v[0]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
options[k] = v
|
64
|
+
end
|
65
|
+
end
|
66
|
+
directory.files.merge_attributes(options)
|
67
|
+
if data.key?('Contents') && !data['Contents'].nil?
|
68
|
+
directory.files.load(data['Contents'])
|
49
69
|
end
|
70
|
+
directory
|
50
71
|
end
|
51
72
|
else
|
52
73
|
new(key: '')
|
53
74
|
end
|
54
|
-
rescue Fog::Storage::
|
75
|
+
rescue Fog::Aliyun::Storage::NotFound
|
55
76
|
nil
|
56
77
|
end
|
57
78
|
end
|
@@ -4,10 +4,10 @@ require 'fog/core/model'
|
|
4
4
|
require 'fog/aliyun/models/storage/files'
|
5
5
|
|
6
6
|
module Fog
|
7
|
-
module
|
8
|
-
class
|
7
|
+
module Aliyun
|
8
|
+
class Storage
|
9
9
|
class Directory < Fog::Model
|
10
|
-
identity :key
|
10
|
+
identity :key, :aliases => ['Key', 'Name', 'name']
|
11
11
|
|
12
12
|
def destroy
|
13
13
|
requires :key
|
@@ -15,20 +15,19 @@ module Fog
|
|
15
15
|
ret = service.list_objects(prefix: prefix)['Contents']
|
16
16
|
|
17
17
|
if ret.nil?
|
18
|
-
puts ' Not found: Direction not exist!'
|
19
18
|
false
|
20
19
|
elsif ret.size == 1
|
21
20
|
service.delete_container(key)
|
22
21
|
true
|
23
22
|
else
|
24
|
-
raise Fog::Storage::
|
23
|
+
raise Fog::Aliyun::Storage::Error, ' Forbidden: Direction not empty!'
|
25
24
|
false
|
26
25
|
end
|
27
26
|
end
|
28
27
|
|
29
28
|
def files
|
30
29
|
@files ||= begin
|
31
|
-
Fog::Storage::
|
30
|
+
Fog::Aliyun::Storage::Files.new(
|
32
31
|
directory: self,
|
33
32
|
service: service
|
34
33
|
)
|
@@ -41,7 +40,17 @@ module Fog
|
|
41
40
|
|
42
41
|
def save
|
43
42
|
requires :key
|
44
|
-
|
43
|
+
|
44
|
+
# Checking whether the key is a bucket and meet the multi-bucket scenario.
|
45
|
+
# If the key is a existing bucket, return it directly.
|
46
|
+
key = key.chomp('/')
|
47
|
+
if !key.nil? && key != '' && key != '.' && !(key.include? '/')
|
48
|
+
data = service.get_bucket(key)
|
49
|
+
if data.class == Hash && data.key?('Code') && !data['Code'].nil? && !data['Code'].empty?
|
50
|
+
service.put_container(key)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
45
54
|
true
|
46
55
|
end
|
47
56
|
end
|
@@ -3,10 +3,10 @@
|
|
3
3
|
require 'fog/core/model'
|
4
4
|
|
5
5
|
module Fog
|
6
|
-
module
|
7
|
-
class
|
6
|
+
module Aliyun
|
7
|
+
class Storage
|
8
8
|
class File < Fog::Model
|
9
|
-
identity :key, aliases: 'name'
|
9
|
+
identity :key, aliases: ['Key', 'Name', 'name']
|
10
10
|
attribute :date, aliases: 'Date'
|
11
11
|
attribute :content_length, aliases: 'Content-Length', type: :integer
|
12
12
|
attribute :content_type, aliases: 'Content-Type'
|
@@ -35,29 +35,32 @@ module Fog
|
|
35
35
|
|
36
36
|
def copy(target_directory_key, target_file_key, options = {})
|
37
37
|
requires :directory, :key
|
38
|
-
|
38
|
+
source_bucket, directory_key = collection.check_directory_key(directory.key)
|
39
|
+
source_object = if directory_key == ''
|
39
40
|
key
|
40
41
|
else
|
41
|
-
|
42
|
+
directory_key + '/' + key
|
42
43
|
end
|
44
|
+
target_bucket, target_directory_key = collection.check_directory_key(target_directory_key)
|
43
45
|
target_object = if target_directory_key == ''
|
44
46
|
target_file_key
|
45
47
|
else
|
46
48
|
target_directory_key + '/' + target_file_key
|
47
49
|
end
|
48
|
-
service.copy_object(
|
50
|
+
service.copy_object(source_bucket, source_object, target_bucket, target_object, options)
|
49
51
|
target_directory = service.directories.new(key: target_directory_key)
|
50
52
|
target_directory.files.get(target_file_key)
|
51
53
|
end
|
52
54
|
|
53
55
|
def destroy
|
54
56
|
requires :directory, :key
|
55
|
-
|
57
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
58
|
+
object = if directory_key == ''
|
56
59
|
key
|
57
60
|
else
|
58
|
-
|
61
|
+
directory_key + '/' + key
|
59
62
|
end
|
60
|
-
service.delete_object(object)
|
63
|
+
service.delete_object(object, bucket: bucket_name)
|
61
64
|
true
|
62
65
|
end
|
63
66
|
|
@@ -91,12 +94,13 @@ module Fog
|
|
91
94
|
expires = expires.nil? ? 0 : expires.to_i
|
92
95
|
|
93
96
|
requires :directory, :key
|
94
|
-
|
97
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
98
|
+
object = if directory_key == ''
|
95
99
|
key
|
96
100
|
else
|
97
|
-
|
101
|
+
directory_key + '/' + key
|
98
102
|
end
|
99
|
-
service.get_object_http_url_public(object, expires, options)
|
103
|
+
service.get_object_http_url_public(object, expires, options.merge(bucket: bucket_name))
|
100
104
|
end
|
101
105
|
|
102
106
|
def public_url
|
@@ -109,18 +113,18 @@ module Fog
|
|
109
113
|
options['Content-Type'] = content_type if content_type
|
110
114
|
options['Content-Disposition'] = content_disposition if content_disposition
|
111
115
|
options.merge!(metadata_to_headers)
|
112
|
-
|
113
|
-
object = if
|
116
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
117
|
+
object = if directory_key == ''
|
114
118
|
key
|
115
119
|
else
|
116
|
-
|
120
|
+
directory_key + '/' + key
|
117
121
|
end
|
118
122
|
if body.is_a?(::File)
|
119
|
-
data = service.put_object(object, body, options).data
|
123
|
+
data = service.put_object(object, body, options.merge(bucket: bucket_name)).data
|
120
124
|
elsif body.is_a?(String)
|
121
|
-
data = service.put_object_with_body(object, body, options).data
|
125
|
+
data = service.put_object_with_body(object, body, options.merge(bucket: bucket_name)).data
|
122
126
|
else
|
123
|
-
raise Fog::Storage::
|
127
|
+
raise Fog::Aliyun::Storage::Error, " Forbidden: Invalid body type: #{body.class}!"
|
124
128
|
end
|
125
129
|
update_attributes_from(data)
|
126
130
|
refresh_metadata
|
@@ -168,13 +172,14 @@ module Fog
|
|
168
172
|
|
169
173
|
def metadata_attributes
|
170
174
|
if last_modified
|
171
|
-
|
175
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
176
|
+
object = if directory_key == ''
|
172
177
|
key
|
173
178
|
else
|
174
|
-
|
179
|
+
directory_key + '/' + key
|
175
180
|
end
|
176
181
|
|
177
|
-
data = service.head_object(object).data
|
182
|
+
data = service.head_object(object, bucket: bucket_name).data
|
178
183
|
if data[:status] == 200
|
179
184
|
headers = data[:headers]
|
180
185
|
headers.select! { |k, _v| metadata_attribute?(k) }
|
@@ -2,23 +2,67 @@
|
|
2
2
|
|
3
3
|
require 'fog/core/collection'
|
4
4
|
require 'fog/aliyun/models/storage/file'
|
5
|
+
require 'aliyun/oss'
|
5
6
|
|
6
7
|
module Fog
|
7
|
-
module
|
8
|
-
class
|
8
|
+
module Aliyun
|
9
|
+
class Storage
|
9
10
|
class Files < Fog::Collection
|
10
11
|
attribute :directory
|
11
12
|
attribute :limit
|
12
|
-
attribute :
|
13
|
+
attribute :prefix, :aliases => 'Prefix'
|
13
14
|
attribute :path
|
14
|
-
attribute :
|
15
|
-
|
16
|
-
|
15
|
+
attribute :common_prefixes, :aliases => 'CommonPrefixes'
|
16
|
+
attribute :delimiter, :aliases => 'Delimiter'
|
17
|
+
attribute :is_truncated, :aliases => 'IsTruncated'
|
18
|
+
attribute :marker, :aliases => 'Marker'
|
19
|
+
attribute :max_keys, :aliases => ['MaxKeys', 'max-keys']
|
20
|
+
|
21
|
+
model Fog::Aliyun::Storage::File
|
22
|
+
|
23
|
+
# check_directory_key have two functions:
|
24
|
+
# 1. trim the directory_key suffix '/'
|
25
|
+
# 2. checking whether the directory_key is a bucket.
|
26
|
+
# If so, it will return directly to avoid to create a new redundant folder named with directory_key.
|
27
|
+
# This point will be applied to multi-bucket and make bucket as a directory scenario.
|
28
|
+
def check_directory_key(directory_key)
|
29
|
+
bucket_name = nil
|
30
|
+
if directory_key.is_a? Array
|
31
|
+
directory_key = directory_key[0]
|
32
|
+
end
|
33
|
+
if directory_key != ''
|
34
|
+
# trim the suffix '/'
|
35
|
+
directory_key = directory_key.chomp('/')
|
36
|
+
# The bucket name can not contain '/', so if directory_key, return directory.
|
37
|
+
if directory_key.include? '/'
|
38
|
+
directory_key
|
39
|
+
else
|
40
|
+
data = service.get_bucket(directory_key)
|
41
|
+
if data.class == Hash && data.key?('Code') && !data['Code'].nil? && !data['Code'].empty?
|
42
|
+
directory_key
|
43
|
+
else
|
44
|
+
bucket_name = directory_key
|
45
|
+
directory_key = ''
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
return bucket_name, directory_key
|
50
|
+
end
|
17
51
|
|
18
|
-
def all(
|
52
|
+
def all(options = {})
|
19
53
|
requires :directory
|
20
|
-
|
21
|
-
|
54
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
55
|
+
remap_attributes(options, {
|
56
|
+
:delimiter => 'delimiter',
|
57
|
+
:marker => 'marker',
|
58
|
+
:max_keys => 'max-keys',
|
59
|
+
:prefix => 'prefix'
|
60
|
+
})
|
61
|
+
prefix_value = options['prefix']
|
62
|
+
prefix_value = directory_key + '/' + prefix if directory_key != '' && directory_key != '.' && !directory_key.nil?
|
63
|
+
options['prefix'] = prefix_value
|
64
|
+
options['bucket'] = bucket_name
|
65
|
+
files = service.list_objects(options)['Contents']
|
22
66
|
return if files.nil?
|
23
67
|
data = []
|
24
68
|
i = 0
|
@@ -59,112 +103,88 @@ module Fog
|
|
59
103
|
|
60
104
|
def get(key)
|
61
105
|
requires :directory
|
62
|
-
|
106
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
107
|
+
object = if directory_key == ''
|
63
108
|
key
|
64
109
|
else
|
65
|
-
|
110
|
+
directory_key + '/' + key
|
66
111
|
end
|
67
112
|
begin
|
68
|
-
data = service.get_object(object)
|
69
|
-
|
70
|
-
|
71
|
-
|
113
|
+
data = service.get_object(object, nil, bucket: bucket_name)
|
114
|
+
lastModified = data['headers'][:last_modified]
|
115
|
+
last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
|
116
|
+
|
117
|
+
date = data['headers'][:date]
|
118
|
+
date = (Time.parse(date).localtime if !date.nil? && date != '')
|
119
|
+
file_data = {
|
120
|
+
body: data[:body],
|
121
|
+
content_length: data['headers'][:content_length].to_i,
|
122
|
+
key: key,
|
123
|
+
last_modified: last_modified,
|
124
|
+
content_type: data['headers'][:content_type],
|
125
|
+
etag: data['headers'][:etag],
|
126
|
+
date: date,
|
127
|
+
connection: data['headers'][:connection],
|
128
|
+
accept_ranges: data['headers'][:accept_ranges],
|
129
|
+
server: data['headers'][:server],
|
130
|
+
object_type: data['headers'][:x_oss_object_type]
|
131
|
+
}
|
132
|
+
|
133
|
+
new(file_data)
|
134
|
+
rescue AliyunOssSdk::ServerError => error
|
135
|
+
case error.error_code
|
136
|
+
when %r{NoSuchKey},%r{SymlinkTargetNotExist}
|
72
137
|
nil
|
73
138
|
else
|
74
139
|
raise(error)
|
75
140
|
end
|
76
141
|
end
|
77
|
-
|
78
|
-
contentLen = data[:headers]['Content-Length'].to_i
|
79
|
-
|
80
|
-
if block_given?
|
81
|
-
pagesNum = (contentLen + Excon::CHUNK_SIZE - 1) / Excon::CHUNK_SIZE
|
82
|
-
|
83
|
-
for i in 1..pagesNum
|
84
|
-
_start = (i - 1) * Excon::CHUNK_SIZE
|
85
|
-
_end = i * Excon::CHUNK_SIZE - 1
|
86
|
-
range = "#{_start}-#{_end}"
|
87
|
-
begin
|
88
|
-
data = service.get_object(object, range)
|
89
|
-
chunk = data[:body]
|
90
|
-
rescue StandardError => error
|
91
|
-
case error.response.body
|
92
|
-
when %r{<Code>NoSuchKey</Code>},%r{<Code>SymlinkTargetNotExist</Code>}
|
93
|
-
chunk = ''
|
94
|
-
else
|
95
|
-
raise(error)
|
96
|
-
end
|
97
|
-
end
|
98
|
-
yield(chunk)
|
99
|
-
body = nil
|
100
|
-
end
|
101
|
-
else
|
102
|
-
body = data[:body]
|
103
|
-
end
|
104
|
-
|
105
|
-
lastModified = data[:headers]['Last-Modified']
|
106
|
-
last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
|
107
|
-
|
108
|
-
date = data[:headers]['Date']
|
109
|
-
date = (Time.parse(date).localtime if !date.nil? && date != '')
|
110
|
-
file_data = {
|
111
|
-
body: body,
|
112
|
-
content_length: contentLen,
|
113
|
-
key: key,
|
114
|
-
last_modified: last_modified,
|
115
|
-
content_type: data[:headers]['Content-Type'],
|
116
|
-
etag: data[:headers]['ETag'],
|
117
|
-
date: date,
|
118
|
-
connection: data[:headers]['Connection'],
|
119
|
-
accept_ranges: data[:headers]['Accept-Ranges'],
|
120
|
-
server: data[:headers]['Server'],
|
121
|
-
object_type: data[:headers]['x-oss-object-type'],
|
122
|
-
content_disposition: data[:headers]['Content-Disposition']
|
123
|
-
}
|
124
|
-
|
125
|
-
new(file_data)
|
126
142
|
end
|
127
143
|
|
128
144
|
def get_url(key)
|
129
145
|
requires :directory
|
130
|
-
|
146
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
147
|
+
object = if directory_key == ''
|
131
148
|
key
|
132
149
|
else
|
133
|
-
|
150
|
+
directory_key + '/' + key
|
134
151
|
end
|
135
|
-
service.get_object_http_url_public(object, 3600)
|
152
|
+
service.get_object_http_url_public(object, 3600, bucket: bucket_name)
|
136
153
|
end
|
137
154
|
|
138
155
|
def get_http_url(key, expires, options = {})
|
139
156
|
requires :directory
|
140
|
-
|
157
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
158
|
+
object = if directory_key == ''
|
141
159
|
key
|
142
160
|
else
|
143
|
-
|
161
|
+
directory_key + '/' + key
|
144
162
|
end
|
145
163
|
expires = expires.nil? ? 0 : expires.to_i
|
146
|
-
service.get_object_http_url_public(object, expires, options)
|
164
|
+
service.get_object_http_url_public(object, expires, options.merge(bucket: bucket_name))
|
147
165
|
end
|
148
166
|
|
149
167
|
def get_https_url(key, expires, options = {})
|
150
168
|
requires :directory
|
151
|
-
|
169
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
170
|
+
object = if directory_key == ''
|
152
171
|
key
|
153
172
|
else
|
154
|
-
|
173
|
+
directory_key + '/' + key
|
155
174
|
end
|
156
175
|
expires = expires.nil? ? 0 : expires.to_i
|
157
|
-
service.get_object_https_url_public(object, expires, options)
|
176
|
+
service.get_object_https_url_public(object, expires, options.merge(bucket: bucket_name))
|
158
177
|
end
|
159
178
|
|
160
179
|
def head(key, _options = {})
|
161
180
|
requires :directory
|
162
|
-
|
181
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
182
|
+
object = if directory_key == ''
|
163
183
|
key
|
164
184
|
else
|
165
|
-
|
185
|
+
directory_key + '/' + key
|
166
186
|
end
|
167
|
-
data = service.head_object(object).data
|
187
|
+
data = service.head_object(object, bucket: bucket_name).data
|
168
188
|
return nil if data[:status] == 404
|
169
189
|
lastModified = data[:headers]['Last-Modified']
|
170
190
|
last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
|
@@ -185,12 +205,19 @@ module Fog
|
|
185
205
|
object_type: data[:headers]['x-oss-object-type']
|
186
206
|
}
|
187
207
|
new(file_data)
|
188
|
-
rescue Fog::Storage::
|
208
|
+
rescue Fog::Aliyun::Storage::NotFound
|
189
209
|
nil
|
190
210
|
end
|
191
211
|
|
192
212
|
def new(attributes = {})
|
193
213
|
requires :directory
|
214
|
+
# Sometimes, the v will be a Array, like "Prefix"=>[{}], "Marker"=>[xxxx], "MaxKeys"=>["100"], "IsTruncated"=>["false"]
|
215
|
+
# and there needs to parse them
|
216
|
+
for k, v in attributes
|
217
|
+
if !v.nil? && (v.is_a? Array) && (v.size > 0)
|
218
|
+
attributes[k] = v[0]
|
219
|
+
end
|
220
|
+
end
|
194
221
|
super({ directory: directory }.merge!(attributes))
|
195
222
|
end
|
196
223
|
end
|