fog-aliyun 0.3.8 → 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +1 -0
- data/README.md +61 -3
- data/fog-aliyun.gemspec +2 -0
- data/lib/fog/aliyun.rb +6 -9
- data/lib/fog/aliyun/models/storage/directories.rb +34 -11
- data/lib/fog/aliyun/models/storage/directory.rb +5 -7
- data/lib/fog/aliyun/models/storage/file.rb +16 -16
- data/lib/fog/aliyun/models/storage/files.rb +71 -78
- 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 +9 -31
- 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 +30 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3be4a1832619663a88cd9ac70eada6d06c24b9e8b7f11da0242516d2e379acd
|
4
|
+
data.tar.gz: 5d9338f0e592f82b9f2565ee8fb5c46077d2b1156e72a808a7c476a17e7da8fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7aebf30618f7e098f37c4a0a0c9a10bba29d33062bc9789547d92caf0dd220a75c7e303b22a64f1c27eec7385be4c4e18b3542aff1430ba5020dea7e763866c0
|
7
|
+
data.tar.gz: dd9e04bac82d1acfd60ef696d43b02f181d810aad04a9ad8bff8e6c9038c9a464fd91ad3dbab2c65b491bb1b929ca6cb4f35b9bd06f4485e65a67fe60baaad03
|
data/.gitignore
CHANGED
data/Gemfile
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
@@ -26,6 +26,8 @@ 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'
|
29
31
|
|
30
32
|
spec.add_dependency 'fog-core'
|
31
33
|
spec.add_dependency 'fog-json'
|
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,19 +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
|
-
|
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'])
|
47
69
|
end
|
70
|
+
directory
|
48
71
|
end
|
49
72
|
else
|
50
73
|
new(key: '')
|
51
74
|
end
|
52
|
-
rescue Fog::Storage::
|
75
|
+
rescue Fog::Aliyun::Storage::NotFound
|
53
76
|
nil
|
54
77
|
end
|
55
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
|
)
|
@@ -48,7 +47,6 @@ module Fog
|
|
48
47
|
if !key.nil? && key != '' && key != '.' && !(key.include? '/')
|
49
48
|
data = service.get_bucket(key)
|
50
49
|
if data.class == Hash && data.key?('Code') && !data['Code'].nil? && !data['Code'].empty?
|
51
|
-
puts "[INFO] The key #{key} is not a bucket and create one folder named with it."
|
52
50
|
service.put_container(key)
|
53
51
|
end
|
54
52
|
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,32 +35,32 @@ module Fog
|
|
35
35
|
|
36
36
|
def copy(target_directory_key, target_file_key, options = {})
|
37
37
|
requires :directory, :key
|
38
|
-
directory_key = collection.check_directory_key(directory.key)
|
38
|
+
source_bucket, directory_key = collection.check_directory_key(directory.key)
|
39
39
|
source_object = if directory_key == ''
|
40
40
|
key
|
41
41
|
else
|
42
42
|
directory_key + '/' + key
|
43
43
|
end
|
44
|
-
target_directory_key = collection.check_directory_key(target_directory_key)
|
44
|
+
target_bucket, target_directory_key = collection.check_directory_key(target_directory_key)
|
45
45
|
target_object = if target_directory_key == ''
|
46
46
|
target_file_key
|
47
47
|
else
|
48
48
|
target_directory_key + '/' + target_file_key
|
49
49
|
end
|
50
|
-
service.copy_object(
|
50
|
+
service.copy_object(source_bucket, source_object, target_bucket, target_object, options)
|
51
51
|
target_directory = service.directories.new(key: target_directory_key)
|
52
52
|
target_directory.files.get(target_file_key)
|
53
53
|
end
|
54
54
|
|
55
55
|
def destroy
|
56
56
|
requires :directory, :key
|
57
|
-
directory_key = collection.check_directory_key(directory.key)
|
57
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
58
58
|
object = if directory_key == ''
|
59
59
|
key
|
60
60
|
else
|
61
61
|
directory_key + '/' + key
|
62
62
|
end
|
63
|
-
service.delete_object(object)
|
63
|
+
service.delete_object(object, bucket: bucket_name)
|
64
64
|
true
|
65
65
|
end
|
66
66
|
|
@@ -94,13 +94,13 @@ module Fog
|
|
94
94
|
expires = expires.nil? ? 0 : expires.to_i
|
95
95
|
|
96
96
|
requires :directory, :key
|
97
|
-
directory_key = collection.check_directory_key(directory.key)
|
97
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
98
98
|
object = if directory_key == ''
|
99
99
|
key
|
100
100
|
else
|
101
101
|
directory_key + '/' + key
|
102
102
|
end
|
103
|
-
service.get_object_http_url_public(object, expires, options)
|
103
|
+
service.get_object_http_url_public(object, expires, options.merge(bucket: bucket_name))
|
104
104
|
end
|
105
105
|
|
106
106
|
def public_url
|
@@ -113,18 +113,18 @@ module Fog
|
|
113
113
|
options['Content-Type'] = content_type if content_type
|
114
114
|
options['Content-Disposition'] = content_disposition if content_disposition
|
115
115
|
options.merge!(metadata_to_headers)
|
116
|
-
directory_key = collection.check_directory_key(directory.key)
|
116
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
117
117
|
object = if directory_key == ''
|
118
118
|
key
|
119
119
|
else
|
120
120
|
directory_key + '/' + key
|
121
121
|
end
|
122
122
|
if body.is_a?(::File)
|
123
|
-
data = service.put_object(object, body, options).data
|
123
|
+
data = service.put_object(object, body, options.merge(bucket: bucket_name)).data
|
124
124
|
elsif body.is_a?(String)
|
125
|
-
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
|
126
126
|
else
|
127
|
-
raise Fog::Storage::
|
127
|
+
raise Fog::Aliyun::Storage::Error, " Forbidden: Invalid body type: #{body.class}!"
|
128
128
|
end
|
129
129
|
update_attributes_from(data)
|
130
130
|
refresh_metadata
|
@@ -172,14 +172,14 @@ module Fog
|
|
172
172
|
|
173
173
|
def metadata_attributes
|
174
174
|
if last_modified
|
175
|
-
directory_key = collection.check_directory_key(directory.key)
|
175
|
+
bucket_name, directory_key = collection.check_directory_key(directory.key)
|
176
176
|
object = if directory_key == ''
|
177
177
|
key
|
178
178
|
else
|
179
179
|
directory_key + '/' + key
|
180
180
|
end
|
181
181
|
|
182
|
-
data = service.head_object(object).data
|
182
|
+
data = service.head_object(object, bucket: bucket_name).data
|
183
183
|
if data[:status] == 200
|
184
184
|
headers = data[:headers]
|
185
185
|
headers.select! { |k, _v| metadata_attribute?(k) }
|
@@ -2,18 +2,23 @@
|
|
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
|
+
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']
|
15
20
|
|
16
|
-
model Fog::Storage::
|
21
|
+
model Fog::Aliyun::Storage::File
|
17
22
|
|
18
23
|
# check_directory_key have two functions:
|
19
24
|
# 1. trim the directory_key suffix '/'
|
@@ -21,6 +26,10 @@ module Fog
|
|
21
26
|
# If so, it will return directly to avoid to create a new redundant folder named with directory_key.
|
22
27
|
# This point will be applied to multi-bucket and make bucket as a directory scenario.
|
23
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
|
24
33
|
if directory_key != ''
|
25
34
|
# trim the suffix '/'
|
26
35
|
directory_key = directory_key.chomp('/')
|
@@ -29,25 +38,31 @@ module Fog
|
|
29
38
|
directory_key
|
30
39
|
else
|
31
40
|
data = service.get_bucket(directory_key)
|
32
|
-
puts "[DEBUG] Getting the bucket named with directory name #{directory_key}..."
|
33
41
|
if data.class == Hash && data.key?('Code') && !data['Code'].nil? && !data['Code'].empty?
|
34
|
-
puts "[INFO] The directory name #{directory_key} is not a bucket and will create one folder named with it."
|
35
42
|
directory_key
|
36
43
|
else
|
37
|
-
|
38
|
-
''
|
44
|
+
bucket_name = directory_key
|
45
|
+
directory_key = ''
|
39
46
|
end
|
40
47
|
end
|
41
|
-
else
|
42
|
-
''
|
43
48
|
end
|
49
|
+
return bucket_name, directory_key
|
44
50
|
end
|
45
51
|
|
46
|
-
def all(
|
52
|
+
def all(options = {})
|
47
53
|
requires :directory
|
48
|
-
directory_key = check_directory_key(directory.key)
|
49
|
-
|
50
|
-
|
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']
|
51
66
|
return if files.nil?
|
52
67
|
data = []
|
53
68
|
i = 0
|
@@ -88,117 +103,88 @@ module Fog
|
|
88
103
|
|
89
104
|
def get(key)
|
90
105
|
requires :directory
|
91
|
-
directory_key = check_directory_key(directory.key)
|
106
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
92
107
|
object = if directory_key == ''
|
93
108
|
key
|
94
109
|
else
|
95
110
|
directory_key + '/' + key
|
96
111
|
end
|
97
112
|
begin
|
98
|
-
data = service.get_object(object)
|
99
|
-
|
100
|
-
|
101
|
-
|
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}
|
102
137
|
nil
|
103
138
|
else
|
104
139
|
raise(error)
|
105
140
|
end
|
106
141
|
end
|
107
|
-
|
108
|
-
contentLen = data[:headers]['Content-Length'].to_i
|
109
|
-
|
110
|
-
if block_given?
|
111
|
-
pagesNum = (contentLen + Excon::CHUNK_SIZE - 1) / Excon::CHUNK_SIZE
|
112
|
-
|
113
|
-
for i in 1..pagesNum
|
114
|
-
_start = (i - 1) * Excon::CHUNK_SIZE
|
115
|
-
_end = i * Excon::CHUNK_SIZE - 1
|
116
|
-
range = "#{_start}-#{_end}"
|
117
|
-
begin
|
118
|
-
data = service.get_object(object, range)
|
119
|
-
chunk = data[:body]
|
120
|
-
rescue StandardError => error
|
121
|
-
case error.response.body
|
122
|
-
when %r{<Code>NoSuchKey</Code>},%r{<Code>SymlinkTargetNotExist</Code>}
|
123
|
-
chunk = ''
|
124
|
-
else
|
125
|
-
raise(error)
|
126
|
-
end
|
127
|
-
end
|
128
|
-
yield(chunk)
|
129
|
-
body = nil
|
130
|
-
end
|
131
|
-
else
|
132
|
-
body = data[:body]
|
133
|
-
end
|
134
|
-
|
135
|
-
lastModified = data[:headers]['Last-Modified']
|
136
|
-
last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
|
137
|
-
|
138
|
-
date = data[:headers]['Date']
|
139
|
-
date = (Time.parse(date).localtime if !date.nil? && date != '')
|
140
|
-
file_data = {
|
141
|
-
body: body,
|
142
|
-
content_length: contentLen,
|
143
|
-
key: key,
|
144
|
-
last_modified: last_modified,
|
145
|
-
content_type: data[:headers]['Content-Type'],
|
146
|
-
etag: data[:headers]['ETag'],
|
147
|
-
date: date,
|
148
|
-
connection: data[:headers]['Connection'],
|
149
|
-
accept_ranges: data[:headers]['Accept-Ranges'],
|
150
|
-
server: data[:headers]['Server'],
|
151
|
-
object_type: data[:headers]['x-oss-object-type'],
|
152
|
-
content_disposition: data[:headers]['Content-Disposition']
|
153
|
-
}
|
154
|
-
|
155
|
-
new(file_data)
|
156
142
|
end
|
157
143
|
|
158
144
|
def get_url(key)
|
159
145
|
requires :directory
|
160
|
-
directory_key = check_directory_key(directory.key)
|
146
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
161
147
|
object = if directory_key == ''
|
162
148
|
key
|
163
149
|
else
|
164
150
|
directory_key + '/' + key
|
165
151
|
end
|
166
|
-
service.get_object_http_url_public(object, 3600)
|
152
|
+
service.get_object_http_url_public(object, 3600, bucket: bucket_name)
|
167
153
|
end
|
168
154
|
|
169
155
|
def get_http_url(key, expires, options = {})
|
170
156
|
requires :directory
|
171
|
-
directory_key = check_directory_key(directory.key)
|
157
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
172
158
|
object = if directory_key == ''
|
173
159
|
key
|
174
160
|
else
|
175
161
|
directory_key + '/' + key
|
176
162
|
end
|
177
163
|
expires = expires.nil? ? 0 : expires.to_i
|
178
|
-
service.get_object_http_url_public(object, expires, options)
|
164
|
+
service.get_object_http_url_public(object, expires, options.merge(bucket: bucket_name))
|
179
165
|
end
|
180
166
|
|
181
167
|
def get_https_url(key, expires, options = {})
|
182
168
|
requires :directory
|
183
|
-
directory_key = check_directory_key(directory.key)
|
169
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
184
170
|
object = if directory_key == ''
|
185
171
|
key
|
186
172
|
else
|
187
173
|
directory_key + '/' + key
|
188
174
|
end
|
189
175
|
expires = expires.nil? ? 0 : expires.to_i
|
190
|
-
service.get_object_https_url_public(object, expires, options)
|
176
|
+
service.get_object_https_url_public(object, expires, options.merge(bucket: bucket_name))
|
191
177
|
end
|
192
178
|
|
193
179
|
def head(key, _options = {})
|
194
180
|
requires :directory
|
195
|
-
directory_key = check_directory_key(directory.key)
|
181
|
+
bucket_name, directory_key = check_directory_key(directory.key)
|
196
182
|
object = if directory_key == ''
|
197
183
|
key
|
198
184
|
else
|
199
185
|
directory_key + '/' + key
|
200
186
|
end
|
201
|
-
data = service.head_object(object).data
|
187
|
+
data = service.head_object(object, bucket: bucket_name).data
|
202
188
|
return nil if data[:status] == 404
|
203
189
|
lastModified = data[:headers]['Last-Modified']
|
204
190
|
last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
|
@@ -219,12 +205,19 @@ module Fog
|
|
219
205
|
object_type: data[:headers]['x-oss-object-type']
|
220
206
|
}
|
221
207
|
new(file_data)
|
222
|
-
rescue Fog::Storage::
|
208
|
+
rescue Fog::Aliyun::Storage::NotFound
|
223
209
|
nil
|
224
210
|
end
|
225
211
|
|
226
212
|
def new(attributes = {})
|
227
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
|
228
221
|
super({ directory: directory }.merge!(attributes))
|
229
222
|
end
|
230
223
|
end
|