fog-aliyun 0.3.17 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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]