wrest 4.0.0-universal-java-18
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 +7 -0
- data/CHANGELOG +169 -0
- data/LICENCE +7 -0
- data/README.md +436 -0
- data/bin/wrest +4 -0
- data/bin/wrest_shell.rb +23 -0
- data/lib/wrest/async_request/event_machine_backend.rb +32 -0
- data/lib/wrest/async_request/thread_backend.rb +34 -0
- data/lib/wrest/async_request/thread_pool.rb +29 -0
- data/lib/wrest/async_request.rb +51 -0
- data/lib/wrest/cache_proxy.rb +119 -0
- data/lib/wrest/caching/memcached.rb +37 -0
- data/lib/wrest/caching/redis.rb +38 -0
- data/lib/wrest/caching.rb +57 -0
- data/lib/wrest/callback.rb +70 -0
- data/lib/wrest/components/container/alias_accessors.rb +70 -0
- data/lib/wrest/components/container/typecaster.rb +178 -0
- data/lib/wrest/components/container.rb +204 -0
- data/lib/wrest/components/mutators/base.rb +65 -0
- data/lib/wrest/components/mutators/camel_to_snake_case.rb +26 -0
- data/lib/wrest/components/mutators/xml_type_caster.rb +56 -0
- data/lib/wrest/components/mutators.rb +42 -0
- data/lib/wrest/components/translators/content_types.rb +25 -0
- data/lib/wrest/components/translators/json.rb +36 -0
- data/lib/wrest/components/translators/txt.rb +35 -0
- data/lib/wrest/components/translators/xml/conversions.rb +56 -0
- data/lib/wrest/components/translators/xml.rb +77 -0
- data/lib/wrest/components/translators.rb +30 -0
- data/lib/wrest/components.rb +22 -0
- data/lib/wrest/core_ext/hash/conversions.rb +45 -0
- data/lib/wrest/core_ext/hash.rb +7 -0
- data/lib/wrest/core_ext/string/conversions.rb +38 -0
- data/lib/wrest/core_ext/string.rb +7 -0
- data/lib/wrest/exceptions.rb +38 -0
- data/lib/wrest/hash_with_case_insensitive_access.rb +52 -0
- data/lib/wrest/hash_with_indifferent_access.rb +442 -0
- data/lib/wrest/http_codes.rb +83 -0
- data/lib/wrest/http_shared/headers.rb +345 -0
- data/lib/wrest/http_shared/standard_headers.rb +22 -0
- data/lib/wrest/http_shared/standard_tokens.rb +21 -0
- data/lib/wrest/http_shared.rb +25 -0
- data/lib/wrest/multipart.rb +84 -0
- data/lib/wrest/native/connection_factory.rb +28 -0
- data/lib/wrest/native/delete.rb +27 -0
- data/lib/wrest/native/get.rb +83 -0
- data/lib/wrest/native/options.rb +27 -0
- data/lib/wrest/native/patch.rb +27 -0
- data/lib/wrest/native/post.rb +27 -0
- data/lib/wrest/native/post_multipart.rb +36 -0
- data/lib/wrest/native/put.rb +27 -0
- data/lib/wrest/native/put_multipart.rb +36 -0
- data/lib/wrest/native/redirection.rb +39 -0
- data/lib/wrest/native/request.rb +161 -0
- data/lib/wrest/native/response.rb +278 -0
- data/lib/wrest/native/session.rb +66 -0
- data/lib/wrest/native.rb +36 -0
- data/lib/wrest/test/request_patches.rb +12 -0
- data/lib/wrest/test.rb +3 -0
- data/lib/wrest/uri/builders.rb +48 -0
- data/lib/wrest/uri.rb +312 -0
- data/lib/wrest/uri_template.rb +63 -0
- data/lib/wrest/utils.rb +129 -0
- data/lib/wrest/version.rb +14 -0
- data/lib/wrest.rb +77 -0
- data/lib/wrest_no_ext.rb +7 -0
- metadata +286 -0
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at native://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
module Wrest
|
13
|
+
# Contains convenience methods to check HTTP response codes
|
14
|
+
module HttpCodes
|
15
|
+
def ok?
|
16
|
+
code.to_i == 200
|
17
|
+
end
|
18
|
+
|
19
|
+
def created?
|
20
|
+
code.to_i == 201
|
21
|
+
end
|
22
|
+
|
23
|
+
def accepted?
|
24
|
+
code.to_i == 202
|
25
|
+
end
|
26
|
+
|
27
|
+
def no_content?
|
28
|
+
code.to_i == 204
|
29
|
+
end
|
30
|
+
|
31
|
+
def moved_permanently?
|
32
|
+
code.to_i == 301
|
33
|
+
end
|
34
|
+
|
35
|
+
def found?
|
36
|
+
code.to_i == 302
|
37
|
+
end
|
38
|
+
|
39
|
+
def see_other?
|
40
|
+
code.to_i == 303
|
41
|
+
end
|
42
|
+
|
43
|
+
def not_modified?
|
44
|
+
code.to_i == 304
|
45
|
+
end
|
46
|
+
|
47
|
+
def temporary_redirect?
|
48
|
+
code.to_i == 307
|
49
|
+
end
|
50
|
+
|
51
|
+
def bad_request?
|
52
|
+
code.to_i == 400
|
53
|
+
end
|
54
|
+
|
55
|
+
def unauthorized?
|
56
|
+
code.to_i == 401
|
57
|
+
end
|
58
|
+
|
59
|
+
def forbidden?
|
60
|
+
code.to_i == 403
|
61
|
+
end
|
62
|
+
|
63
|
+
def not_found?
|
64
|
+
code.to_i == 404
|
65
|
+
end
|
66
|
+
|
67
|
+
def method_not_allowed?
|
68
|
+
code.to_i == 405
|
69
|
+
end
|
70
|
+
|
71
|
+
def not_acceptable?
|
72
|
+
code.to_i == 406
|
73
|
+
end
|
74
|
+
|
75
|
+
def unprocessable_entity?
|
76
|
+
code.to_i == 422
|
77
|
+
end
|
78
|
+
|
79
|
+
def internal_server_error?
|
80
|
+
code.to_i == 500
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,345 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Header module.
|
5
|
+
#
|
6
|
+
# Provides access to headers in the mixed-into class as a hash-like
|
7
|
+
# object, except with case-insensitive keys. Also provides
|
8
|
+
# methods for accessing commonly-used header values in a more
|
9
|
+
# convenient format.
|
10
|
+
#
|
11
|
+
# Sourced from Net::HTTP and then modified to be generic
|
12
|
+
module Wrest
|
13
|
+
module HttpShared
|
14
|
+
module Headers
|
15
|
+
# Returns the header field corresponding to the case-insensitive key.
|
16
|
+
# For example, a key of "Content-Type" might return "text/html"
|
17
|
+
def [](key)
|
18
|
+
headers[key] || headers[key.downcase]
|
19
|
+
end
|
20
|
+
|
21
|
+
# # Sets the header field corresponding to the case-insensitive key.
|
22
|
+
# def []=(key, val)
|
23
|
+
# unless val
|
24
|
+
# headers.delete key.downcase
|
25
|
+
# return val
|
26
|
+
# end
|
27
|
+
# headers[key.downcase] = [val]
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# # [Ruby 1.8.3]
|
31
|
+
# # Adds header field instead of replace.
|
32
|
+
# # Second argument +val+ must be a String.
|
33
|
+
# # See also #[]=, #[] and #get_fields.
|
34
|
+
# #
|
35
|
+
# # request.add_field 'X-My-Header', 'a'
|
36
|
+
# # p request['X-My-Header'] #=> "a"
|
37
|
+
# # p request.get_fields('X-My-Header') #=> ["a"]
|
38
|
+
# # request.add_field 'X-My-Header', 'b'
|
39
|
+
# # p request['X-My-Header'] #=> "a, b"
|
40
|
+
# # p request.get_fields('X-My-Header') #=> ["a", "b"]
|
41
|
+
# # request.add_field 'X-My-Header', 'c'
|
42
|
+
# # p request['X-My-Header'] #=> "a, b, c"
|
43
|
+
# # p request.get_fields('X-My-Header') #=> ["a", "b", "c"]
|
44
|
+
# #
|
45
|
+
# def add_field(key, val)
|
46
|
+
# if headers.key?(key.downcase)
|
47
|
+
# headers[key.downcase].push val
|
48
|
+
# else
|
49
|
+
# headers[key.downcase] = [val]
|
50
|
+
# end
|
51
|
+
# end
|
52
|
+
#
|
53
|
+
# # [Ruby 1.8.3]
|
54
|
+
# # Returns an array of header field strings corresponding to the
|
55
|
+
# # case-insensitive +key+. This method allows you to get duplicated
|
56
|
+
# # header fields without any processing. See also #[].
|
57
|
+
# #
|
58
|
+
# # p response.get_fields('Set-Cookie')
|
59
|
+
# # #=> ["session=al98axx; expires=Fri, 31-Dec-1999 23:58:23",
|
60
|
+
# # "query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"]
|
61
|
+
# # p response['Set-Cookie']
|
62
|
+
# # #=> "session=al98axx; expires=Fri, 31-Dec-1999 23:58:23, query=rubyscript; expires=Fri, 31-Dec-1999 23:58:23"
|
63
|
+
# #
|
64
|
+
# def get_fields(key)
|
65
|
+
# return nil unless headers[key.downcase]
|
66
|
+
# headers[key.downcase].dup
|
67
|
+
# end
|
68
|
+
#
|
69
|
+
# # Returns the header field corresponding to the case-insensitive key.
|
70
|
+
# # Returns the default value +args+, or the result of the block, or nil,
|
71
|
+
# # if there's no header field named key. See Hash#fetch
|
72
|
+
# def fetch(key, *args, &block) #:yield: +key+
|
73
|
+
# a = headers.fetch(key.downcase, *args, &block)
|
74
|
+
# a.join(', ')
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# # Iterates for each header names and values.
|
78
|
+
# def each_header #:yield: +key+, +value+
|
79
|
+
# headers.each do |k,va|
|
80
|
+
# yield k, va.join(', ')
|
81
|
+
# end
|
82
|
+
# end
|
83
|
+
#
|
84
|
+
# alias each each_header
|
85
|
+
#
|
86
|
+
# # Iterates for each header names.
|
87
|
+
# def each_name(&block) #:yield: +key+
|
88
|
+
# headers.each_key(&block)
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# alias each_key each_name
|
92
|
+
#
|
93
|
+
# # Iterates for each capitalized header names.
|
94
|
+
# def each_capitalized_name(&block) #:yield: +key+
|
95
|
+
# headers.each_key do |k|
|
96
|
+
# yield capitalize(k)
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
#
|
100
|
+
# # Iterates for each header values.
|
101
|
+
# def each_value #:yield: +value+
|
102
|
+
# headers.each_value do |va|
|
103
|
+
# yield va.join(', ')
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
#
|
107
|
+
# # Removes a header field.
|
108
|
+
# def delete(key)
|
109
|
+
# headers.delete(key.downcase)
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# # true if +key+ header exists.
|
113
|
+
# def key?(key)
|
114
|
+
# headers.key?(key.downcase)
|
115
|
+
# end
|
116
|
+
#
|
117
|
+
# # Returns a Hash consist of header names and values.
|
118
|
+
# def to_hash
|
119
|
+
# headers.dup
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# # As for #each_header, except the keys are provided in capitalized form.
|
123
|
+
# def each_capitalized
|
124
|
+
# headers.each do |k,v|
|
125
|
+
# yield capitalize(k), v.join(', ')
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# alias canonical_each each_capitalized
|
130
|
+
#
|
131
|
+
# def capitalize(name)
|
132
|
+
# name.split(/-/).map {|s| s.capitalize }.join('-')
|
133
|
+
# end
|
134
|
+
# private :capitalize
|
135
|
+
#
|
136
|
+
# # Returns an Array of Range objects which represents Range: header field,
|
137
|
+
# # or +nil+ if there is no such header.
|
138
|
+
# def range
|
139
|
+
# return nil unless headers['range']
|
140
|
+
# self['Range'].split(/,/).map {|spec|
|
141
|
+
# m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or
|
142
|
+
# raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
|
143
|
+
# d1 = m[1].to_i
|
144
|
+
# d2 = m[2].to_i
|
145
|
+
# if m[1] and m[2] then d1..d2
|
146
|
+
# elsif m[1] then d1..-1
|
147
|
+
# elsif m[2] then -d2..-1
|
148
|
+
# else
|
149
|
+
# raise HTTPHeaderSyntaxError, 'range is not specified'
|
150
|
+
# end
|
151
|
+
# }
|
152
|
+
# end
|
153
|
+
#
|
154
|
+
# # Set Range: header from Range (arg r) or beginning index and
|
155
|
+
# # length from it (arg idx&len).
|
156
|
+
# #
|
157
|
+
# # req.range = (0..1023)
|
158
|
+
# # req.set_range 0, 1023
|
159
|
+
# #
|
160
|
+
# def set_range(r, e = nil)
|
161
|
+
# unless r
|
162
|
+
# headers.delete 'range'
|
163
|
+
# return r
|
164
|
+
# end
|
165
|
+
# r = (r...r+e) if e
|
166
|
+
# case r
|
167
|
+
# when Numeric
|
168
|
+
# n = r.to_i
|
169
|
+
# rangestr = (n > 0 ? "0-#{n-1}" : "-#{-n}")
|
170
|
+
# when Range
|
171
|
+
# first = r.first
|
172
|
+
# last = r.last
|
173
|
+
# last -= 1 if r.exclude_end?
|
174
|
+
# if last == -1
|
175
|
+
# rangestr = (first > 0 ? "#{first}-" : "-#{-first}")
|
176
|
+
# else
|
177
|
+
# raise HTTPHeaderSyntaxError, 'range.first is negative' if first < 0
|
178
|
+
# raise HTTPHeaderSyntaxError, 'range.last is negative' if last < 0
|
179
|
+
# raise HTTPHeaderSyntaxError, 'must be .first < .last' if first > last
|
180
|
+
# rangestr = "#{first}-#{last}"
|
181
|
+
# end
|
182
|
+
# else
|
183
|
+
# raise TypeError, 'Range/Integer is required'
|
184
|
+
# end
|
185
|
+
# headers['range'] = ["bytes=#{rangestr}"]
|
186
|
+
# r
|
187
|
+
# end
|
188
|
+
#
|
189
|
+
# alias range= set_range
|
190
|
+
#
|
191
|
+
# # Returns an Integer object which represents the Content-Length: header field
|
192
|
+
# # or +nil+ if that field is not provided.
|
193
|
+
# def content_length
|
194
|
+
# return nil unless key?('Content-Length')
|
195
|
+
# len = self['Content-Length'].slice(/\d+/) or
|
196
|
+
# raise HTTPHeaderSyntaxError, 'wrong Content-Length format'
|
197
|
+
# len.to_i
|
198
|
+
# end
|
199
|
+
#
|
200
|
+
# def content_length=(len)
|
201
|
+
# unless len
|
202
|
+
# headers.delete 'content-length'
|
203
|
+
# return nil
|
204
|
+
# end
|
205
|
+
# headers['content-length'] = [len.to_i.to_s]
|
206
|
+
# end
|
207
|
+
#
|
208
|
+
# # Returns "true" if the "transfer-encoding" header is present and
|
209
|
+
# # set to "chunked". This is an HTTP/1.1 feature, allowing the
|
210
|
+
# # the content to be sent in "chunks" without at the outset
|
211
|
+
# # stating the entire content length.
|
212
|
+
# def chunked?
|
213
|
+
# return false unless headers['transfer-encoding']
|
214
|
+
# field = self['Transfer-Encoding']
|
215
|
+
# (/(?:\A|[^\-\w])chunked(?![\-\w])/i =~ field) ? true : false
|
216
|
+
# end
|
217
|
+
#
|
218
|
+
# # Returns a Range object which represents Content-Range: header field.
|
219
|
+
# # This indicates, for a partial entity body, where this fragment
|
220
|
+
# # fits inside the full entity body, as range of byte offsets.
|
221
|
+
# def content_range
|
222
|
+
# return nil unless headers['content-range']
|
223
|
+
# m = %r<bytes\s+(\d+)-(\d+)/(\d+|\*)>i.match(self['Content-Range']) or
|
224
|
+
# raise HTTPHeaderSyntaxError, 'wrong Content-Range format'
|
225
|
+
# m[1].to_i .. m[2].to_i + 1
|
226
|
+
# end
|
227
|
+
#
|
228
|
+
# # The length of the range represented in Content-Range: header.
|
229
|
+
# def range_length
|
230
|
+
# r = content_range() or return nil
|
231
|
+
# r.end - r.begin
|
232
|
+
# end
|
233
|
+
#
|
234
|
+
# # Returns a content type string such as "text/html".
|
235
|
+
# # This method returns nil if Content-Type: header field does not exist.
|
236
|
+
# def content_type
|
237
|
+
# return nil unless main_type()
|
238
|
+
# if sub_type()
|
239
|
+
# "#{main_type()}/#{sub_type()}"
|
240
|
+
# else
|
241
|
+
# main_type()
|
242
|
+
# end
|
243
|
+
# end
|
244
|
+
#
|
245
|
+
# # Returns a content type string such as "text".
|
246
|
+
# # This method returns nil if Content-Type: header field does not exist.
|
247
|
+
# def main_type
|
248
|
+
# return nil unless headers['content-type']
|
249
|
+
# self['Content-Type'].split(';').first.to_s.split('/')[0].to_s.strip
|
250
|
+
# end
|
251
|
+
#
|
252
|
+
# # Returns a content type string such as "html".
|
253
|
+
# # This method returns nil if Content-Type: header field does not exist
|
254
|
+
# # or sub-type is not given (e.g. "Content-Type: text").
|
255
|
+
# def sub_type
|
256
|
+
# return nil unless headers['content-type']
|
257
|
+
# main, sub = *self['Content-Type'].split(';').first.to_s.split('/')
|
258
|
+
# return nil unless sub
|
259
|
+
# sub.strip
|
260
|
+
# end
|
261
|
+
#
|
262
|
+
# # Returns content type parameters as a Hash as like
|
263
|
+
# # {"charset" => "iso-2022-jp"}.
|
264
|
+
# def type_params
|
265
|
+
# result = {}
|
266
|
+
# list = self['Content-Type'].to_s.split(';')
|
267
|
+
# list.shift
|
268
|
+
# list.each do |param|
|
269
|
+
# k, v = *param.split('=', 2)
|
270
|
+
# result[k.strip] = v.strip
|
271
|
+
# end
|
272
|
+
# result
|
273
|
+
# end
|
274
|
+
#
|
275
|
+
# # Set Content-Type: header field by +type+ and +params+.
|
276
|
+
# # +type+ must be a String, +params+ must be a Hash.
|
277
|
+
# def set_content_type(type, params = {})
|
278
|
+
# headers['content-type'] = [type + params.map{|k,v|"; #{k}=#{v}"}.join('')]
|
279
|
+
# end
|
280
|
+
#
|
281
|
+
# alias content_type= set_content_type
|
282
|
+
#
|
283
|
+
# # Set header fields and a body from HTML form data.
|
284
|
+
# # +params+ should be a Hash containing HTML form data.
|
285
|
+
# # Optional argument +sep+ means data record separator.
|
286
|
+
# #
|
287
|
+
# # This method also set Content-Type: header field to
|
288
|
+
# # application/x-www-form-urlencoded.
|
289
|
+
# #
|
290
|
+
# # Example:
|
291
|
+
# # http.form_data = {"q" => "ruby", "lang" => "en"}
|
292
|
+
# # http.form_data = {"q" => ["ruby", "perl"], "lang" => "en"}
|
293
|
+
# # http.set_form_data({"q" => "ruby", "lang" => "en"}, ';')
|
294
|
+
# #
|
295
|
+
# def set_form_data(params, sep = '&')
|
296
|
+
# self.body = params.map {|k, v| encode_kvpair(k, v) }.flatten.join(sep)
|
297
|
+
# self.content_type = 'application/x-www-form-urlencoded'
|
298
|
+
# end
|
299
|
+
#
|
300
|
+
# alias form_data= set_form_data
|
301
|
+
#
|
302
|
+
# def encode_kvpair(k, vs)
|
303
|
+
# Array(vs).map {|v| "#{urlencode(k)}=#{urlencode(v.to_s)}" }
|
304
|
+
# end
|
305
|
+
# private :encode_kvpair
|
306
|
+
#
|
307
|
+
# def urlencode(str)
|
308
|
+
# str.dup.force_encoding('ASCII-8BIT').gsub(/[^a-zA-Z0-9_\.\-]/){'%%%02x' % $&.ord}
|
309
|
+
# end
|
310
|
+
# private :urlencode
|
311
|
+
#
|
312
|
+
# # Set the Authorization: header for "Basic" authorization.
|
313
|
+
# def basic_auth(account, password)
|
314
|
+
# headers['authorization'] = [basic_encode(account, password)]
|
315
|
+
# end
|
316
|
+
#
|
317
|
+
# # Set Proxy-Authorization: header for "Basic" authorization.
|
318
|
+
# def proxy_basic_auth(account, password)
|
319
|
+
# headers['proxy-authorization'] = [basic_encode(account, password)]
|
320
|
+
# end
|
321
|
+
#
|
322
|
+
# def basic_encode(account, password)
|
323
|
+
# 'Basic ' + ["#{account}:#{password}"].pack('m').delete("\r\n")
|
324
|
+
# end
|
325
|
+
# private :basic_encode
|
326
|
+
#
|
327
|
+
# def connection_close?
|
328
|
+
# tokens(headers['connection']).include?('close') or
|
329
|
+
# tokens(headers['proxy-connection']).include?('close')
|
330
|
+
# end
|
331
|
+
#
|
332
|
+
# def connection_keep_alive?
|
333
|
+
# tokens(headers['connection']).include?('keep-alive') or
|
334
|
+
# tokens(headers['proxy-connection']).include?('keep-alive')
|
335
|
+
# end
|
336
|
+
#
|
337
|
+
# def tokens(vals)
|
338
|
+
# return [] unless vals
|
339
|
+
# vals.map {|v| v.split(',') }.flatten\
|
340
|
+
# .reject {|str| str.strip.empty? }\
|
341
|
+
# .map {|tok| tok.strip.downcase }
|
342
|
+
# end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at Http://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
module Wrest
|
13
|
+
module HttpShared
|
14
|
+
module StandardHeaders
|
15
|
+
Connection = 'connection'
|
16
|
+
ContentType = 'content-type'
|
17
|
+
ContentLength = 'content-length'
|
18
|
+
IfNoneMatch = 'if-none-match'
|
19
|
+
Cookie = 'cookie'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at Http://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
module Wrest
|
13
|
+
module HttpShared
|
14
|
+
module StandardTokens
|
15
|
+
Close = 'close'
|
16
|
+
KeepAlive = 'keep-alive'
|
17
|
+
FormEncoded = 'application/x-www-form-urlencoded'
|
18
|
+
ApplicationXml = 'application/xml'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at native://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
module Wrest
|
13
|
+
# Contains functionality that is independent of
|
14
|
+
# the underlying HTTP libs
|
15
|
+
module HttpShared
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'wrest/http_shared/headers'
|
20
|
+
require 'wrest/http_shared/standard_headers'
|
21
|
+
require 'wrest/http_shared/standard_tokens'
|
22
|
+
|
23
|
+
# Set up a shorter convenience API for constants
|
24
|
+
Wrest::H = Wrest::HttpShared::StandardHeaders
|
25
|
+
Wrest::T = Wrest::HttpShared::StandardTokens
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 - 2010 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
begin
|
13
|
+
gem 'multipart-post', '~> 2.0'
|
14
|
+
rescue Gem::LoadError => e
|
15
|
+
Wrest.logger.debug "Multipart Post ~> 2.0 not found. Multipart Post is necessary to be able to post multipart. To install Multipart Post run 'sudo gem install multipart-post'"
|
16
|
+
raise e
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'wrest/native/post_multipart'
|
20
|
+
require 'wrest/native/put_multipart'
|
21
|
+
|
22
|
+
module Wrest
|
23
|
+
# To enable Multipart support, use
|
24
|
+
# require 'wrest/multipart'
|
25
|
+
#
|
26
|
+
# Multipart support is currently only available on Net::Http
|
27
|
+
# It depends on the multipart-post gem being available. To install multipart-post
|
28
|
+
# (sudo) gem install multipart-post
|
29
|
+
#
|
30
|
+
# The methods in this module are mixed into Wrest::Uri.
|
31
|
+
module Multipart
|
32
|
+
# Makes a multipart/form-data encoded POST request to this URI. This is a convenience API
|
33
|
+
# that mimics a multipart form being posted; some allegedly RESTful APIs like FCBK require
|
34
|
+
# this for file uploads.
|
35
|
+
#
|
36
|
+
# File.open('/path/to/image.jpg') do |file|
|
37
|
+
# 'http://localhost:3000/uploads'.to_uri.post_multipart('file' => UploadIO.new(file, "image/jpg", '/path/to/image.jpg'))
|
38
|
+
# end
|
39
|
+
def post_multipart(parameters = {}, headers = {}, &block)
|
40
|
+
Http::PostMultipart.new(self, parameters, headers,
|
41
|
+
block ? @options.merge(callback_block: block) : @options).invoke
|
42
|
+
end
|
43
|
+
|
44
|
+
# Makes a multipart/form-data encoded POST request to this URI. This is a convenience API
|
45
|
+
# that mimics a multipart form being posted; some allegedly RESTful APIs like FCBK require
|
46
|
+
# this for file uploads.
|
47
|
+
#
|
48
|
+
# File.open('/path/to/image.jpg') do |file|
|
49
|
+
# 'http://localhost:3000/uploads'.to_uri.post_multipart_async('file' => UploadIO.new(file, "image/jpg", '/path/to/image.jpg'))
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# Note: post_multipart_async does not return a response and the response should be accessed through callbacks.
|
53
|
+
# This implementation of asynchronous post_multipart is currently in alpha. Hence, it should not be used in production.
|
54
|
+
def post_multipart_async(parameters = {}, headers = {}, &block)
|
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
|
+
)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Makes a multipart/form-data encoded PUT request to this URI. This is a convenience API
|
63
|
+
# that mimics a multipart form being put. I sincerely hope you never need to use this.
|
64
|
+
def put_multipart(parameters = {}, headers = {}, &block)
|
65
|
+
Http::PutMultipart.new(self, parameters, headers,
|
66
|
+
block ? @options.merge(callback_block: block) : @options).invoke
|
67
|
+
end
|
68
|
+
|
69
|
+
# Makes a multipart/form-data encoded PUT request to this URI. This is a convenience API
|
70
|
+
# that mimics a multipart form being put. I sincerely hope you never need to use this.
|
71
|
+
#
|
72
|
+
# Note: put_multipart_async does not return a response and the response should be accessed through callbacks
|
73
|
+
# This implementation of asynchronous put_multipart is currently in alpha. Hence, it should not be used in production.
|
74
|
+
def put_multipart_async(parameters = {}, headers = {}, &block)
|
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)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class Uri
|
82
|
+
include Multipart
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
module Wrest
|
13
|
+
module Native
|
14
|
+
module ConnectionFactory
|
15
|
+
def create_connection(options = { timeout: 60, verify_mode: OpenSSL::SSL::VERIFY_NONE })
|
16
|
+
options[:timeout] ||= 60
|
17
|
+
connection = Net::HTTP.new(host, port)
|
18
|
+
connection.read_timeout = options[:timeout]
|
19
|
+
if https?
|
20
|
+
connection.use_ssl = true
|
21
|
+
connection.verify_mode = options[:verify_mode] || OpenSSL::SSL::VERIFY_PEER
|
22
|
+
connection.ca_path = options[:ca_path] if options[:ca_path]
|
23
|
+
end
|
24
|
+
connection
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright 2009 Sidu Ponnappa
|
4
|
+
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
# you may not use this file except in compliance with the License.
|
7
|
+
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
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.
|
11
|
+
|
12
|
+
module Wrest
|
13
|
+
module Native
|
14
|
+
class Delete < Request
|
15
|
+
def initialize(wrest_uri, parameters = {}, headers = {}, options = {})
|
16
|
+
super(
|
17
|
+
wrest_uri,
|
18
|
+
Net::HTTP::Delete,
|
19
|
+
parameters,
|
20
|
+
nil,
|
21
|
+
headers,
|
22
|
+
options
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|