fog-aliyun 0.3.7 → 0.3.12
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/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
|