wrest 3.0.0 → 4.0.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.
- checksums.yaml +5 -5
- data/CHANGELOG +3 -0
- data/LICENCE +1 -1
- data/README.md +29 -28
- data/bin/wrest +2 -1
- data/bin/wrest_shell.rb +10 -8
- data/lib/wrest/async_request/event_machine_backend.rb +3 -1
- data/lib/wrest/async_request/thread_backend.rb +5 -2
- data/lib/wrest/async_request/thread_pool.rb +4 -2
- data/lib/wrest/async_request.rb +7 -6
- data/lib/wrest/cache_proxy.rb +39 -28
- data/lib/wrest/caching/memcached.rb +21 -18
- data/lib/wrest/caching/redis.rb +22 -22
- data/lib/wrest/caching.rb +16 -14
- data/lib/wrest/callback.rb +19 -16
- data/lib/wrest/components/container/alias_accessors.rb +51 -47
- data/lib/wrest/components/container/typecaster.rb +146 -96
- data/lib/wrest/components/container.rb +171 -152
- data/lib/wrest/components/mutators/base.rb +43 -34
- data/lib/wrest/components/mutators/camel_to_snake_case.rb +7 -3
- data/lib/wrest/components/mutators/{xml_mini_type_caster.rb → xml_type_caster.rb} +29 -16
- data/lib/wrest/components/mutators.rb +21 -19
- data/lib/wrest/components/translators/content_types.rb +20 -16
- data/lib/wrest/components/translators/json.rb +19 -16
- data/lib/wrest/components/translators/txt.rb +19 -15
- data/lib/wrest/components/translators/xml/conversions.rb +56 -0
- data/lib/wrest/components/translators/xml.rb +60 -18
- data/lib/wrest/components/translators.rb +7 -6
- data/lib/wrest/components.rb +11 -8
- data/lib/wrest/core_ext/hash/conversions.rb +10 -10
- data/lib/wrest/core_ext/hash.rb +4 -2
- data/lib/wrest/core_ext/string/conversions.rb +14 -13
- data/lib/wrest/core_ext/string.rb +5 -3
- data/lib/wrest/exceptions.rb +4 -2
- data/lib/wrest/hash_with_case_insensitive_access.rb +8 -8
- data/lib/wrest/hash_with_indifferent_access.rb +442 -0
- data/lib/wrest/http_codes.rb +20 -19
- data/lib/wrest/http_shared/headers.rb +2 -0
- data/lib/wrest/http_shared/standard_headers.rb +2 -2
- data/lib/wrest/http_shared/standard_tokens.rb +8 -6
- data/lib/wrest/http_shared.rb +5 -3
- data/lib/wrest/multipart.rb +20 -11
- data/lib/wrest/native/connection_factory.rb +15 -11
- data/lib/wrest/native/delete.rb +15 -11
- data/lib/wrest/native/get.rb +60 -56
- data/lib/wrest/native/options.rb +15 -11
- data/lib/wrest/native/patch.rb +16 -12
- data/lib/wrest/native/post.rb +15 -11
- data/lib/wrest/native/post_multipart.rb +22 -18
- data/lib/wrest/native/put.rb +16 -12
- data/lib/wrest/native/put_multipart.rb +22 -18
- data/lib/wrest/native/redirection.rb +13 -12
- data/lib/wrest/native/request.rb +144 -108
- data/lib/wrest/native/response.rb +87 -78
- data/lib/wrest/native/session.rb +49 -40
- data/lib/wrest/native.rb +14 -12
- data/lib/wrest/test/request_patches.rb +10 -3
- data/lib/wrest/test.rb +3 -1
- data/lib/wrest/uri/builders.rb +14 -12
- data/lib/wrest/uri.rb +70 -52
- data/lib/wrest/uri_template.rb +11 -7
- data/lib/wrest/utils.rb +129 -0
- data/lib/wrest/version.rb +3 -1
- data/lib/wrest.rb +31 -33
- data/lib/wrest_no_ext.rb +2 -0
- metadata +98 -48
- data/lib/wrest/components/mutators/xml_simple_type_caster.rb +0 -37
- data/lib/wrest/xml_mini/jdom/xpath_filter.rb +0 -17
- data/lib/wrest/xml_mini/jdom.rb +0 -6
- data/lib/wrest/xml_mini/libxml/xpath_filter.rb +0 -12
- data/lib/wrest/xml_mini/libxml.rb +0 -8
- data/lib/wrest/xml_mini/nokogiri/xpath_filter.rb +0 -15
- data/lib/wrest/xml_mini/nokogiri.rb +0 -7
- data/lib/wrest/xml_mini/rexml/xpath_filter.rb +0 -15
- data/lib/wrest/xml_mini/rexml.rb +0 -8
- data/lib/wrest/xml_mini.rb +0 -8
@@ -0,0 +1,442 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Wrest
|
4
|
+
# https://github.com/rails/rails/commit/1dcad65f8075d5b766082d3fbabdcb20fecb4ccd
|
5
|
+
# Implements a hash where keys <tt>:foo</tt> and <tt>"foo"</tt> are considered
|
6
|
+
# to be the same.
|
7
|
+
#
|
8
|
+
# rgb = ActiveSupport::HashWithIndifferentAccess.new
|
9
|
+
#
|
10
|
+
# rgb[:black] = '#000000'
|
11
|
+
# rgb[:black] # => '#000000'
|
12
|
+
# rgb['black'] # => '#000000'
|
13
|
+
#
|
14
|
+
# rgb['white'] = '#FFFFFF'
|
15
|
+
# rgb[:white] # => '#FFFFFF'
|
16
|
+
# rgb['white'] # => '#FFFFFF'
|
17
|
+
#
|
18
|
+
# Internally symbols are mapped to strings when used as keys in the entire
|
19
|
+
# writing interface (calling <tt>[]=</tt>, <tt>merge</tt>, etc). This
|
20
|
+
# mapping belongs to the public interface. For example, given:
|
21
|
+
#
|
22
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
|
23
|
+
#
|
24
|
+
# You are guaranteed that the key is returned as a string:
|
25
|
+
#
|
26
|
+
# hash.keys # => ["a"]
|
27
|
+
#
|
28
|
+
# Technically other types of keys are accepted:
|
29
|
+
#
|
30
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new(a: 1)
|
31
|
+
# hash[0] = 0
|
32
|
+
# hash # => {"a"=>1, 0=>0}
|
33
|
+
#
|
34
|
+
# but this class is intended for use cases where strings or symbols are the
|
35
|
+
# expected keys and it is convenient to understand both as the same. For
|
36
|
+
# example the +params+ hash in Ruby on Rails.
|
37
|
+
#
|
38
|
+
# Note that core extensions define <tt>Hash#with_indifferent_access</tt>:
|
39
|
+
#
|
40
|
+
# rgb = { black: '#000000', white: '#FFFFFF' }.with_indifferent_access
|
41
|
+
#
|
42
|
+
# which may be handy.
|
43
|
+
#
|
44
|
+
class HashWithIndifferentAccess < Hash
|
45
|
+
# Returns +true+ so that <tt>Array#extract_options!</tt> finds members of
|
46
|
+
# this class.
|
47
|
+
def extractable_options?
|
48
|
+
true
|
49
|
+
end
|
50
|
+
|
51
|
+
def with_indifferent_access
|
52
|
+
dup
|
53
|
+
end
|
54
|
+
|
55
|
+
def nested_under_indifferent_access
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
def initialize(constructor = nil)
|
60
|
+
if constructor.respond_to?(:to_hash)
|
61
|
+
super()
|
62
|
+
update(constructor)
|
63
|
+
|
64
|
+
hash = constructor.is_a?(Hash) ? constructor : constructor.to_hash
|
65
|
+
self.default = hash.default if hash.default
|
66
|
+
self.default_proc = hash.default_proc if hash.default_proc
|
67
|
+
elsif constructor.nil?
|
68
|
+
super()
|
69
|
+
else
|
70
|
+
super(constructor)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def self.[](*args)
|
75
|
+
new.merge!(Hash[*args])
|
76
|
+
end
|
77
|
+
|
78
|
+
alias regular_writer []= unless method_defined?(:regular_writer)
|
79
|
+
alias regular_update update unless method_defined?(:regular_update)
|
80
|
+
|
81
|
+
# Assigns a new value to the hash:
|
82
|
+
#
|
83
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
84
|
+
# hash[:key] = 'value'
|
85
|
+
#
|
86
|
+
# This value can be later fetched using either +:key+ or <tt>'key'</tt>.
|
87
|
+
def []=(key, value)
|
88
|
+
regular_writer(convert_key(key), convert_value(value, conversion: :assignment))
|
89
|
+
end
|
90
|
+
|
91
|
+
alias store []=
|
92
|
+
|
93
|
+
# Updates the receiver in-place, merging in the hashes passed as arguments:
|
94
|
+
#
|
95
|
+
# hash_1 = ActiveSupport::HashWithIndifferentAccess.new
|
96
|
+
# hash_1[:key] = 'value'
|
97
|
+
#
|
98
|
+
# hash_2 = ActiveSupport::HashWithIndifferentAccess.new
|
99
|
+
# hash_2[:key] = 'New Value!'
|
100
|
+
#
|
101
|
+
# hash_1.update(hash_2) # => {"key"=>"New Value!"}
|
102
|
+
#
|
103
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
104
|
+
# hash.update({ "a" => 1 }, { "b" => 2 }) # => { "a" => 1, "b" => 2 }
|
105
|
+
#
|
106
|
+
# The arguments can be either an
|
107
|
+
# <tt>ActiveSupport::HashWithIndifferentAccess</tt> or a regular +Hash+.
|
108
|
+
# In either case the merge respects the semantics of indifferent access.
|
109
|
+
#
|
110
|
+
# If the argument is a regular hash with keys +:key+ and <tt>"key"</tt> only one
|
111
|
+
# of the values end up in the receiver, but which one is unspecified.
|
112
|
+
#
|
113
|
+
# When given a block, the value for duplicated keys will be determined
|
114
|
+
# by the result of invoking the block with the duplicated key, the value
|
115
|
+
# in the receiver, and the value in +other_hash+. The rules for duplicated
|
116
|
+
# keys follow the semantics of indifferent access:
|
117
|
+
#
|
118
|
+
# hash_1[:key] = 10
|
119
|
+
# hash_2['key'] = 12
|
120
|
+
# hash_1.update(hash_2) { |key, old, new| old + new } # => {"key"=>22}
|
121
|
+
def update(*other_hashes, &block)
|
122
|
+
if other_hashes.size == 1
|
123
|
+
update_with_single_argument(other_hashes.first, block)
|
124
|
+
else
|
125
|
+
other_hashes.each do |other_hash|
|
126
|
+
update_with_single_argument(other_hash, block)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
self
|
130
|
+
end
|
131
|
+
|
132
|
+
alias merge! update
|
133
|
+
|
134
|
+
# Checks the hash for a key matching the argument passed in:
|
135
|
+
#
|
136
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
137
|
+
# hash['key'] = 'value'
|
138
|
+
# hash.key?(:key) # => true
|
139
|
+
# hash.key?('key') # => true
|
140
|
+
def key?(key)
|
141
|
+
super(convert_key(key))
|
142
|
+
end
|
143
|
+
|
144
|
+
alias include? key?
|
145
|
+
alias has_key? key?
|
146
|
+
alias member? key?
|
147
|
+
|
148
|
+
# Same as <tt>Hash#[]</tt> where the key passed as argument can be
|
149
|
+
# either a string or a symbol:
|
150
|
+
#
|
151
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
152
|
+
# counters[:foo] = 1
|
153
|
+
#
|
154
|
+
# counters['foo'] # => 1
|
155
|
+
# counters[:foo] # => 1
|
156
|
+
# counters[:zoo] # => nil
|
157
|
+
def [](key)
|
158
|
+
super(convert_key(key))
|
159
|
+
end
|
160
|
+
|
161
|
+
# Same as <tt>Hash#assoc</tt> where the key passed as argument can be
|
162
|
+
# either a string or a symbol:
|
163
|
+
#
|
164
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
165
|
+
# counters[:foo] = 1
|
166
|
+
#
|
167
|
+
# counters.assoc('foo') # => ["foo", 1]
|
168
|
+
# counters.assoc(:foo) # => ["foo", 1]
|
169
|
+
# counters.assoc(:zoo) # => nil
|
170
|
+
def assoc(key)
|
171
|
+
super(convert_key(key))
|
172
|
+
end
|
173
|
+
|
174
|
+
# Same as <tt>Hash#fetch</tt> where the key passed as argument can be
|
175
|
+
# either a string or a symbol:
|
176
|
+
#
|
177
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
178
|
+
# counters[:foo] = 1
|
179
|
+
#
|
180
|
+
# counters.fetch('foo') # => 1
|
181
|
+
# counters.fetch(:bar, 0) # => 0
|
182
|
+
# counters.fetch(:bar) { |key| 0 } # => 0
|
183
|
+
# counters.fetch(:zoo) # => KeyError: key not found: "zoo"
|
184
|
+
def fetch(key, *extras)
|
185
|
+
super(convert_key(key), *extras)
|
186
|
+
end
|
187
|
+
|
188
|
+
# Same as <tt>Hash#dig</tt> where the key passed as argument can be
|
189
|
+
# either a string or a symbol:
|
190
|
+
#
|
191
|
+
# counters = ActiveSupport::HashWithIndifferentAccess.new
|
192
|
+
# counters[:foo] = { bar: 1 }
|
193
|
+
#
|
194
|
+
# counters.dig('foo', 'bar') # => 1
|
195
|
+
# counters.dig(:foo, :bar) # => 1
|
196
|
+
# counters.dig(:zoo) # => nil
|
197
|
+
def dig(*args)
|
198
|
+
args[0] = convert_key(args[0]) if args.size.positive?
|
199
|
+
super(*args)
|
200
|
+
end
|
201
|
+
|
202
|
+
# Same as <tt>Hash#default</tt> where the key passed as argument can be
|
203
|
+
# either a string or a symbol:
|
204
|
+
#
|
205
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new(1)
|
206
|
+
# hash.default # => 1
|
207
|
+
#
|
208
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new { |hash, key| key }
|
209
|
+
# hash.default # => nil
|
210
|
+
# hash.default('foo') # => 'foo'
|
211
|
+
# hash.default(:foo) # => 'foo'
|
212
|
+
def default(*args)
|
213
|
+
super(*args.map { |arg| convert_key(arg) })
|
214
|
+
end
|
215
|
+
|
216
|
+
# Returns an array of the values at the specified indices:
|
217
|
+
#
|
218
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
219
|
+
# hash[:a] = 'x'
|
220
|
+
# hash[:b] = 'y'
|
221
|
+
# hash.values_at('a', 'b') # => ["x", "y"]
|
222
|
+
def values_at(*keys)
|
223
|
+
super(*keys.map { |key| convert_key(key) })
|
224
|
+
end
|
225
|
+
|
226
|
+
# Returns an array of the values at the specified indices, but also
|
227
|
+
# raises an exception when one of the keys can't be found.
|
228
|
+
#
|
229
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
230
|
+
# hash[:a] = 'x'
|
231
|
+
# hash[:b] = 'y'
|
232
|
+
# hash.fetch_values('a', 'b') # => ["x", "y"]
|
233
|
+
# hash.fetch_values('a', 'c') { |key| 'z' } # => ["x", "z"]
|
234
|
+
# hash.fetch_values('a', 'c') # => KeyError: key not found: "c"
|
235
|
+
def fetch_values(*indices, &block)
|
236
|
+
super(*indices.map { |key| convert_key(key) }, &block)
|
237
|
+
end
|
238
|
+
|
239
|
+
# Returns a shallow copy of the hash.
|
240
|
+
#
|
241
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new({ a: { b: 'b' } })
|
242
|
+
# dup = hash.dup
|
243
|
+
# dup[:a][:c] = 'c'
|
244
|
+
#
|
245
|
+
# hash[:a][:c] # => "c"
|
246
|
+
# dup[:a][:c] # => "c"
|
247
|
+
def dup
|
248
|
+
self.class.new(self).tap do |new_hash|
|
249
|
+
set_defaults(new_hash)
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
# This method has the same semantics of +update+, except it does not
|
254
|
+
# modify the receiver but rather returns a new hash with indifferent
|
255
|
+
# access with the result of the merge.
|
256
|
+
def merge(*hashes, &block)
|
257
|
+
dup.update(*hashes, &block)
|
258
|
+
end
|
259
|
+
|
260
|
+
# Like +merge+ but the other way around: Merges the receiver into the
|
261
|
+
# argument and returns a new hash with indifferent access as result:
|
262
|
+
#
|
263
|
+
# hash = ActiveSupport::HashWithIndifferentAccess.new
|
264
|
+
# hash['a'] = nil
|
265
|
+
# hash.reverse_merge(a: 0, b: 1) # => {"a"=>nil, "b"=>1}
|
266
|
+
def reverse_merge(other_hash)
|
267
|
+
super(self.class.new(other_hash))
|
268
|
+
end
|
269
|
+
|
270
|
+
alias with_defaults reverse_merge
|
271
|
+
|
272
|
+
# Same semantics as +reverse_merge+ but modifies the receiver in-place.
|
273
|
+
def reverse_merge!(other_hash)
|
274
|
+
super(self.class.new(other_hash))
|
275
|
+
end
|
276
|
+
|
277
|
+
alias with_defaults! reverse_merge!
|
278
|
+
|
279
|
+
# Replaces the contents of this hash with other_hash.
|
280
|
+
#
|
281
|
+
# h = { "a" => 100, "b" => 200 }
|
282
|
+
# h.replace({ "c" => 300, "d" => 400 }) # => {"c"=>300, "d"=>400}
|
283
|
+
def replace(other_hash)
|
284
|
+
super(self.class.new(other_hash))
|
285
|
+
end
|
286
|
+
|
287
|
+
# Removes the specified key from the hash.
|
288
|
+
def delete(key)
|
289
|
+
super(convert_key(key))
|
290
|
+
end
|
291
|
+
|
292
|
+
# Returns a hash with indifferent access that includes everything except given keys.
|
293
|
+
# hash = { a: "x", b: "y", c: 10 }.with_indifferent_access
|
294
|
+
# hash.except(:a, "b") # => {c: 10}.with_indifferent_access
|
295
|
+
# hash # => { a: "x", b: "y", c: 10 }.with_indifferent_access
|
296
|
+
def except(*keys)
|
297
|
+
slice(*self.keys - keys.map { |key| convert_key(key) })
|
298
|
+
end
|
299
|
+
|
300
|
+
alias without except
|
301
|
+
|
302
|
+
def stringify_keys!
|
303
|
+
transform_keys!(&:to_s)
|
304
|
+
end
|
305
|
+
|
306
|
+
def stringify_keys
|
307
|
+
transform_keys(&:to_s)
|
308
|
+
end
|
309
|
+
|
310
|
+
def symbolize_keys
|
311
|
+
symbolize_keys!
|
312
|
+
end
|
313
|
+
|
314
|
+
def symbolize_keys!
|
315
|
+
transform_keys! do |key|
|
316
|
+
key.to_sym
|
317
|
+
rescue StandardError
|
318
|
+
key
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
alias to_options symbolize_keys
|
323
|
+
|
324
|
+
def to_options!
|
325
|
+
self
|
326
|
+
end
|
327
|
+
|
328
|
+
def select(*args, &block)
|
329
|
+
return to_enum(:select) unless block_given?
|
330
|
+
|
331
|
+
dup.tap { |hash| hash.select!(*args, &block) }
|
332
|
+
end
|
333
|
+
|
334
|
+
def reject(*args, &block)
|
335
|
+
return to_enum(:reject) unless block_given?
|
336
|
+
|
337
|
+
dup.tap { |hash| hash.reject!(*args, &block) }
|
338
|
+
end
|
339
|
+
|
340
|
+
def transform_values(*args, &block)
|
341
|
+
return to_enum(:transform_values) unless block_given?
|
342
|
+
|
343
|
+
dup.tap { |hash| hash.transform_values!(*args, &block) }
|
344
|
+
end
|
345
|
+
|
346
|
+
def transform_keys(*args, &block)
|
347
|
+
return to_enum(:transform_keys) unless block_given?
|
348
|
+
|
349
|
+
dup.tap { |hash| hash.transform_keys!(*args, &block) }
|
350
|
+
end
|
351
|
+
|
352
|
+
def transform_keys!
|
353
|
+
return enum_for(:transform_keys!) { size } unless block_given?
|
354
|
+
|
355
|
+
keys.each do |key|
|
356
|
+
self[yield(key)] = delete(key)
|
357
|
+
end
|
358
|
+
self
|
359
|
+
end
|
360
|
+
|
361
|
+
def slice(*keys)
|
362
|
+
keys.map! { |key| convert_key(key) }
|
363
|
+
self.class.new(super)
|
364
|
+
end
|
365
|
+
|
366
|
+
def slice!(*keys)
|
367
|
+
keys.map! { |key| convert_key(key) }
|
368
|
+
super
|
369
|
+
end
|
370
|
+
|
371
|
+
def compact
|
372
|
+
dup.tap(&:compact!)
|
373
|
+
end
|
374
|
+
|
375
|
+
# Convert to a regular hash with string keys.
|
376
|
+
def to_hash
|
377
|
+
a_new_hash = {}
|
378
|
+
set_defaults(a_new_hash)
|
379
|
+
|
380
|
+
each do |key, value|
|
381
|
+
a_new_hash[key] = convert_value(value, conversion: :to_hash)
|
382
|
+
end
|
383
|
+
a_new_hash
|
384
|
+
end
|
385
|
+
|
386
|
+
private
|
387
|
+
|
388
|
+
if Symbol.method_defined?(:name)
|
389
|
+
def convert_key(key)
|
390
|
+
key.is_a?(Symbol) ? key.name : key
|
391
|
+
end
|
392
|
+
else
|
393
|
+
def convert_key(key)
|
394
|
+
key.is_a?(Symbol) ? key.to_s : key
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
def convert_value(value, conversion: nil)
|
399
|
+
case value
|
400
|
+
when Hash
|
401
|
+
convert_hash_value(conversion, value)
|
402
|
+
when Array
|
403
|
+
convert_array_value(conversion, value)
|
404
|
+
else
|
405
|
+
value
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
def convert_array_value(conversion, value)
|
410
|
+
value = value.dup if conversion != :assignment || value.frozen?
|
411
|
+
value.map! { |e| convert_value(e, conversion: conversion) }
|
412
|
+
value
|
413
|
+
end
|
414
|
+
|
415
|
+
def convert_hash_value(conversion, value)
|
416
|
+
if conversion == :to_hash
|
417
|
+
value.to_hash
|
418
|
+
else
|
419
|
+
HashWithIndifferentAccess.new(value)
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
def set_defaults(target) # rubocop:disable Naming/AccessorMethodName
|
424
|
+
if default_proc
|
425
|
+
target.default_proc = default_proc.dup
|
426
|
+
else
|
427
|
+
target.default = default
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
def update_with_single_argument(other_hash, block)
|
432
|
+
if other_hash.is_a? HashWithIndifferentAccess
|
433
|
+
regular_update(other_hash, &block)
|
434
|
+
else
|
435
|
+
other_hash.to_hash.each_pair do |key, value|
|
436
|
+
value = block.call(convert_key(key), self[key], value) if block && key?(key)
|
437
|
+
regular_writer(convert_key(key), convert_value(value))
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
data/lib/wrest/http_codes.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2009 Sidu Ponnappa
|
2
4
|
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -10,73 +12,72 @@
|
|
10
12
|
module Wrest
|
11
13
|
# Contains convenience methods to check HTTP response codes
|
12
14
|
module HttpCodes
|
13
|
-
|
14
15
|
def ok?
|
15
|
-
|
16
|
+
code.to_i == 200
|
16
17
|
end
|
17
18
|
|
18
19
|
def created?
|
19
|
-
|
20
|
+
code.to_i == 201
|
20
21
|
end
|
21
|
-
|
22
|
+
|
22
23
|
def accepted?
|
23
|
-
|
24
|
+
code.to_i == 202
|
24
25
|
end
|
25
26
|
|
26
27
|
def no_content?
|
27
|
-
|
28
|
+
code.to_i == 204
|
28
29
|
end
|
29
30
|
|
30
31
|
def moved_permanently?
|
31
|
-
|
32
|
+
code.to_i == 301
|
32
33
|
end
|
33
34
|
|
34
35
|
def found?
|
35
|
-
|
36
|
+
code.to_i == 302
|
36
37
|
end
|
37
38
|
|
38
39
|
def see_other?
|
39
|
-
|
40
|
+
code.to_i == 303
|
40
41
|
end
|
41
42
|
|
42
43
|
def not_modified?
|
43
|
-
|
44
|
+
code.to_i == 304
|
44
45
|
end
|
45
46
|
|
46
47
|
def temporary_redirect?
|
47
|
-
|
48
|
+
code.to_i == 307
|
48
49
|
end
|
49
50
|
|
50
51
|
def bad_request?
|
51
|
-
|
52
|
+
code.to_i == 400
|
52
53
|
end
|
53
54
|
|
54
55
|
def unauthorized?
|
55
|
-
|
56
|
+
code.to_i == 401
|
56
57
|
end
|
57
58
|
|
58
59
|
def forbidden?
|
59
|
-
|
60
|
+
code.to_i == 403
|
60
61
|
end
|
61
62
|
|
62
63
|
def not_found?
|
63
|
-
|
64
|
+
code.to_i == 404
|
64
65
|
end
|
65
66
|
|
66
67
|
def method_not_allowed?
|
67
|
-
|
68
|
+
code.to_i == 405
|
68
69
|
end
|
69
70
|
|
70
71
|
def not_acceptable?
|
71
|
-
|
72
|
+
code.to_i == 406
|
72
73
|
end
|
73
74
|
|
74
75
|
def unprocessable_entity?
|
75
|
-
|
76
|
+
code.to_i == 422
|
76
77
|
end
|
77
78
|
|
78
79
|
def internal_server_error?
|
79
|
-
|
80
|
+
code.to_i == 500
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
@@ -1,11 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2009 Sidu Ponnappa
|
2
4
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
-
# you may not use this file except in compliance with the License.
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
5
7
|
# You may obtain a copy of the License at Http://www.apache.org/licenses/LICENSE-2.0
|
6
|
-
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
7
|
-
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
8
|
-
# See the License for the specific language governing permissions and limitations under the License.
|
8
|
+
# Unless required by applicable law or agreed to in writing, software distributed under the License
|
9
|
+
# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and limitations under the License.
|
9
11
|
|
10
12
|
module Wrest
|
11
13
|
module HttpShared
|
@@ -16,4 +18,4 @@ module Wrest
|
|
16
18
|
ApplicationXml = 'application/xml'
|
17
19
|
end
|
18
20
|
end
|
19
|
-
end
|
21
|
+
end
|
data/lib/wrest/http_shared.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2009 Sidu Ponnappa
|
2
4
|
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -14,9 +16,9 @@ module Wrest
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
require
|
18
|
-
require
|
19
|
-
require
|
19
|
+
require 'wrest/http_shared/headers'
|
20
|
+
require 'wrest/http_shared/standard_headers'
|
21
|
+
require 'wrest/http_shared/standard_tokens'
|
20
22
|
|
21
23
|
# Set up a shorter convenience API for constants
|
22
24
|
Wrest::H = Wrest::HttpShared::StandardHeaders
|
data/lib/wrest/multipart.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Copyright 2009 - 2010 Sidu Ponnappa
|
2
4
|
|
3
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
@@ -14,8 +16,8 @@ rescue Gem::LoadError => e
|
|
14
16
|
raise e
|
15
17
|
end
|
16
18
|
|
17
|
-
require
|
18
|
-
require
|
19
|
+
require 'wrest/native/post_multipart'
|
20
|
+
require 'wrest/native/put_multipart'
|
19
21
|
|
20
22
|
module Wrest
|
21
23
|
# To enable Multipart support, use
|
@@ -28,18 +30,19 @@ module Wrest
|
|
28
30
|
# The methods in this module are mixed into Wrest::Uri.
|
29
31
|
module Multipart
|
30
32
|
# Makes a multipart/form-data encoded POST request to this URI. This is a convenience API
|
31
|
-
# that mimics a multipart form being posted; some allegedly RESTful APIs like FCBK require
|
33
|
+
# that mimics a multipart form being posted; some allegedly RESTful APIs like FCBK require
|
32
34
|
# this for file uploads.
|
33
35
|
#
|
34
36
|
# File.open('/path/to/image.jpg') do |file|
|
35
37
|
# 'http://localhost:3000/uploads'.to_uri.post_multipart('file' => UploadIO.new(file, "image/jpg", '/path/to/image.jpg'))
|
36
38
|
# end
|
37
39
|
def post_multipart(parameters = {}, headers = {}, &block)
|
38
|
-
Http::PostMultipart.new(self, parameters, headers,
|
40
|
+
Http::PostMultipart.new(self, parameters, headers,
|
41
|
+
block ? @options.merge(callback_block: block) : @options).invoke
|
39
42
|
end
|
40
43
|
|
41
44
|
# Makes a multipart/form-data encoded POST request to this URI. This is a convenience API
|
42
|
-
# that mimics a multipart form being posted; some allegedly RESTful APIs like FCBK require
|
45
|
+
# that mimics a multipart form being posted; some allegedly RESTful APIs like FCBK require
|
43
46
|
# this for file uploads.
|
44
47
|
#
|
45
48
|
# File.open('/path/to/image.jpg') do |file|
|
@@ -49,13 +52,18 @@ module Wrest
|
|
49
52
|
# Note: post_multipart_async does not return a response and the response should be accessed through callbacks.
|
50
53
|
# This implementation of asynchronous post_multipart is currently in alpha. Hence, it should not be used in production.
|
51
54
|
def post_multipart_async(parameters = {}, headers = {}, &block)
|
52
|
-
(@options[:asynchronous_backend] || Wrest::AsyncRequest.default_backend)
|
55
|
+
(@options[:asynchronous_backend] || Wrest::AsyncRequest.default_backend)
|
56
|
+
.execute(
|
57
|
+
Http::PostMultipart.new(self,
|
58
|
+
parameters, headers, block ? @options.merge(callback_block: block) : @options)
|
59
|
+
)
|
53
60
|
end
|
54
|
-
|
61
|
+
|
55
62
|
# Makes a multipart/form-data encoded PUT request to this URI. This is a convenience API
|
56
63
|
# that mimics a multipart form being put. I sincerely hope you never need to use this.
|
57
64
|
def put_multipart(parameters = {}, headers = {}, &block)
|
58
|
-
Http::PutMultipart.new(self, parameters, headers,
|
65
|
+
Http::PutMultipart.new(self, parameters, headers,
|
66
|
+
block ? @options.merge(callback_block: block) : @options).invoke
|
59
67
|
end
|
60
68
|
|
61
69
|
# Makes a multipart/form-data encoded PUT request to this URI. This is a convenience API
|
@@ -64,12 +72,13 @@ module Wrest
|
|
64
72
|
# Note: put_multipart_async does not return a response and the response should be accessed through callbacks
|
65
73
|
# This implementation of asynchronous put_multipart is currently in alpha. Hence, it should not be used in production.
|
66
74
|
def put_multipart_async(parameters = {}, headers = {}, &block)
|
67
|
-
|
75
|
+
request = Http::PutMultipart.new(self,
|
76
|
+
parameters, headers, block ? @options.merge(callback_block: block) : @options)
|
77
|
+
(@options[:asynchronous_backend] || Wrest::AsyncRequest.default_backend).execute(request)
|
68
78
|
end
|
69
79
|
end
|
70
|
-
|
80
|
+
|
71
81
|
class Uri
|
72
82
|
include Multipart
|
73
83
|
end
|
74
84
|
end
|
75
|
-
|