fog-aliyun 0.3.17 → 0.4.0

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/CHANGELOG.md +35 -2
  4. data/fog-aliyun.gemspec +4 -3
  5. data/lib/fog/aliyun/compute.rb +7 -5
  6. data/lib/fog/aliyun/models/storage/directories.rb +30 -53
  7. data/lib/fog/aliyun/models/storage/directory.rb +96 -17
  8. data/lib/fog/aliyun/models/storage/file.rb +127 -126
  9. data/lib/fog/aliyun/models/storage/files.rb +43 -124
  10. data/lib/fog/aliyun/requests/compute/attach_disk.rb +3 -1
  11. data/lib/fog/aliyun/requests/compute/create_security_group_egress_ip_rule.rb +4 -2
  12. data/lib/fog/aliyun/requests/compute/create_security_group_egress_sg_rule.rb +3 -1
  13. data/lib/fog/aliyun/requests/compute/create_security_group_ip_rule.rb +4 -2
  14. data/lib/fog/aliyun/requests/compute/create_security_group_sg_rule.rb +3 -1
  15. data/lib/fog/aliyun/requests/compute/create_vpc.rb +3 -1
  16. data/lib/fog/aliyun/requests/compute/create_vswitch.rb +3 -1
  17. data/lib/fog/aliyun/requests/compute/delete_security_group_egress_ip_rule.rb +4 -2
  18. data/lib/fog/aliyun/requests/compute/delete_security_group_egress_sg_rule.rb +3 -1
  19. data/lib/fog/aliyun/requests/compute/delete_security_group_ip_rule.rb +4 -2
  20. data/lib/fog/aliyun/requests/compute/delete_security_group_sg_rule.rb +3 -1
  21. data/lib/fog/aliyun/requests/compute/detach_disk.rb +3 -1
  22. data/lib/fog/aliyun/requests/compute/modify_vpc.rb +3 -1
  23. data/lib/fog/aliyun/requests/compute/modify_vswitch.rb +3 -1
  24. data/lib/fog/aliyun/requests/storage/abort_multipart_upload.rb +22 -0
  25. data/lib/fog/aliyun/requests/storage/complete_multipart_upload.rb +21 -0
  26. data/lib/fog/aliyun/requests/storage/copy_object.rb +14 -18
  27. data/lib/fog/aliyun/requests/storage/delete_bucket.rb +3 -9
  28. data/lib/fog/aliyun/requests/storage/delete_multiple_objects.rb +20 -0
  29. data/lib/fog/aliyun/requests/storage/delete_object.rb +10 -11
  30. data/lib/fog/aliyun/requests/storage/get_bucket.rb +22 -99
  31. data/lib/fog/aliyun/requests/storage/get_bucket_location.rb +33 -0
  32. data/lib/fog/aliyun/requests/storage/get_object.rb +20 -12
  33. data/lib/fog/aliyun/requests/storage/get_object_acl.rb +30 -0
  34. data/lib/fog/aliyun/requests/storage/get_object_http_url.rb +9 -10
  35. data/lib/fog/aliyun/requests/storage/get_object_https_url.rb +9 -10
  36. data/lib/fog/aliyun/requests/storage/get_service.rb +13 -0
  37. data/lib/fog/aliyun/requests/storage/head_object.rb +25 -13
  38. data/lib/fog/aliyun/requests/storage/initiate_multipart_upload.rb +19 -0
  39. data/lib/fog/aliyun/requests/storage/list_buckets.rb +5 -25
  40. data/lib/fog/aliyun/requests/storage/list_objects.rb +10 -62
  41. data/lib/fog/aliyun/requests/storage/put_bucket.rb +2 -8
  42. data/lib/fog/aliyun/requests/storage/put_object.rb +16 -122
  43. data/lib/fog/aliyun/requests/storage/upload_part.rb +24 -0
  44. data/lib/fog/aliyun/storage.rb +20 -4
  45. data/lib/fog/aliyun/version.rb +1 -1
  46. metadata +31 -19
  47. data/lib/fog/aliyun/requests/storage/delete_container.rb +0 -30
  48. data/lib/fog/aliyun/requests/storage/get_container.rb +0 -57
  49. data/lib/fog/aliyun/requests/storage/get_containers.rb +0 -61
  50. data/lib/fog/aliyun/requests/storage/put_container.rb +0 -29
@@ -7,77 +7,123 @@ module Fog
7
7
  class Storage
8
8
  class File < Fog::Model
9
9
  identity :key, aliases: ['Key', 'Name', 'name']
10
+
11
+ attr_writer :body
12
+ attribute :cache_control, aliases: 'Cache-Control'
13
+ attribute :content_encoding, aliases: 'Content-Encoding'
10
14
  attribute :date, aliases: 'Date'
11
- attribute :content_length, aliases: 'Content-Length', type: :integer
15
+ attribute :content_length, aliases: ['Content-Length', 'Size'], type: :integer
16
+ attribute :content_md5, aliases: 'Content-MD5'
12
17
  attribute :content_type, aliases: 'Content-Type'
13
18
  attribute :connection, aliases: 'Connection'
14
19
  attribute :content_disposition, aliases: 'Content-Disposition'
15
- attribute :etag, aliases: 'Etag'
20
+ attribute :etag, aliases: ['Etag', 'ETag']
21
+ attribute :expires, aliases: 'Expires'
22
+ attribute :metadata
23
+ attribute :owner, aliases: 'Owner'
16
24
  attribute :last_modified, aliases: 'Last-Modified', type: :time
17
25
  attribute :accept_ranges, aliases: 'Accept-Ranges'
18
26
  attribute :server, aliases: 'Server'
19
- attribute :object_type, aliases: 'x-oss-object-type'
27
+ attribute :object_type, aliases: ['x-oss-object-type', 'x_oss_object_type']
28
+
29
+ # @note Chunk size to use for multipart uploads.
30
+ # Use small chunk sizes to minimize memory. E.g. 5242880 = 5mb
31
+ attr_reader :multipart_chunk_size
32
+ def multipart_chunk_size=(mp_chunk_size)
33
+ raise ArgumentError.new("minimum multipart_chunk_size is 5242880") if mp_chunk_size < 5242880
34
+ @multipart_chunk_size = mp_chunk_size
35
+ end
36
+
37
+ def acl
38
+ requires :directory, :key
39
+ service.get_object_acl(directory.key, key)
40
+ end
41
+
42
+ def acl=(new_acl)
43
+ valid_acls = ['private', 'public-read', 'public-read-write', 'default']
44
+ unless valid_acls.include?(new_acl)
45
+ raise ArgumentError.new("acl must be one of [#{valid_acls.join(', ')}]")
46
+ end
47
+ @acl = new_acl
48
+ end
20
49
 
21
50
  def body
22
- attributes[:body] ||=
23
- if last_modified
24
- collection.get(identity).body
25
- else
26
- ''
27
- end
51
+ return attributes[:body] if attributes[:body]
52
+ return '' unless last_modified
53
+
54
+ file = collection.get(identity)
55
+ if file
56
+ attributes[:body] = file.body
57
+ else
58
+ attributes[:body] = ''
59
+ end
28
60
  end
29
61
 
30
62
  def body=(new_body)
31
63
  attributes[:body] = new_body
32
64
  end
33
65
 
34
- attr_reader :directory
66
+ def directory
67
+ @directory
68
+ end
35
69
 
70
+ # Copy object from one bucket to other bucket.
71
+ #
72
+ # required attributes: directory, key
73
+ #
74
+ # @param target_directory_key [String]
75
+ # @param target_file_key [String]
76
+ # @param options [Hash] options for copy_object method
77
+ # @return [String] Fog::Aliyun::Files#head status of directory contents
78
+ #
36
79
  def copy(target_directory_key, target_file_key, options = {})
37
80
  requires :directory, :key
38
- source_bucket, directory_key = collection.check_directory_key(directory.key)
39
- source_object = if directory_key == ''
40
- key
41
- else
42
- directory_key + '/' + key
43
- end
44
- target_bucket, target_directory_key = collection.check_directory_key(target_directory_key)
45
- target_object = if target_directory_key == ''
46
- target_file_key
47
- else
48
- target_directory_key + '/' + target_file_key
49
- end
50
- service.copy_object(source_bucket, source_object, target_bucket, target_object, options)
51
- target_directory = service.directories.new(key: target_directory_key)
52
- target_directory.files.get(target_file_key)
53
- end
54
-
55
- def destroy
81
+ service.copy_object(directory.key, key, target_directory_key, target_file_key, options)
82
+ target_directory = service.directories.new(:key => target_directory_key)
83
+ target_directory.files.head(target_file_key)
84
+ end
85
+
86
+ def destroy(options = {})
56
87
  requires :directory, :key
57
- bucket_name, directory_key = collection.check_directory_key(directory.key)
58
- object = if directory_key == ''
59
- key
60
- else
61
- directory_key + '/' + key
62
- end
63
- service.delete_object(object, bucket: bucket_name)
88
+ # TODO support versionId
89
+ # attributes[:body] = nil if options['versionId'] == version
90
+ service.delete_object(directory.key, key, options)
64
91
  true
65
92
  end
66
93
 
94
+ remove_method :metadata
67
95
  def metadata
68
- attributes[:metadata] ||= headers_to_metadata
96
+ attributes.reject {|key, value| !(key.to_s =~ /^x-oss-/)}
97
+ end
98
+
99
+ remove_method :metadata=
100
+ def metadata=(new_metadata)
101
+ merge_attributes(new_metadata)
69
102
  end
70
103
 
104
+ remove_method :owner=
71
105
  def owner=(new_owner)
72
106
  if new_owner
73
107
  attributes[:owner] = {
74
- display_name: new_owner['DisplayName'],
75
- id: new_owner['ID']
108
+ :display_name => new_owner['DisplayName'] || new_owner[:display_name],
109
+ :id => new_owner['ID'] || new_owner[:id]
76
110
  }
77
111
  end
78
112
  end
79
113
 
114
+ # Set Access-Control-List permissions.
115
+ #
116
+ # valid new_publics: public_read, private
117
+ #
118
+ # @param [String] new_public
119
+ # @return [String] new_public
120
+ #
80
121
  def public=(new_public)
122
+ if new_public
123
+ @acl = 'public-read'
124
+ else
125
+ @acl = 'private'
126
+ end
81
127
  new_public
82
128
  end
83
129
 
@@ -86,50 +132,32 @@ module Fog
86
132
  # required attributes: directory, key
87
133
  #
88
134
  # @param expires [String] number of seconds (since 1970-01-01 00:00) before url expires
89
- # @param options [Hash]
135
+ # @param options[Hash] No need to use
90
136
  # @return [String] url
91
137
  #
92
138
  def url(expires, options = {})
93
-
94
- expires = expires.nil? ? 0 : expires.to_i
95
-
96
- requires :directory, :key
97
- bucket_name, directory_key = collection.check_directory_key(directory.key)
98
- object = if directory_key == ''
99
- key
100
- else
101
- directory_key + '/' + key
102
- end
103
- service.get_object_http_url_public(object, expires, options.merge(bucket: bucket_name))
104
- end
105
-
106
- def public_url
107
139
  requires :key
108
- collection.get_url(key)
140
+ service.get_object_http_url_public(directory.key, key, expires)
109
141
  end
110
142
 
111
143
  def save(options = {})
112
144
  requires :body, :directory, :key
113
- options['Content-Type'] = content_type if content_type
145
+ options['x-oss-object-acl'] ||= @acl if @acl
146
+ options['Cache-Control'] = cache_control if cache_control
114
147
  options['Content-Disposition'] = content_disposition if content_disposition
115
- options.merge!(metadata_to_headers)
116
- bucket_name, directory_key = collection.check_directory_key(directory.key)
117
- object = if directory_key == ''
118
- key
119
- else
120
- directory_key + '/' + key
121
- end
122
- if body.is_a?(::File)
123
- service.put_object(object, body, options.merge(bucket: bucket_name))
124
- data = service.head_object(object, bucket: bucket_name)
125
- elsif body.is_a?(String)
126
- data = service.put_object_with_body(object, body, options.merge(bucket: bucket_name)).data
148
+ options['Content-Encoding'] = content_encoding if content_encoding
149
+ options['Content-MD5'] = content_md5 if content_md5
150
+ options['Content-Type'] = content_type if content_type
151
+ options['Expires'] = expires if expires
152
+ options.merge!(metadata)
153
+
154
+ self.multipart_chunk_size = 5242880 if !multipart_chunk_size && Fog::Storage.get_body_size(body) > 5368709120
155
+ if multipart_chunk_size && Fog::Storage.get_body_size(body) >= multipart_chunk_size && body.respond_to?(:read)
156
+ multipart_save(options)
127
157
  else
128
- raise Fog::Aliyun::Storage::Error, " Forbidden: Invalid body type: #{body.class}!"
158
+ service.put_object(directory.key, key, body, options)
129
159
  end
130
- update_attributes_from(data)
131
- refresh_metadata
132
-
160
+ self.etag = self.etag.gsub('"','') if self.etag
133
161
  self.content_length = Fog::Storage.get_body_size(body)
134
162
  self.content_type ||= Fog::Storage.get_content_type(body)
135
163
  true
@@ -137,70 +165,43 @@ module Fog
137
165
 
138
166
  private
139
167
 
140
- attr_writer :directory
141
-
142
- def refresh_metadata
143
- metadata.reject! { |_k, v| v.nil? }
144
- end
145
-
146
- def headers_to_metadata
147
- key_map = key_mapping
148
- Hash[metadata_attributes.map { |k, v| [key_map[k], v] }]
149
- end
150
-
151
- def key_mapping
152
- key_map = metadata_attributes
153
- key_map.each_pair { |k, _v| key_map[k] = header_to_key(k) }
168
+ def directory=(new_directory)
169
+ @directory = new_directory
154
170
  end
155
171
 
156
- def header_to_key(opt)
157
- opt.gsub(metadata_prefix, '').split('-').map { |k| k[0, 1].downcase + k[1..-1] }.join('_').to_sym
158
- end
159
-
160
- def metadata_to_headers
161
- header_map = header_mapping
162
- Hash[metadata.map { |k, v| [header_map[k], v] }]
163
- end
164
-
165
- def header_mapping
166
- header_map = metadata.dup
167
- header_map.each_pair { |k, _v| header_map[k] = key_to_header(k) }
168
- end
169
-
170
- def key_to_header(key)
171
- metadata_prefix + key.to_s.split(/[-_]/).map(&:capitalize).join('-')
172
- end
172
+ def multipart_save(options)
173
+ # Initiate the upload
174
+ upload_id = service.initiate_multipart_upload(directory.key, key, options)
173
175
 
174
- def metadata_attributes
175
- if last_modified
176
- bucket_name, directory_key = collection.check_directory_key(directory.key)
177
- object = if directory_key == ''
178
- key
179
- else
180
- directory_key + '/' + key
181
- end
176
+ # Store ETags of upload parts
177
+ part_tags = []
182
178
 
183
- data = service.head_object(object, bucket: bucket_name).data
184
- if data[:status] == 200
185
- headers = data[:headers]
186
- headers.select! { |k, _v| metadata_attribute?(k) }
187
- end
188
- else
189
- {}
179
+ # Upload each part
180
+ # TODO: optionally upload chunks in parallel using threads
181
+ # (may cause network performance problems with many small chunks)
182
+ # TODO: Support large chunk sizes without reading the chunk into memory
183
+ if body.respond_to?(:rewind)
184
+ body.rewind rescue nil
185
+ end
186
+ while (chunk = body.read(multipart_chunk_size)) do
187
+ part_upload = service.upload_part(directory.key, key, upload_id, part_tags.size + 1, chunk)
188
+ part_tags << part_upload
190
189
  end
191
- end
192
190
 
193
- def metadata_attribute?(key)
194
- key.to_s =~ /^#{metadata_prefix}/
195
- end
191
+ if part_tags.empty? #it is an error to have a multipart upload with no parts
192
+ part_upload = service.upload_part(directory.key, key, upload_id, 1, '')
193
+ part_tags << part_upload
194
+ end
196
195
 
197
- def metadata_prefix
198
- 'X-Object-Meta-'
196
+ rescue
197
+ # Abort the upload & reraise
198
+ service.abort_multipart_upload(directory.key, key, upload_id) if upload_id
199
+ raise
200
+ else
201
+ # Complete the upload
202
+ service.complete_multipart_upload(directory.key, key, upload_id, part_tags)
199
203
  end
200
204
 
201
- def update_attributes_from(data)
202
- merge_attributes(data[:headers].reject { |key, _value| ['Content-Length', 'Content-Type'].include?(key) })
203
- end
204
205
  end
205
206
  end
206
207
  end
@@ -20,39 +20,13 @@ module Fog
20
20
 
21
21
  model Fog::Aliyun::Storage::File
22
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
- elsif service.bucket_exists?(directory_key)
40
- bucket_name = directory_key
41
- directory_key = ''
42
- else
43
- directory_key
44
- end
45
- end
46
- return bucket_name, directory_key
47
- end
48
-
49
23
  def all(options = {})
50
24
  requires :directory
51
25
  options = {
52
- 'delimiter' => delimiter,
53
- 'marker' => marker,
54
- 'max-keys' => max_keys.to_i,
55
- 'prefix' => prefix
26
+ 'delimiter': delimiter,
27
+ 'marker': marker,
28
+ 'max-keys': max_keys.to_i,
29
+ 'prefix': prefix
56
30
  }.merge!(options)
57
31
  options = options.reject {|key,value| value.nil? || value.to_s.empty?}
58
32
  merge_attributes(options)
@@ -68,7 +42,8 @@ module Fog
68
42
  end
69
43
  end
70
44
 
71
- alias each_file_this_page each
45
+ alias_method :each_file_this_page, :each
46
+
72
47
  def each
73
48
  if !block_given?
74
49
  self
@@ -76,7 +51,7 @@ module Fog
76
51
  subset = dup.all
77
52
 
78
53
  subset.each_file_this_page { |f| yield f }
79
- while subset.length == (subset.limit || 10_000)
54
+ while subset.is_truncated
80
55
  subset = subset.all(marker: subset.last.key)
81
56
  subset.each_file_this_page { |f| yield f }
82
57
  end
@@ -87,38 +62,16 @@ module Fog
87
62
 
88
63
  def get(key, options = {}, &block)
89
64
  requires :directory
90
- bucket_name, directory_key = check_directory_key(directory.key)
91
- object = if directory_key == ''
92
- key
93
- else
94
- directory_key + '/' + key
95
- end
96
65
  begin
97
- data = service.get_object(object, options.merge({bucket: bucket_name}), &block)
98
- headers = data.headers
99
- lastModified = headers[:last_modified]
100
- last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
101
-
102
- date = headers[:date]
103
- date = (Time.parse(date).localtime if !date.nil? && date != '')
104
- file_data = {
105
- body: data.body,
106
- content_length: headers[:content_length].to_i,
107
- key: key,
108
- last_modified: last_modified,
109
- content_type: headers[:content_type],
110
- etag: headers[:etag],
111
- date: date,
112
- connection: headers[:connection],
113
- accept_ranges: headers[:accept_ranges],
114
- server: headers[:server],
115
- object_type: headers[:x_oss_object_type]
116
- }
117
-
66
+ data = service.get_object(directory.key, key, options, &block)
67
+ normalize_headers(data)
68
+ file_data = data.headers.merge({
69
+ :body => data.body,
70
+ :key => key
71
+ })
118
72
  new(file_data)
119
- rescue AliyunOssSdk::ServerError => error
120
- case error.error_code
121
- when %r{NoSuchKey},%r{SymlinkTargetNotExist}
73
+ rescue Exception => error
74
+ if error.respond_to?(:http_code) && error.http_code.to_i == 404
122
75
  nil
123
76
  else
124
77
  raise(error)
@@ -126,84 +79,50 @@ module Fog
126
79
  end
127
80
  end
128
81
 
129
- def get_url(key)
82
+ # @param options[Hash] No need to use
83
+ def get_url(key, options = {})
130
84
  requires :directory
131
- bucket_name, directory_key = check_directory_key(directory.key)
132
- object = if directory_key == ''
133
- key
134
- else
135
- directory_key + '/' + key
136
- end
137
- service.get_object_http_url_public(object, 3600, bucket: bucket_name)
85
+ service.get_object_http_url_public(directory.key, key, 3600)
138
86
  end
139
87
 
88
+ # @param options[Hash] No need to use
140
89
  def get_http_url(key, expires, options = {})
141
90
  requires :directory
142
- bucket_name, directory_key = check_directory_key(directory.key)
143
- object = if directory_key == ''
144
- key
145
- else
146
- directory_key + '/' + key
147
- end
148
- expires = expires.nil? ? 0 : expires.to_i
149
- service.get_object_http_url_public(object, expires, options.merge(bucket: bucket_name))
91
+ service.get_object_http_url_public(directory.key, key, expires)
150
92
  end
151
93
 
94
+ # @param options[Hash] No need to use
152
95
  def get_https_url(key, expires, options = {})
153
96
  requires :directory
154
- bucket_name, directory_key = check_directory_key(directory.key)
155
- object = if directory_key == ''
156
- key
157
- else
158
- directory_key + '/' + key
159
- end
160
- expires = expires.nil? ? 0 : expires.to_i
161
- service.get_object_https_url_public(object, expires, options.merge(bucket: bucket_name))
97
+ service.get_object_https_url_public(directory.key, key, expires)
162
98
  end
163
99
 
164
- def head(key, _options = {})
100
+ def head(key, options = {})
165
101
  requires :directory
166
- bucket_name, directory_key = check_directory_key(directory.key)
167
- object = if directory_key == ''
168
- key
169
- else
170
- directory_key + '/' + key
171
- end
172
- data = service.head_object(object, bucket: bucket_name).data
173
- return nil if data[:status] == 404
174
- lastModified = data[:headers]['Last-Modified']
175
- last_modified = (Time.parse(lastModified).localtime if !lastModified.nil? && lastModified != '')
176
-
177
- date = data[:headers]['Date']
178
- date = (Time.parse(date).localtime if !date.nil? && date != '')
179
-
180
- file_data = {
181
- content_length: data[:headers]['Content-Length'].to_i,
182
- key: key,
183
- last_modified: last_modified,
184
- content_type: data[:headers]['Content-Type'],
185
- etag: data[:headers]['ETag'],
186
- date: date,
187
- connection: data[:headers]['Connection'],
188
- accept_ranges: data[:headers]['Accept-Ranges'],
189
- server: data[:headers]['Server'],
190
- object_type: data[:headers]['x-oss-object-type']
191
- }
192
- new(file_data)
193
- rescue Fog::Aliyun::Storage::NotFound
194
- nil
102
+ begin
103
+ data = service.head_object(directory.key, key, options)
104
+ normalize_headers(data)
105
+ file_data = data.headers.merge({
106
+ :key => key
107
+ })
108
+ new(file_data)
109
+ rescue Exception => error
110
+ if error.respond_to?(:http_code) && error.http_code.to_i == 404
111
+ nil
112
+ else
113
+ raise(error)
114
+ end
115
+ end
195
116
  end
196
117
 
197
118
  def new(attributes = {})
198
119
  requires :directory
199
- # Sometimes, the v will be a Array, like "Prefix"=>[{}], "Marker"=>[xxxx], "MaxKeys"=>["100"], "IsTruncated"=>["false"]
200
- # and there needs to parse them
201
- for k, v in attributes
202
- if !v.nil? && (v.is_a? Array) && (v.size > 0)
203
- attributes[k] = v[0]
204
- end
205
- end
206
- super({ directory: directory }.merge!(attributes))
120
+ super({ :directory => directory }.merge!(attributes))
121
+ end
122
+
123
+ def normalize_headers(data)
124
+ data.headers[:last_modified] = Time.parse(data.headers[:last_modified])
125
+ data.headers[:etag] = data.headers[:etag].gsub('"','')
207
126
  end
208
127
  end
209
128
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'addressable'
4
+
3
5
  module Fog
4
6
  module Compute
5
7
  class Aliyun
@@ -46,7 +48,7 @@ module Fog
46
48
  if device
47
49
  parameters['Device'] = device
48
50
  pathUrl += '&Device='
49
- pathUrl += URI.encode(device, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
51
+ pathUrl += Addressable::URI.encode_component(device, Addressable::URI::CharacterClasses::UNRESERVED + '|')
50
52
  end
51
53
 
52
54
  signature = sign(@aliyun_accesskey_secret, parameters)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'addressable'
4
+
3
5
  module Fog
4
6
  module Compute
5
7
  class Aliyun
@@ -19,7 +21,7 @@ module Fog
19
21
 
20
22
  parameters['DestCidrIp'] = destCidrIp
21
23
  pathUrl += '&DestCidrIp='
22
- pathUrl += URI.encode(destCidrIp, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
24
+ pathUrl += Addressable::URI.encode_component(destCidrIp, Addressable::URI::CharacterClasses::UNRESERVED + '|')
23
25
  nicType ||= 'intranet'
24
26
  parameters['NicType'] = nicType
25
27
  pathUrl += '&NicType='
@@ -29,7 +31,7 @@ module Fog
29
31
  portRange ||= '-1/-1'
30
32
  parameters['PortRange'] = portRange
31
33
  pathUrl += '&PortRange='
32
- pathUrl += URI.encode(portRange, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
34
+ pathUrl += Addressable::URI.encode_component(portRange, Addressable::URI::CharacterClasses::UNRESERVED + '|')
33
35
 
34
36
  protocol = option[:protocol]
35
37
  protocol ||= 'all'
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'addressable'
4
+
3
5
  module Fog
4
6
  module Compute
5
7
  class Aliyun
@@ -30,7 +32,7 @@ module Fog
30
32
  portRange ||= '-1/-1'
31
33
  parameters['PortRange'] = portRange
32
34
  pathUrl += '&PortRange='
33
- pathUrl += URI.encode(portRange, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
35
+ pathUrl += Addressable::URI.encode_component(portRange, Addressable::URI::CharacterClasses::UNRESERVED + '|')
34
36
 
35
37
  protocol = option[:protocol]
36
38
  protocol ||= 'all'
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'addressable'
4
+
3
5
  module Fog
4
6
  module Compute
5
7
  class Aliyun
@@ -19,7 +21,7 @@ module Fog
19
21
 
20
22
  parameters['SourceCidrIp'] = sourceCidrIp
21
23
  pathUrl += '&SourceCidrIp='
22
- pathUrl += URI.encode(sourceCidrIp, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
24
+ pathUrl += Addressable::URI.encode_component(sourceCidrIp, Addressable::URI::CharacterClasses::UNRESERVED + '|')
23
25
  nicType ||= 'intranet'
24
26
  parameters['NicType'] = nicType
25
27
  pathUrl += '&NicType='
@@ -29,7 +31,7 @@ module Fog
29
31
  portRange ||= '-1/-1'
30
32
  parameters['PortRange'] = portRange
31
33
  pathUrl += '&PortRange='
32
- pathUrl += URI.encode(portRange, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
34
+ pathUrl += Addressable::URI.encode_component(portRange, Addressable::URI::CharacterClasses::UNRESERVED + '|')
33
35
 
34
36
  protocol = option[:protocol]
35
37
  protocol ||= 'all'
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'addressable'
4
+
3
5
  module Fog
4
6
  module Compute
5
7
  class Aliyun
@@ -30,7 +32,7 @@ module Fog
30
32
  portRange ||= '-1/-1'
31
33
  parameters['PortRange'] = portRange
32
34
  pathUrl += '&PortRange='
33
- pathUrl += URI.encode(portRange, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
35
+ pathUrl += Addressable::URI.encode_component(portRange, Addressable::URI::CharacterClasses::UNRESERVED + '|')
34
36
 
35
37
  protocol = option[:protocol]
36
38
  protocol ||= 'all'
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'addressable'
4
+
3
5
  module Fog
4
6
  module Compute
5
7
  class Aliyun
@@ -15,7 +17,7 @@ module Fog
15
17
 
16
18
  parameters['CidrBlock'] = cidrBlock
17
19
  pathUrl += '&CidrBlock='
18
- pathUrl += URI.encode(cidrBlock, '/[^!*\'()\;?:@#&%=+$,{}[]<>`" ')
20
+ pathUrl += Addressable::URI.encode_component(cidrBlock, Addressable::URI::CharacterClasses::UNRESERVED + '|')
19
21
 
20
22
  name = options[:name]
21
23
  desc = options[:description]