fog-aliyun 0.3.9 → 0.3.15

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1282dc25fa74615eb50ae3d68e2e6a4525712cf12d7b2af1741a18b61b4842da
4
- data.tar.gz: 07b73a4fcfb1ad04d1bf16d5127153b554633afe7a91aa31a1675533680b1478
3
+ metadata.gz: 3d17874f631a07b500567d7b68ee75bccac8a68f4bb68e7a25e3be0a74dbfee9
4
+ data.tar.gz: 1824454812189f3b30898eab1f902203e77494f02866a1952d8f78a9e632b4ed
5
5
  SHA512:
6
- metadata.gz: 0bd08522fda123aa1a0fac945ca83bf09a16ac811594eafb8b3d36d2d4f354298dc8146dfe1c64608dc90a3d1fb55c9bc4c9a1ab647316d63048cda15d6ecb54
7
- data.tar.gz: 346b5a912c43de55a7ed3067d7fb1bfc3c8e7f216e512eb880aa9eb7c5f144bc32857e786e2346bef2034f7ee0125179497afcf88736e61da4159aec1f9dbf09
6
+ metadata.gz: 589b6e6590b1681ec8dc51d45cec1e631b17ecdf207625a703e677519362098b0b9101adfc4f79792d7eda9c694c4a90ed109c77c7d2af23c1fad2b1b3bb6d2f
7
+ data.tar.gz: cbe9f5b1d5cc0f0b99179fd9c7aae8dec67ad9d1f5effdc7b7e86131deadf4aad51a963b061bd7c92efb52cb1fb79479db7b494ad9d9735da8fa6915f3790f3d
data/.gitignore CHANGED
@@ -23,3 +23,5 @@ tmp
23
23
  *.a
24
24
  mkmf.log
25
25
  gemfiles/*.lock
26
+ morethan100m
27
+ *.log
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
- :aliyun_accesskey_id: <YOUR_ACCESS_KEY_ID>,
34
- :aliyun_accesskey_secret: <YOUR_SECRET_ACCESS_KEY>,
35
- :aliyun_region_id: <YOUR_TARGET_REGION>
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).
@@ -26,7 +26,11 @@ 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', '~> 0.7.2'
29
32
 
33
+ spec.add_dependency 'aliyun-sdk', '~> 0.7.2'
30
34
  spec.add_dependency 'fog-core'
31
35
  spec.add_dependency 'fog-json'
32
36
  spec.add_dependency 'ipaddress', '~> 0.8'
@@ -2,19 +2,16 @@
2
2
 
3
3
  require 'fog/core'
4
4
  require 'fog/json'
5
- require 'fog/aliyun/version'
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 Storage
8
- class Aliyun
7
+ module Aliyun
8
+ class Storage
9
9
  class Directories < Fog::Collection
10
- model Fog::Storage::Aliyun::Directory
10
+ model Fog::Aliyun::Storage::Directory
11
11
 
12
12
  def all
13
13
  containers = service.get_containers
@@ -72,7 +72,7 @@ module Fog
72
72
  else
73
73
  new(key: '')
74
74
  end
75
- rescue Fog::Storage::Aliyun::NotFound
75
+ rescue Fog::Aliyun::Storage::NotFound
76
76
  nil
77
77
  end
78
78
  end
@@ -4,8 +4,8 @@ require 'fog/core/model'
4
4
  require 'fog/aliyun/models/storage/files'
5
5
 
6
6
  module Fog
7
- module Storage
8
- class Aliyun
7
+ module Aliyun
8
+ class Storage
9
9
  class Directory < Fog::Model
10
10
  identity :key, :aliases => ['Key', 'Name', 'name']
11
11
 
@@ -20,14 +20,14 @@ module Fog
20
20
  service.delete_container(key)
21
21
  true
22
22
  else
23
- raise Fog::Storage::Aliyun::Error, ' Forbidden: Direction not empty!'
23
+ raise Fog::Aliyun::Storage::Error, ' Forbidden: Direction not empty!'
24
24
  false
25
25
  end
26
26
  end
27
27
 
28
28
  def files
29
29
  @files ||= begin
30
- Fog::Storage::Aliyun::Files.new(
30
+ Fog::Aliyun::Storage::Files.new(
31
31
  directory: self,
32
32
  service: service
33
33
  )
@@ -3,8 +3,8 @@
3
3
  require 'fog/core/model'
4
4
 
5
5
  module Fog
6
- module Storage
7
- class Aliyun
6
+ module Aliyun
7
+ class Storage
8
8
  class File < Fog::Model
9
9
  identity :key, aliases: ['Key', 'Name', 'name']
10
10
  attribute :date, aliases: 'Date'
@@ -124,7 +124,7 @@ module Fog
124
124
  elsif body.is_a?(String)
125
125
  data = service.put_object_with_body(object, body, options.merge(bucket: bucket_name)).data
126
126
  else
127
- raise Fog::Storage::Aliyun::Error, " Forbidden: Invalid body type: #{body.class}!"
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
@@ -2,10 +2,11 @@
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 Storage
8
- class Aliyun
8
+ module Aliyun
9
+ class Storage
9
10
  class Files < Fog::Collection
10
11
  attribute :directory
11
12
  attribute :limit
@@ -17,7 +18,7 @@ module Fog
17
18
  attribute :marker, :aliases => 'Marker'
18
19
  attribute :max_keys, :aliases => ['MaxKeys', 'max-keys']
19
20
 
20
- model Fog::Storage::Aliyun::File
21
+ model Fog::Aliyun::Storage::File
21
22
 
22
23
  # check_directory_key have two functions:
23
24
  # 1. trim the directory_key suffix '/'
@@ -48,12 +49,20 @@ module Fog
48
49
  return bucket_name, directory_key
49
50
  end
50
51
 
51
- def all(_options = {})
52
+ def all(options = {})
52
53
  requires :directory
53
54
  bucket_name, directory_key = check_directory_key(directory.key)
54
- prefix_value = prefix
55
+ remap_attributes(options, {
56
+ :delimiter => 'delimiter',
57
+ :marker => 'marker',
58
+ :max_keys => 'max-keys',
59
+ :prefix => 'prefix'
60
+ })
61
+ prefix_value = options['prefix']
55
62
  prefix_value = directory_key + '/' + prefix if directory_key != '' && directory_key != '.' && !directory_key.nil?
56
- files = service.list_objects(prefix: prefix_value, bucket: bucket_name)['Contents']
63
+ options['prefix'] = prefix_value
64
+ options['bucket'] = bucket_name
65
+ files = service.list_objects(options)['Contents']
57
66
  return if files.nil?
58
67
  data = []
59
68
  i = 0
@@ -102,63 +111,34 @@ module Fog
102
111
  end
103
112
  begin
104
113
  data = service.get_object(object, nil, bucket: bucket_name)
105
- rescue StandardError => error
106
- case error.response.body
107
- when %r{<Code>NoSuchKey</Code>},%r{<Code>SymlinkTargetNotExist</Code>}
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}
108
137
  nil
109
138
  else
110
139
  raise(error)
111
140
  end
112
141
  end
113
-
114
- contentLen = data[:headers]['Content-Length'].to_i
115
-
116
- if block_given?
117
- pagesNum = (contentLen + Excon::CHUNK_SIZE - 1) / Excon::CHUNK_SIZE
118
-
119
- for i in 1..pagesNum
120
- _start = (i - 1) * Excon::CHUNK_SIZE
121
- _end = i * Excon::CHUNK_SIZE - 1
122
- range = "#{_start}-#{_end}"
123
- begin
124
- data = service.get_object(object, range, bucket: bucket_name)
125
- chunk = data[:body]
126
- rescue StandardError => error
127
- case error.response.body
128
- when %r{<Code>NoSuchKey</Code>},%r{<Code>SymlinkTargetNotExist</Code>}
129
- chunk = ''
130
- else
131
- raise(error)
132
- end
133
- end
134
- yield(chunk)
135
- body = nil
136
- end
137
- else
138
- body = data[:body]
139
- end
140
-
141
- lastModified = data[:headers]['Last-Modified']
142
- last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
143
-
144
- date = data[:headers]['Date']
145
- date = (Time.parse(date).localtime if !date.nil? && date != '')
146
- file_data = {
147
- body: body,
148
- content_length: contentLen,
149
- key: key,
150
- last_modified: last_modified,
151
- content_type: data[:headers]['Content-Type'],
152
- etag: data[:headers]['ETag'],
153
- date: date,
154
- connection: data[:headers]['Connection'],
155
- accept_ranges: data[:headers]['Accept-Ranges'],
156
- server: data[:headers]['Server'],
157
- object_type: data[:headers]['x-oss-object-type'],
158
- content_disposition: data[:headers]['Content-Disposition']
159
- }
160
-
161
- new(file_data)
162
142
  end
163
143
 
164
144
  def get_url(key)
@@ -225,7 +205,7 @@ module Fog
225
205
  object_type: data[:headers]['x-oss-object-type']
226
206
  }
227
207
  new(file_data)
228
- rescue Fog::Storage::Aliyun::NotFound
208
+ rescue Fog::Aliyun::Storage::NotFound
229
209
  nil
230
210
  end
231
211
 
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Copy object
8
8
  #
@@ -19,8 +19,6 @@ module Fog
19
19
  source_bucket ||= bucket
20
20
  target_bucket ||= bucket
21
21
  headers = { 'x-oss-copy-source' => "/#{source_bucket}/#{source_object}" }
22
- location = get_bucket_location(target_bucket)
23
- endpoint = 'http://' + location + '.aliyuncs.com'
24
22
  resource = target_bucket + '/' + target_object
25
23
  request(expects: [200, 203],
26
24
  headers: headers,
@@ -28,7 +26,7 @@ module Fog
28
26
  path: target_object,
29
27
  bucket: target_bucket,
30
28
  resource: resource,
31
- endpoint: endpoint)
29
+ location: get_bucket_location(bucket))
32
30
  end
33
31
  end
34
32
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Delete an existing bucket
8
8
  #
@@ -10,15 +10,13 @@ module Fog
10
10
  # * bucket<~String> - Name of bucket to delete
11
11
  #
12
12
  def delete_bucket(bucket)
13
- location = get_bucket_location(bucket)
14
- endpoint = 'http://' + location + '.aliyuncs.com'
15
13
  resource = bucket + '/'
16
14
  request(
17
15
  expects: 204,
18
16
  method: 'DELETE',
19
17
  bucket: bucket,
20
18
  resource: resource,
21
- endpoint: endpoint
19
+ location: get_bucket_location(bucket)
22
20
  )
23
21
  end
24
22
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Delete an existing container
8
8
  #
@@ -13,8 +13,6 @@ module Fog
13
13
  def delete_container(container, options = {})
14
14
  bucket = options[:bucket]
15
15
  bucket ||= @aliyun_oss_bucket
16
- location = get_bucket_location(bucket)
17
- endpoint = 'http://' + location + '.aliyuncs.com'
18
16
  object = container + '/'
19
17
  resource = bucket + '/' + object
20
18
 
@@ -24,7 +22,7 @@ module Fog
24
22
  path: object,
25
23
  bucket: bucket,
26
24
  resource: resource,
27
- endpoint: endpoint
25
+ location: get_bucket_location(bucket)
28
26
  )
29
27
  end
30
28
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Delete an existing object
8
8
  #
@@ -10,37 +10,15 @@ module Fog
10
10
  # * object<~String> - Name of object to delete
11
11
  #
12
12
  def delete_object(object, options = {})
13
- bucket = options[:bucket]
14
- bucket ||= @aliyun_oss_bucket
15
- location = get_bucket_location(bucket)
16
- endpoint = 'http://' + location + '.aliyuncs.com'
17
- resource = bucket + '/' + object
18
- request(
19
- expects: 204,
20
- method: 'DELETE',
21
- path: object,
22
- bucket: bucket,
23
- resource: resource,
24
- endpoint: endpoint
25
- )
13
+ bucket_name = options[:bucket]
14
+ bucket_name ||= @aliyun_oss_bucket
15
+ bucket = @oss_client.get_bucket(bucket_name)
16
+ bucket.delete_object(object)
26
17
  end
27
18
 
28
- def abort_multipart_upload(bucket, object, endpoint, uploadid)
29
- if endpoint.nil?
30
- location = get_bucket_location(bucket)
31
- endpoint = 'http://' + location + '.aliyuncs.com'
32
- end
33
- path = object + '?uploadId=' + uploadid
34
- resource = bucket + '/' + path
35
-
36
- ret = request(
37
- expects: 204,
38
- method: 'DELETE',
39
- path: path,
40
- bucket: bucket,
41
- resource: resource,
42
- endpoint: endpoint
43
- )
19
+ def abort_multipart_upload(bucket_name, object, upload_id)
20
+ bucket = @oss_client.get_bucket(bucket_name)
21
+ bucket.abort_upload(upload_id, object)
44
22
  end
45
23
  end
46
24
  end
@@ -1,24 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  def get_bucket(bucket, options = {})
8
- location = get_bucket_location(bucket)
9
- # If there is an error, it will return a Hash with error code, host id and others
10
- # If can not get a valid location, will return one using region
11
- if location.class == Hash && location.key?('HostId')
12
- value = location['HostId']
13
- location = value[0].split('.')[1]
14
- else
15
- location = 'oss-' + @aliyun_region_id
16
- end
17
- endpoint = 'http://' + location + '.aliyuncs.com'
18
-
19
8
  prefix = options['prefix']
20
9
  marker = options['marker']
21
- maxKeys = options['max_keys']
10
+ # Set the GetBucket max limitation to 1000
11
+ maxKeys = options['max-keys'] || 1000
12
+ maxKeys = [maxKeys, 1000].min
22
13
  delimiter = options['delimiter']
23
14
  path = ''
24
15
  if prefix
@@ -45,7 +36,7 @@ module Fog
45
36
  method: 'GET',
46
37
  bucket: bucket,
47
38
  resource: resource,
48
- endpoint: endpoint,
39
+ location: get_bucket_location(bucket),
49
40
  path: path
50
41
  )
51
42
  xml = ret.data[:body]
@@ -62,12 +53,17 @@ module Fog
62
53
  bucket: bucket,
63
54
  resource: resource
64
55
  )
65
- XmlSimple.xml_in(ret.data[:body])
56
+ # If there is an error, it will return a Hash with error code, host id and others
57
+ # If can not get a valid location, will return one using region
58
+ location = XmlSimple.xml_in(ret.data[:body])
59
+ if location.class == Hash && location.key?('HostId')
60
+ value = location['HostId']
61
+ location = value[0].split('.')[1]
62
+ end
63
+ location ||= 'oss-' + @aliyun_region_id
66
64
  end
67
65
 
68
66
  def get_bucket_acl(bucket)
69
- location = get_bucket_location(bucket)
70
- endpoint = 'http://' + location + '.aliyuncs.com'
71
67
  attribute = '?acl'
72
68
  resource = bucket + '/' + attribute
73
69
  ret = request(
@@ -76,14 +72,12 @@ module Fog
76
72
  path: attribute,
77
73
  bucket: bucket,
78
74
  resource: resource,
79
- endpoint: endpoint
75
+ location: get_bucket_location(bucket)
80
76
  )
81
77
  XmlSimple.xml_in(ret.data[:body])['AccessControlList'][0]['Grant'][0]
82
78
  end
83
79
 
84
80
  def get_bucket_CORSRules(bucket)
85
- location = get_bucket_location(bucket)
86
- endpoint = 'http://' + location + '.aliyuncs.com'
87
81
  attribute = '?cors'
88
82
  resource = bucket + '/' + attribute
89
83
  ret = request(
@@ -92,14 +86,12 @@ module Fog
92
86
  path: attribute,
93
87
  bucket: bucket,
94
88
  resource: resource,
95
- endpoint: endpoint
89
+ location: get_bucket_location(bucket)
96
90
  )
97
91
  XmlSimple.xml_in(ret.data[:body])['CORSRule'][0] if ret.data[:status] != 404
98
92
  end
99
93
 
100
94
  def get_bucket_lifecycle(bucket)
101
- location = get_bucket_location(bucket)
102
- endpoint = 'http://' + location + '.aliyuncs.com'
103
95
  attribute = '?lifecycle'
104
96
  resource = bucket + '/' + attribute
105
97
  ret = request(
@@ -108,14 +100,12 @@ module Fog
108
100
  path: attribute,
109
101
  bucket: bucket,
110
102
  resource: resource,
111
- endpoint: endpoint
103
+ location: get_bucket_location(bucket)
112
104
  )
113
105
  XmlSimple.xml_in(ret.data[:body])['Rule'][0] if ret.data[:status] != 404
114
106
  end
115
107
 
116
108
  def get_bucket_logging(bucket)
117
- location = get_bucket_location(bucket)
118
- endpoint = 'http://' + location + '.aliyuncs.com'
119
109
  attribute = '?logging'
120
110
  resource = bucket + '/' + attribute
121
111
  ret = request(
@@ -124,14 +114,12 @@ module Fog
124
114
  path: attribute,
125
115
  bucket: bucket,
126
116
  resource: resource,
127
- endpoint: endpoint
117
+ location: get_bucket_location(bucket)
128
118
  )
129
119
  XmlSimple.xml_in(ret.data[:body])['LoggingEnabled'][0]['TargetPrefix']
130
120
  end
131
121
 
132
122
  def get_bucket_referer(bucket)
133
- location = get_bucket_location(bucket)
134
- endpoint = 'http://' + location + '.aliyuncs.com'
135
123
  attribute = '?referer'
136
124
  resource = bucket + '/' + attribute
137
125
  ret = request(
@@ -140,14 +128,12 @@ module Fog
140
128
  path: attribute,
141
129
  bucket: bucket,
142
130
  resource: resource,
143
- endpoint: endpoint
131
+ location: get_bucket_location(bucket)
144
132
  )
145
133
  XmlSimple.xml_in(ret.data[:body])
146
134
  end
147
135
 
148
136
  def get_bucket_website(bucket)
149
- location = get_bucket_location(bucket)
150
- endpoint = 'http://' + location + '.aliyuncs.com'
151
137
  attribute = '?website'
152
138
  resource = bucket + '/' + attribute
153
139
  ret = request(
@@ -156,7 +142,7 @@ module Fog
156
142
  path: attribute,
157
143
  bucket: bucket,
158
144
  resource: resource,
159
- endpoint: endpoint
145
+ location: get_bucket_location(bucket)
160
146
  )
161
147
  XmlSimple.xml_in(ret.data[:body]) if ret.data[:status] != 404
162
148
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  def get_container(container, options = {})
8
8
  options = options.reject { |_key, value| value.nil? }
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # List existing storage containers
8
8
  #
@@ -42,13 +42,18 @@ module Fog
42
42
  path += '?delimiter=' + delimiter
43
43
  end
44
44
 
45
- location = get_bucket_location(bucket)
45
+ endpoint = options[:endpoint]
46
+ if endpoint.nil?
47
+ location = get_bucket_location(bucket)
48
+ end
46
49
  resource = bucket + '/'
47
50
  ret = request(
48
51
  expects: [200, 203, 400],
49
52
  method: 'GET',
50
53
  path: path,
51
54
  resource: resource,
55
+ endpoint: endpoint,
56
+ location: location,
52
57
  bucket: bucket
53
58
  )
54
59
  xml = ret.data[:body]
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Get details for object
8
8
  #
@@ -11,30 +11,17 @@ module Fog
11
11
  #
12
12
  def get_object(object, range = nil, options = {})
13
13
  options = options.reject { |_key, value| value.nil? }
14
- bucket = options[:bucket]
15
- bucket ||= @aliyun_oss_bucket
16
- endpoint = options[:endpoint]
17
- if endpoint.nil?
18
- location = get_bucket_location(bucket)
19
- endpoint = 'http://' + location + '.aliyuncs.com'
14
+ bucket_name = options[:bucket]
15
+ bucket_name ||= @aliyun_oss_bucket
16
+ # Using OSS ruby SDK to fix performance issue
17
+ bucket = @oss_client.get_bucket(bucket_name)
18
+ body = Array.new
19
+ obj = bucket.get_object(object) do |chunk|
20
+ body << chunk
20
21
  end
21
- resource = bucket + '/' + object
22
- para = {
23
- expects: [200, 206, 404],
24
- method: 'GET',
25
- path: object,
26
- bucket: bucket,
27
- resource: resource,
28
- endpoint: endpoint
29
- }
30
-
31
- if range
32
- rangeStr = 'bytes=' + range
33
- para[:headers] = { 'Range' => rangeStr }
34
- end
35
-
36
- response = request(para)
37
- response.data
22
+ response = {}
23
+ obj.instance_variables.each {|var| response[var.to_s.delete("@")] = obj.instance_variable_get(var) }
24
+ response.merge({:body => body.join('')})
38
25
  end
39
26
  end
40
27
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Get an expiring object http url
8
8
  #
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Get an expiring object https url from Cloud Files
8
8
  #
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Get headers for object
8
8
  #
@@ -12,8 +12,6 @@ module Fog
12
12
  def head_object(object, options = {})
13
13
  bucket = options[:bucket]
14
14
  bucket ||= @aliyun_oss_bucket
15
- location = get_bucket_location(bucket)
16
- endpoint = 'http://' + location + '.aliyuncs.com'
17
15
  resource = bucket + '/' + object
18
16
  ret = request(
19
17
  expects: [200, 404],
@@ -21,7 +19,7 @@ module Fog
21
19
  path: object,
22
20
  bucket: bucket,
23
21
  resource: resource,
24
- endpoint: endpoint
22
+ location: get_bucket_location(bucket)
25
23
  )
26
24
  ret
27
25
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  def list_buckets(options = {})
8
8
  prefix = options[:prefix]
@@ -1,16 +1,18 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  def list_objects(options = {})
8
- bucket = options[:bucket]
8
+ bucket = options['bucket']
9
9
  bucket ||= @aliyun_oss_bucket
10
- prefix = options[:prefix]
11
- marker = options[:marker]
12
- maxKeys = options[:maxKeys]
13
- delimiter = options[:delimiter]
10
+ prefix = options['prefix']
11
+ marker = options['marker']
12
+ # Set the ListObjects max limitation to 1000
13
+ maxKeys = options['max-keys'] || 1000
14
+ maxKeys = [maxKeys, 1000].min
15
+ delimiter = options['delimiter']
14
16
 
15
17
  path = ''
16
18
  if prefix
@@ -43,11 +45,9 @@ module Fog
43
45
  XmlSimple.xml_in(xml)
44
46
  end
45
47
 
46
- def list_multipart_uploads(bucket, endpoint, _options = {})
47
- if endpoint.nil?
48
- location = get_bucket_location(bucket)
49
- endpoint = 'http://' + location + '.aliyuncs.com'
50
- end
48
+ def list_multipart_uploads(bucket, location, _options = {})
49
+ location ||= get_bucket_location(bucket)
50
+
51
51
  path = '?uploads'
52
52
  resource = bucket + '/' + path
53
53
 
@@ -57,16 +57,14 @@ module Fog
57
57
  path: path,
58
58
  bucket: bucket,
59
59
  resource: resource,
60
- endpoint: endpoint
60
+ location: location
61
61
  )
62
62
  XmlSimple.xml_in(ret.data[:body])['Upload']
63
63
  end
64
64
 
65
- def list_parts(bucket, object, endpoint, uploadid, _options = {})
66
- if endpoint.nil?
67
- location = get_bucket_location(bucket)
68
- endpoint = 'http://' + location + '.aliyuncs.com'
69
- end
65
+ def list_parts(bucket, object, location, uploadid, _options = {})
66
+ location ||= get_bucket_location(bucket)
67
+
70
68
  path = object + '?uploadId=' + uploadid
71
69
  resource = bucket + '/' + path
72
70
 
@@ -76,7 +74,7 @@ module Fog
76
74
  path: path,
77
75
  bucket: bucket,
78
76
  resource: resource,
79
- endpoint: endpoint
77
+ location: location
80
78
  )
81
79
  XmlSimple.xml_in(ret.data[:body])['Part']
82
80
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  def put_bucket(bucketName)
8
8
  resource = bucketName + '/'
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Create a new container
8
8
  #
@@ -12,8 +12,6 @@ module Fog
12
12
  def put_container(name, options = {})
13
13
  bucket = options[:bucket]
14
14
  bucket ||= @aliyun_oss_bucket
15
- location = get_bucket_location(bucket)
16
- endpoint = 'http://' + location + '.aliyuncs.com'
17
15
 
18
16
  path = name + '/'
19
17
  resource = bucket + '/' + name + '/'
@@ -23,7 +21,7 @@ module Fog
23
21
  path: path,
24
22
  bucket: bucket,
25
23
  resource: resource,
26
- endpoint: endpoint
24
+ location: get_bucket_location(bucket)
27
25
  )
28
26
  end
29
27
  end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Fog
4
- module Storage
5
- class Aliyun
4
+ module Aliyun
5
+ class Storage
6
6
  class Real
7
7
  # Put details for object
8
8
  #
@@ -12,9 +12,7 @@ module Fog
12
12
  def put_object(object, file = nil, options = {})
13
13
  bucket = options[:bucket]
14
14
  bucket ||= @aliyun_oss_bucket
15
- location = get_bucket_location(bucket)
16
- endpoint = 'http://' + location + '.aliyuncs.com'
17
- return put_folder(bucket, object, endpoint) if file.nil?
15
+ return put_folder(bucket, object) if file.nil?
18
16
 
19
17
  # put multiparts if object's size is over 100m
20
18
  return put_multipart_object(bucket, object, file) if file.size > 104_857_600
@@ -29,15 +27,13 @@ module Fog
29
27
  bucket: bucket,
30
28
  resource: resource,
31
29
  body: body,
32
- endpoint: endpoint
30
+ location: get_bucket_location(bucket)
33
31
  )
34
32
  end
35
33
 
36
34
  def put_object_with_body(object, body, options = {})
37
35
  bucket = options[:bucket]
38
36
  bucket ||= @aliyun_oss_bucket
39
- location = get_bucket_location(bucket)
40
- endpoint = 'http://' + location + '.aliyuncs.com'
41
37
 
42
38
  resource = bucket + '/' + object
43
39
  request(
@@ -47,15 +43,11 @@ module Fog
47
43
  bucket: bucket,
48
44
  resource: resource,
49
45
  body: body,
50
- endpoint: endpoint
46
+ location: get_bucket_location(bucket)
51
47
  )
52
48
  end
53
49
 
54
- def put_folder(bucket, folder, endpoint)
55
- if endpoint.nil?
56
- location = get_bucket_location(bucket)
57
- endpoint = 'http://' + location + '.aliyuncs.com'
58
- end
50
+ def put_folder(bucket, folder)
59
51
  path = folder + '/'
60
52
  resource = bucket + '/' + folder + '/'
61
53
  request(
@@ -64,27 +56,26 @@ module Fog
64
56
  path: path,
65
57
  bucket: bucket,
66
58
  resource: resource,
67
- endpoint: endpoint
59
+ location: get_bucket_location(bucket)
68
60
  )
69
61
  end
70
62
 
71
63
  def put_multipart_object(bucket, object, file)
72
64
  location = get_bucket_location(bucket)
73
- endpoint = 'http://' + location + '.aliyuncs.com'
74
65
 
75
66
  # find the right uploadid
76
- uploads = list_multipart_uploads(bucket, endpoint)
67
+ uploads = list_multipart_uploads(bucket, location)
77
68
  upload = (uploads&.find { |tmpupload| tmpupload['Key'][0] == object })
78
69
 
79
70
  uploadedSize = 0
80
71
  start_partNumber = 1
81
72
  if !upload.nil?
82
73
  uploadId = upload['UploadId'][0]
83
- parts = list_parts(bucket, object, endpoint, uploadId)
74
+ parts = list_parts(bucket, object, location, uploadId)
84
75
  if !parts.nil? && !parts.empty?
85
76
  if parts[-1]['Size'][0].to_i != 5_242_880
86
77
  # the part is the last one, if its size is over 5m, then finish this upload
87
- complete_multipart_upload(bucket, object, endpoint, uploadId)
78
+ complete_multipart_upload(bucket, object, location, uploadId)
88
79
  return
89
80
  end
90
81
  uploadedSize = (parts[0]['Size'][0].to_i * (parts.size - 1)) + parts[-1]['Size'][0].to_i
@@ -92,11 +83,11 @@ module Fog
92
83
  end
93
84
  else
94
85
  # create upload ID
95
- uploadId = initiate_multipart_upload(bucket, object, endpoint)
86
+ uploadId = initiate_multipart_upload(bucket, object, location)
96
87
  end
97
88
 
98
89
  if file.size <= uploadedSize
99
- complete_multipart_upload(bucket, object, endpoint, uploadId)
90
+ complete_multipart_upload(bucket, object, location, uploadId)
100
91
  return
101
92
  end
102
93
 
@@ -105,17 +96,14 @@ module Fog
105
96
 
106
97
  for i in start_partNumber..end_partNumber
107
98
  body = file.read(5_242_880)
108
- upload_part(bucket, object, endpoint, i.to_s, uploadId, body)
99
+ upload_part(bucket, object, location, i.to_s, uploadId, body)
109
100
  end
110
101
 
111
- complete_multipart_upload(bucket, object, endpoint, uploadId)
102
+ complete_multipart_upload(bucket, object, location, uploadId)
112
103
  end
113
104
 
114
- def initiate_multipart_upload(bucket, object, endpoint)
115
- if endpoint.nil?
116
- location = get_bucket_location(bucket)
117
- endpoint = 'http://' + location + '.aliyuncs.com'
118
- end
105
+ def initiate_multipart_upload(bucket, object, location)
106
+ location ||= get_bucket_location(bucket)
119
107
  path = object + '?uploads'
120
108
  resource = bucket + '/' + path
121
109
  ret = request(
@@ -124,16 +112,13 @@ module Fog
124
112
  path: path,
125
113
  bucket: bucket,
126
114
  resource: resource,
127
- endpoint: endpoint
115
+ location: location
128
116
  )
129
117
  XmlSimple.xml_in(ret.data[:body])['UploadId'][0]
130
118
  end
131
119
 
132
- def upload_part(bucket, object, endpoint, partNumber, uploadId, body)
133
- if endpoint.nil?
134
- location = get_bucket_location(bucket)
135
- endpoint = 'http://' + location + '.aliyuncs.com'
136
- end
120
+ def upload_part(bucket, object, location, partNumber, uploadId, body)
121
+ location ||= get_bucket_location(bucket)
137
122
  path = object + '?partNumber=' + partNumber + '&uploadId=' + uploadId
138
123
  resource = bucket + '/' + path
139
124
  request(
@@ -143,16 +128,13 @@ module Fog
143
128
  bucket: bucket,
144
129
  resource: resource,
145
130
  body: body,
146
- endpoint: endpoint
131
+ location: location
147
132
  )
148
133
  end
149
134
 
150
- def complete_multipart_upload(bucket, object, endpoint, uploadId)
151
- if endpoint.nil?
152
- location = get_bucket_location(bucket)
153
- endpoint = 'http://' + location + '.aliyuncs.com'
154
- end
155
- parts = list_parts(bucket, object, endpoint, uploadId, options = {})
135
+ def complete_multipart_upload(bucket, object, location, uploadId)
136
+ location ||= get_bucket_location(bucket)
137
+ parts = list_parts(bucket, object, location, uploadId, options = {})
156
138
  request_part = []
157
139
  return if parts.empty?
158
140
  for i in 0..(parts.size - 1)
@@ -169,7 +151,7 @@ module Fog
169
151
  path: path,
170
152
  bucket: bucket,
171
153
  resource: resource,
172
- endpoint: endpoint,
154
+ location: location,
173
155
  body: body
174
156
  )
175
157
  end
@@ -1,13 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'xmlsimple'
4
+ require 'aliyun/oss'
5
+
6
+ # Using Aliyun OSS Ruby SDK
7
+ AliyunOssSdk= Aliyun::OSS
4
8
 
5
9
  module Fog
6
- module Storage
7
- class Aliyun < Fog::Service
10
+ module Aliyun
11
+ class Storage < Fog::Service
8
12
  DEFAULT_REGION = 'cn-hangzhou'
9
13
 
10
- DEFAULT_SCHEME = 'http'
14
+ DEFAULT_SCHEME = 'https'
11
15
  DEFAULT_SCHEME_PORT = {
12
16
  'http' => 80,
13
17
  'https' => 443
@@ -97,6 +101,11 @@ module Fog
97
101
  @port = uri.port || DEFAULT_SCHEME_PORT[@scheme]
98
102
 
99
103
  @persistent = options[:persistent] || false
104
+ @oss_client = AliyunOssSdk::Client.new(
105
+ :endpoint => @aliyun_oss_endpoint,
106
+ :access_key_id => @aliyun_accesskey_id,
107
+ :access_key_secret => @aliyun_accesskey_secret
108
+ )
100
109
  end
101
110
 
102
111
  def reload
@@ -118,19 +127,22 @@ module Fog
118
127
  date = time.strftime('%a, %d %b %Y %H:%M:%S GMT')
119
128
 
120
129
  endpoint = params[:endpoint]
130
+ location = params[:location]
121
131
  if endpoint
122
132
  uri = URI.parse(endpoint)
123
133
  host = uri.host
124
134
  path = uri.path
125
135
  port = uri.port
126
136
  scheme = uri.scheme
127
- else
128
- host = @host
129
- path = @path
130
- port = @port
131
- scheme = @scheme
137
+ elsif location
138
+ host = location + '.aliyuncs.com'
132
139
  end
133
140
 
141
+ host ||= @host
142
+ path ||= @path
143
+ port ||= @port
144
+ scheme ||= @scheme
145
+
134
146
  bucket = params[:bucket]
135
147
  tmpHost = if bucket
136
148
  bucket + '.' + host
@@ -143,8 +155,10 @@ module Fog
143
155
 
144
156
  begin
145
157
  headers = ''
146
- params[:headers]&.each do |k, v|
158
+ if params[:headers]
159
+ params[:headers].each do |k, v|
147
160
  headers += "#{k}:#{v}\n" if k != 'Range'
161
+ end
148
162
  end
149
163
  signature = sign(method, date, contentType, params[:resource], headers)
150
164
  response = @connection.request(params.merge(headers: {
@@ -157,7 +171,7 @@ module Fog
157
171
  rescue Excon::Errors::HTTPStatusError => error
158
172
  raise case error
159
173
  when Excon::Errors::NotFound
160
- Fog::Storage::Aliyun::NotFound.slurp(error)
174
+ Fog::Aliyun::Storage::NotFound.slurp(error)
161
175
  else
162
176
  error
163
177
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Fog
4
4
  module Aliyun
5
- VERSION = '0.3.9'
5
+ VERSION = '0.3.15'
6
6
  end
7
7
  end
@@ -5,7 +5,7 @@ class Aliyun < Fog::Bin
5
5
  def class_for(key)
6
6
  case key
7
7
  when :storage
8
- Fog::Storage::Aliyun
8
+ Fog::Aliyun::Storage
9
9
  when :compute
10
10
  Fog::Compute::Aliyun
11
11
  else
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fog-aliyun
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.9
4
+ version: 0.3.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Qinsi Deng, Jianxun Li, Jane Han, Guimin He
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-07 00:00:00.000000000 Z
11
+ date: 2020-06-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -100,6 +100,62 @@ dependencies:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: simplecov
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: memory_profiler
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ - !ruby/object:Gem::Dependency
132
+ name: aliyun-sdk
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 0.7.2
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - "~>"
143
+ - !ruby/object:Gem::Version
144
+ version: 0.7.2
145
+ - !ruby/object:Gem::Dependency
146
+ name: aliyun-sdk
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - "~>"
150
+ - !ruby/object:Gem::Version
151
+ version: 0.7.2
152
+ type: :runtime
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: 0.7.2
103
159
  - !ruby/object:Gem::Dependency
104
160
  name: fog-core
105
161
  requirement: !ruby/object:Gem::Requirement