httparty 0.15.0 → 0.21.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/.editorconfig +18 -0
- data/.github/workflows/ci.yml +26 -0
- data/.gitignore +3 -0
- data/.rubocop_todo.yml +1 -1
- data/{History.md → Changelog.md} +137 -0
- data/Gemfile +8 -1
- data/Guardfile +3 -2
- data/README.md +6 -6
- data/docs/README.md +120 -38
- data/examples/README.md +28 -11
- data/examples/aaws.rb +6 -2
- data/examples/body_stream.rb +14 -0
- data/examples/custom_parsers.rb +4 -0
- data/examples/headers_and_user_agents.rb +7 -3
- data/examples/idn.rb +10 -0
- data/examples/logging.rb +3 -3
- data/examples/microsoft_graph.rb +52 -0
- data/examples/multipart.rb +22 -0
- data/examples/peer_cert.rb +9 -0
- data/examples/stream_download.rb +8 -2
- data/httparty.gemspec +7 -4
- data/lib/httparty/connection_adapter.rb +59 -16
- data/lib/httparty/cookie_hash.rb +10 -8
- data/lib/httparty/decompressor.rb +102 -0
- data/lib/httparty/exceptions.rb +4 -1
- data/lib/httparty/hash_conversions.rb +28 -12
- data/lib/httparty/headers_processor.rb +32 -0
- data/lib/httparty/logger/apache_formatter.rb +31 -6
- data/lib/httparty/logger/curl_formatter.rb +9 -7
- data/lib/httparty/logger/logger.rb +5 -1
- data/lib/httparty/logger/logstash_formatter.rb +61 -0
- data/lib/httparty/module_inheritable_attributes.rb +6 -4
- data/lib/httparty/net_digest_auth.rb +15 -15
- data/lib/httparty/parser.rb +25 -16
- data/lib/httparty/request/body.rb +105 -0
- data/lib/httparty/request/multipart_boundary.rb +13 -0
- data/lib/httparty/request.rb +96 -105
- data/lib/httparty/response/headers.rb +6 -2
- data/lib/httparty/response.rb +59 -8
- data/lib/httparty/response_fragment.rb +21 -0
- data/lib/httparty/text_encoder.rb +72 -0
- data/lib/httparty/utils.rb +13 -0
- data/lib/httparty/version.rb +3 -1
- data/lib/httparty.rb +70 -25
- data/website/css/common.css +1 -1
- metadata +38 -106
- data/.simplecov +0 -1
- data/.travis.yml +0 -8
- data/features/basic_authentication.feature +0 -20
- data/features/command_line.feature +0 -95
- data/features/deals_with_http_error_codes.feature +0 -26
- data/features/digest_authentication.feature +0 -30
- data/features/handles_compressed_responses.feature +0 -27
- data/features/handles_multiple_formats.feature +0 -57
- data/features/steps/env.rb +0 -27
- data/features/steps/httparty_response_steps.rb +0 -56
- data/features/steps/httparty_steps.rb +0 -43
- data/features/steps/mongrel_helper.rb +0 -127
- data/features/steps/remote_service_steps.rb +0 -92
- data/features/supports_read_timeout_option.feature +0 -13
- data/features/supports_redirection.feature +0 -22
- data/features/supports_timeout_option.feature +0 -13
- data/spec/fixtures/delicious.xml +0 -23
- data/spec/fixtures/empty.xml +0 -0
- data/spec/fixtures/google.html +0 -3
- data/spec/fixtures/ssl/generate.sh +0 -29
- data/spec/fixtures/ssl/generated/1fe462c2.0 +0 -1
- data/spec/fixtures/ssl/generated/bogushost.crt +0 -13
- data/spec/fixtures/ssl/generated/ca.crt +0 -16
- data/spec/fixtures/ssl/generated/ca.key +0 -15
- data/spec/fixtures/ssl/generated/selfsigned.crt +0 -14
- data/spec/fixtures/ssl/generated/server.crt +0 -13
- data/spec/fixtures/ssl/generated/server.key +0 -15
- data/spec/fixtures/ssl/openssl-exts.cnf +0 -9
- data/spec/fixtures/twitter.csv +0 -2
- data/spec/fixtures/twitter.json +0 -1
- data/spec/fixtures/twitter.xml +0 -403
- data/spec/fixtures/undefined_method_add_node_for_nil.xml +0 -2
- data/spec/httparty/connection_adapter_spec.rb +0 -495
- data/spec/httparty/cookie_hash_spec.rb +0 -100
- data/spec/httparty/exception_spec.rb +0 -45
- data/spec/httparty/hash_conversions_spec.rb +0 -49
- data/spec/httparty/logger/apache_formatter_spec.rb +0 -41
- data/spec/httparty/logger/curl_formatter_spec.rb +0 -119
- data/spec/httparty/logger/logger_spec.rb +0 -38
- data/spec/httparty/net_digest_auth_spec.rb +0 -268
- data/spec/httparty/parser_spec.rb +0 -178
- data/spec/httparty/request_spec.rb +0 -1244
- data/spec/httparty/response_spec.rb +0 -347
- data/spec/httparty/ssl_spec.rb +0 -74
- data/spec/httparty_spec.rb +0 -877
- data/spec/spec_helper.rb +0 -59
- data/spec/support/ssl_test_helper.rb +0 -47
- data/spec/support/ssl_test_server.rb +0 -80
- data/spec/support/stub_response.rb +0 -49
data/lib/httparty/request.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'erb'
|
2
4
|
|
3
5
|
module HTTParty
|
@@ -13,6 +15,8 @@ module HTTParty
|
|
13
15
|
Net::HTTP::Move,
|
14
16
|
Net::HTTP::Copy,
|
15
17
|
Net::HTTP::Mkcol,
|
18
|
+
Net::HTTP::Lock,
|
19
|
+
Net::HTTP::Unlock,
|
16
20
|
]
|
17
21
|
|
18
22
|
SupportedURISchemes = ['http', 'https', 'webcal', nil]
|
@@ -42,6 +46,15 @@ module HTTParty
|
|
42
46
|
end.flatten.join('&')
|
43
47
|
end
|
44
48
|
|
49
|
+
def self._load(data)
|
50
|
+
http_method, path, options, last_response, last_uri, raw_request = Marshal.load(data)
|
51
|
+
instance = new(http_method, path, options)
|
52
|
+
instance.last_response = last_response
|
53
|
+
instance.last_uri = last_uri
|
54
|
+
instance.instance_variable_set("@raw_request", raw_request)
|
55
|
+
instance
|
56
|
+
end
|
57
|
+
|
45
58
|
attr_accessor :http_method, :options, :last_response, :redirect, :last_uri
|
46
59
|
attr_reader :path
|
47
60
|
|
@@ -60,7 +73,7 @@ module HTTParty
|
|
60
73
|
connection_adapter: ConnectionAdapter
|
61
74
|
}.merge(o)
|
62
75
|
self.path = path
|
63
|
-
set_basic_auth_from_uri
|
76
|
+
set_basic_auth_from_uri
|
64
77
|
end
|
65
78
|
|
66
79
|
def path=(uri)
|
@@ -69,7 +82,7 @@ module HTTParty
|
|
69
82
|
@path = if uri.is_a?(uri_adapter)
|
70
83
|
uri
|
71
84
|
elsif String.try_convert(uri)
|
72
|
-
uri_adapter.parse
|
85
|
+
uri_adapter.parse(uri).normalize
|
73
86
|
else
|
74
87
|
raise ArgumentError,
|
75
88
|
"bad argument (expected #{uri_adapter} object or URI string)"
|
@@ -85,17 +98,17 @@ module HTTParty
|
|
85
98
|
end
|
86
99
|
|
87
100
|
def uri
|
88
|
-
if redirect && path.relative? && path.path[0] !=
|
89
|
-
last_uri_host = @last_uri.path.gsub(/[^\/]+$/,
|
101
|
+
if redirect && path.relative? && path.path[0] != '/'
|
102
|
+
last_uri_host = @last_uri.path.gsub(/[^\/]+$/, '')
|
90
103
|
|
91
|
-
path.path = "/#{path.path}" if last_uri_host[-1] !=
|
92
|
-
path.path = last_uri_host
|
104
|
+
path.path = "/#{path.path}" if last_uri_host[-1] != '/'
|
105
|
+
path.path = "#{last_uri_host}#{path.path}"
|
93
106
|
end
|
94
107
|
|
95
108
|
if path.relative? && path.host
|
96
|
-
new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}")
|
109
|
+
new_uri = options[:uri_adapter].parse("#{@last_uri.scheme}:#{path}").normalize
|
97
110
|
elsif path.relative?
|
98
|
-
new_uri = options[:uri_adapter].parse("#{base_uri}#{path}")
|
111
|
+
new_uri = options[:uri_adapter].parse("#{base_uri}#{path}").normalize
|
99
112
|
else
|
100
113
|
new_uri = path.clone
|
101
114
|
end
|
@@ -115,7 +128,7 @@ module HTTParty
|
|
115
128
|
def base_uri
|
116
129
|
if redirect
|
117
130
|
base_uri = "#{@last_uri.scheme}://#{@last_uri.host}"
|
118
|
-
base_uri
|
131
|
+
base_uri = "#{base_uri}:#{@last_uri.port}" if @last_uri.port != 80
|
119
132
|
base_uri
|
120
133
|
else
|
121
134
|
options[:base_uri] && HTTParty.normalize_base_uri(options[:base_uri])
|
@@ -138,31 +151,32 @@ module HTTParty
|
|
138
151
|
validate
|
139
152
|
setup_raw_request
|
140
153
|
chunked_body = nil
|
154
|
+
current_http = http
|
141
155
|
|
142
|
-
self.last_response =
|
156
|
+
self.last_response = current_http.request(@raw_request) do |http_response|
|
143
157
|
if block
|
144
158
|
chunks = []
|
145
159
|
|
146
160
|
http_response.read_body do |fragment|
|
147
|
-
|
148
|
-
|
161
|
+
encoded_fragment = encode_text(fragment, http_response['content-type'])
|
162
|
+
chunks << encoded_fragment if !options[:stream_body]
|
163
|
+
block.call ResponseFragment.new(encoded_fragment, http_response, current_http)
|
149
164
|
end
|
150
165
|
|
151
166
|
chunked_body = chunks.join
|
152
167
|
end
|
153
168
|
end
|
154
|
-
|
155
|
-
|
169
|
+
|
156
170
|
handle_host_redirection if response_redirects?
|
157
171
|
result = handle_unauthorized
|
158
172
|
result ||= handle_response(chunked_body, &block)
|
159
|
-
result
|
173
|
+
result
|
160
174
|
end
|
161
175
|
|
162
176
|
def handle_unauthorized(&block)
|
163
177
|
return unless digest_auth? && response_unauthorized? && response_has_digest_auth_challenge?
|
164
178
|
return if @credentials_sent
|
165
|
-
@credentials_sent = true
|
179
|
+
@credentials_sent = true
|
166
180
|
perform(&block)
|
167
181
|
end
|
168
182
|
|
@@ -170,16 +184,19 @@ module HTTParty
|
|
170
184
|
@raw_request.body
|
171
185
|
end
|
172
186
|
|
187
|
+
def _dump(_level)
|
188
|
+
opts = options.dup
|
189
|
+
opts.delete(:logger)
|
190
|
+
opts.delete(:parser) if opts[:parser] && opts[:parser].is_a?(Proc)
|
191
|
+
Marshal.dump([http_method, path, opts, last_response, @last_uri, @raw_request])
|
192
|
+
end
|
193
|
+
|
173
194
|
private
|
174
195
|
|
175
196
|
def http
|
176
197
|
connection_adapter.call(uri, options)
|
177
198
|
end
|
178
199
|
|
179
|
-
def body
|
180
|
-
options[:body].respond_to?(:to_hash) ? normalize_query(options[:body]) : options[:body]
|
181
|
-
end
|
182
|
-
|
183
200
|
def credentials
|
184
201
|
(options[:basic_auth] || options[:digest_auth]).to_hash
|
185
202
|
end
|
@@ -205,25 +222,35 @@ module HTTParty
|
|
205
222
|
end
|
206
223
|
|
207
224
|
def setup_raw_request
|
208
|
-
@raw_request = http_method.new(request_uri(uri))
|
209
|
-
@raw_request.body = body if body
|
210
|
-
@raw_request.body_stream = options[:body_stream] if options[:body_stream]
|
211
225
|
if options[:headers].respond_to?(:to_hash)
|
212
226
|
headers_hash = options[:headers].to_hash
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
227
|
+
else
|
228
|
+
headers_hash = nil
|
229
|
+
end
|
230
|
+
|
231
|
+
@raw_request = http_method.new(request_uri(uri), headers_hash)
|
232
|
+
@raw_request.body_stream = options[:body_stream] if options[:body_stream]
|
233
|
+
|
234
|
+
if options[:body]
|
235
|
+
body = Body.new(
|
236
|
+
options[:body],
|
237
|
+
query_string_normalizer: query_string_normalizer,
|
238
|
+
force_multipart: options[:multipart]
|
239
|
+
)
|
240
|
+
|
241
|
+
if body.multipart?
|
242
|
+
content_type = "multipart/form-data; boundary=#{body.boundary}"
|
243
|
+
@raw_request['Content-Type'] = content_type
|
221
244
|
end
|
245
|
+
@raw_request.body = body.call
|
222
246
|
end
|
223
|
-
|
247
|
+
|
248
|
+
@raw_request.instance_variable_set(:@decode_content, decompress_content?)
|
249
|
+
|
250
|
+
if options[:basic_auth] && send_authorization_header?
|
224
251
|
@raw_request.basic_auth(username, password)
|
225
252
|
@credentials_sent = true
|
226
|
-
end
|
253
|
+
end
|
227
254
|
setup_digest_auth if digest_auth? && response_unauthorized? && response_has_digest_auth_challenge?
|
228
255
|
end
|
229
256
|
|
@@ -231,6 +258,10 @@ module HTTParty
|
|
231
258
|
!!options[:digest_auth]
|
232
259
|
end
|
233
260
|
|
261
|
+
def decompress_content?
|
262
|
+
!options[:skip_decompression]
|
263
|
+
end
|
264
|
+
|
234
265
|
def response_unauthorized?
|
235
266
|
!!last_response && last_response.code == '401'
|
236
267
|
end
|
@@ -240,7 +271,7 @@ module HTTParty
|
|
240
271
|
end
|
241
272
|
|
242
273
|
def setup_digest_auth
|
243
|
-
@raw_request.digest_auth(username, password, last_response)
|
274
|
+
@raw_request.digest_auth(username, password, last_response)
|
244
275
|
end
|
245
276
|
|
246
277
|
def query_string(uri)
|
@@ -254,78 +285,15 @@ module HTTParty
|
|
254
285
|
query_string_parts << options[:query] unless options[:query].nil?
|
255
286
|
end
|
256
287
|
|
257
|
-
query_string_parts.reject!(&:empty?) unless query_string_parts == [
|
288
|
+
query_string_parts.reject!(&:empty?) unless query_string_parts == ['']
|
258
289
|
query_string_parts.size > 0 ? query_string_parts.join('&') : nil
|
259
290
|
end
|
260
291
|
|
261
|
-
def get_charset
|
262
|
-
content_type = last_response["content-type"]
|
263
|
-
if content_type.nil?
|
264
|
-
return nil
|
265
|
-
end
|
266
|
-
|
267
|
-
if content_type =~ /;\s*charset\s*=\s*([^=,;"\s]+)/i
|
268
|
-
return $1
|
269
|
-
end
|
270
|
-
|
271
|
-
if content_type =~ /;\s*charset\s*=\s*"((\\.|[^\\"])+)"/i
|
272
|
-
return $1.gsub(/\\(.)/, '\1')
|
273
|
-
end
|
274
|
-
|
275
|
-
nil
|
276
|
-
end
|
277
|
-
|
278
|
-
def encode_with_ruby_encoding(body, charset)
|
279
|
-
if Encoding.name_list.include?(charset)
|
280
|
-
body.force_encoding(charset)
|
281
|
-
else
|
282
|
-
body
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
292
|
def assume_utf16_is_big_endian
|
287
293
|
options[:assume_utf16_is_big_endian]
|
288
294
|
end
|
289
295
|
|
290
|
-
def
|
291
|
-
if body.bytesize >= 2
|
292
|
-
if body.getbyte(0) == 0xFF && body.getbyte(1) == 0xFE
|
293
|
-
return body.force_encoding("UTF-16LE")
|
294
|
-
elsif body.getbyte(0) == 0xFE && body.getbyte(1) == 0xFF
|
295
|
-
return body.force_encoding("UTF-16BE")
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
if assume_utf16_is_big_endian
|
300
|
-
body.force_encoding("UTF-16BE")
|
301
|
-
else
|
302
|
-
body.force_encoding("UTF-16LE")
|
303
|
-
end
|
304
|
-
end
|
305
|
-
|
306
|
-
def _encode_body(body)
|
307
|
-
charset = get_charset
|
308
|
-
|
309
|
-
if charset.nil?
|
310
|
-
return body
|
311
|
-
end
|
312
|
-
|
313
|
-
if "utf-16".casecmp(charset) == 0
|
314
|
-
encode_utf_16(body)
|
315
|
-
else
|
316
|
-
encode_with_ruby_encoding(body, charset)
|
317
|
-
end
|
318
|
-
end
|
319
|
-
|
320
|
-
def encode_body(body)
|
321
|
-
if "".respond_to?(:encoding)
|
322
|
-
_encode_body(body)
|
323
|
-
else
|
324
|
-
body
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
def handle_response(body, &block)
|
296
|
+
def handle_response(raw_body, &block)
|
329
297
|
if response_redirects?
|
330
298
|
options[:limit] -= 1
|
331
299
|
if options[:logger]
|
@@ -346,15 +314,26 @@ module HTTParty
|
|
346
314
|
capture_cookies(last_response)
|
347
315
|
perform(&block)
|
348
316
|
else
|
349
|
-
|
350
|
-
|
351
|
-
|
317
|
+
raw_body ||= last_response.body
|
318
|
+
|
319
|
+
body = decompress(raw_body, last_response['content-encoding']) unless raw_body.nil?
|
320
|
+
|
321
|
+
unless body.nil?
|
322
|
+
body = encode_text(body, last_response['content-type'])
|
323
|
+
|
324
|
+
if decompress_content?
|
325
|
+
last_response.delete('content-encoding')
|
326
|
+
raw_body = body
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
Response.new(self, last_response, lambda { parse_response(body) }, body: raw_body)
|
352
331
|
end
|
353
332
|
end
|
354
333
|
|
355
334
|
def handle_host_redirection
|
356
335
|
check_duplicate_location_header
|
357
|
-
redirect_path = options[:uri_adapter].parse
|
336
|
+
redirect_path = options[:uri_adapter].parse(last_response['location']).normalize
|
358
337
|
return if redirect_path.relative? || path.host == redirect_path.host
|
359
338
|
@changed_hosts = true
|
360
339
|
end
|
@@ -367,7 +346,7 @@ module HTTParty
|
|
367
346
|
end
|
368
347
|
|
369
348
|
def send_authorization_header?
|
370
|
-
!@changed_hosts
|
349
|
+
!@changed_hosts
|
371
350
|
end
|
372
351
|
|
373
352
|
def response_redirects?
|
@@ -388,7 +367,7 @@ module HTTParty
|
|
388
367
|
cookies_hash = HTTParty::CookieHash.new
|
389
368
|
cookies_hash.add_cookies(options[:headers].to_hash['Cookie']) if options[:headers] && options[:headers].to_hash['Cookie']
|
390
369
|
response.get_fields('Set-Cookie').each { |cookie| cookies_hash.add_cookies(cookie) }
|
391
|
-
|
370
|
+
|
392
371
|
options[:headers] ||= {}
|
393
372
|
options[:headers]['Cookie'] = cookies_hash.to_cookie_string
|
394
373
|
end
|
@@ -423,5 +402,17 @@ module HTTParty
|
|
423
402
|
@credentials_sent = true
|
424
403
|
end
|
425
404
|
end
|
405
|
+
|
406
|
+
def decompress(body, encoding)
|
407
|
+
Decompressor.new(body, encoding).decompress
|
408
|
+
end
|
409
|
+
|
410
|
+
def encode_text(text, content_type)
|
411
|
+
TextEncoder.new(
|
412
|
+
text,
|
413
|
+
content_type: content_type,
|
414
|
+
assume_utf16_is_big_endian: assume_utf16_is_big_endian
|
415
|
+
).call
|
416
|
+
end
|
426
417
|
end
|
427
418
|
end
|
@@ -1,3 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'delegate'
|
4
|
+
|
1
5
|
module HTTParty
|
2
6
|
class Response #:nodoc:
|
3
7
|
class Headers < ::SimpleDelegator
|
@@ -20,10 +24,10 @@ module HTTParty
|
|
20
24
|
end
|
21
25
|
|
22
26
|
def ==(other)
|
23
|
-
if other.is_a?(::Net::HTTPHeader)
|
27
|
+
if other.is_a?(::Net::HTTPHeader)
|
24
28
|
@header == other.instance_variable_get(:@header)
|
25
29
|
elsif other.is_a?(Hash)
|
26
|
-
@header == other || @header == Headers.new(other).instance_variable_get(:@header)
|
30
|
+
@header == other || @header == Headers.new(other).instance_variable_get(:@header)
|
27
31
|
end
|
28
32
|
end
|
29
33
|
end
|
data/lib/httparty/response.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module HTTParty
|
2
4
|
class Response < Object
|
3
5
|
def self.underscore(string)
|
4
6
|
string.gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z])([A-Z])/, '\1_\2').downcase
|
5
7
|
end
|
6
8
|
|
9
|
+
def self._load(data)
|
10
|
+
req, resp, parsed_resp, resp_body = Marshal.load(data)
|
11
|
+
|
12
|
+
new(req, resp, -> { parsed_resp }, body: resp_body)
|
13
|
+
end
|
14
|
+
|
7
15
|
attr_reader :request, :response, :body, :headers
|
8
16
|
|
9
17
|
def initialize(request, response, parsed_block, options = {})
|
@@ -14,7 +22,11 @@ module HTTParty
|
|
14
22
|
@headers = Headers.new(response.to_hash)
|
15
23
|
|
16
24
|
if request.options[:logger]
|
17
|
-
logger = ::HTTParty::Logger.build(
|
25
|
+
logger = ::HTTParty::Logger.build(
|
26
|
+
request.options[:logger],
|
27
|
+
request.options[:log_level],
|
28
|
+
request.options[:log_format]
|
29
|
+
)
|
18
30
|
logger.format(request, self)
|
19
31
|
end
|
20
32
|
|
@@ -29,20 +41,24 @@ module HTTParty
|
|
29
41
|
response.code.to_i
|
30
42
|
end
|
31
43
|
|
44
|
+
def http_version
|
45
|
+
response.http_version
|
46
|
+
end
|
47
|
+
|
32
48
|
def tap
|
33
49
|
yield self
|
34
50
|
self
|
35
51
|
end
|
36
52
|
|
37
53
|
def inspect
|
38
|
-
inspect_id = ::Kernel::format
|
54
|
+
inspect_id = ::Kernel::format '%x', (object_id * 2)
|
39
55
|
%(#<#{self.class}:0x#{inspect_id} parsed_response=#{parsed_response.inspect}, @response=#{response.inspect}, @headers=#{headers.inspect}>)
|
40
56
|
end
|
41
57
|
|
42
58
|
CODES_TO_OBJ = ::Net::HTTPResponse::CODE_CLASS_TO_OBJ.merge ::Net::HTTPResponse::CODE_TO_OBJ
|
43
59
|
|
44
60
|
CODES_TO_OBJ.each do |response_code, klass|
|
45
|
-
name = klass.name.sub(
|
61
|
+
name = klass.name.sub('Net::HTTP', '')
|
46
62
|
name = "#{underscore(name)}?".to_sym
|
47
63
|
|
48
64
|
define_method(name) do
|
@@ -51,28 +67,46 @@ module HTTParty
|
|
51
67
|
end
|
52
68
|
|
53
69
|
# Support old multiple_choice? method from pre 2.0.0 era.
|
54
|
-
if ::RUBY_VERSION >=
|
70
|
+
if ::RUBY_VERSION >= '2.0.0' && ::RUBY_PLATFORM != 'java'
|
55
71
|
alias_method :multiple_choice?, :multiple_choices?
|
56
72
|
end
|
57
73
|
|
74
|
+
# Support old status codes method from pre 2.6.0 era.
|
75
|
+
if ::RUBY_VERSION >= '2.6.0' && ::RUBY_PLATFORM != 'java'
|
76
|
+
alias_method :gateway_time_out?, :gateway_timeout?
|
77
|
+
alias_method :request_entity_too_large?, :payload_too_large?
|
78
|
+
alias_method :request_time_out?, :request_timeout?
|
79
|
+
alias_method :request_uri_too_long?, :uri_too_long?
|
80
|
+
alias_method :requested_range_not_satisfiable?, :range_not_satisfiable?
|
81
|
+
end
|
82
|
+
|
58
83
|
def nil?
|
84
|
+
warn_about_nil_deprecation
|
59
85
|
response.nil? || response.body.nil? || response.body.empty?
|
60
86
|
end
|
61
87
|
|
62
|
-
def to_s
|
88
|
+
def to_s
|
63
89
|
if !response.nil? && !response.body.nil? && response.body.respond_to?(:to_s)
|
64
90
|
response.body.to_s
|
65
|
-
else
|
91
|
+
else
|
66
92
|
inspect
|
67
93
|
end
|
68
94
|
end
|
69
95
|
|
96
|
+
def pretty_print(pp)
|
97
|
+
if !parsed_response.nil? && parsed_response.respond_to?(:pretty_print)
|
98
|
+
parsed_response.pretty_print(pp)
|
99
|
+
else
|
100
|
+
super
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
70
104
|
def display(port=$>)
|
71
105
|
if !parsed_response.nil? && parsed_response.respond_to?(:display)
|
72
106
|
parsed_response.display(port)
|
73
107
|
elsif !response.nil? && !response.body.nil? && response.body.respond_to?(:display)
|
74
108
|
response.body.display(port)
|
75
|
-
else
|
109
|
+
else
|
76
110
|
port.write(inspect)
|
77
111
|
end
|
78
112
|
end
|
@@ -81,7 +115,11 @@ module HTTParty
|
|
81
115
|
return true if super
|
82
116
|
parsed_response.respond_to?(name) || response.respond_to?(name)
|
83
117
|
end
|
84
|
-
|
118
|
+
|
119
|
+
def _dump(_level)
|
120
|
+
Marshal.dump([request, response, parsed_response, body])
|
121
|
+
end
|
122
|
+
|
85
123
|
protected
|
86
124
|
|
87
125
|
def method_missing(name, *args, &block)
|
@@ -99,6 +137,19 @@ module HTTParty
|
|
99
137
|
::Kernel.raise ::HTTParty::ResponseError.new(@response), "Code #{code} - #{body}"
|
100
138
|
end
|
101
139
|
end
|
140
|
+
|
141
|
+
private
|
142
|
+
|
143
|
+
def warn_about_nil_deprecation
|
144
|
+
trace_line = caller.reject { |line| line.include?('httparty') }.first
|
145
|
+
warning = "[DEPRECATION] HTTParty will no longer override `response#nil?`. " \
|
146
|
+
"This functionality will be removed in future versions. " \
|
147
|
+
"Please, add explicit check `response.body.nil? || response.body.empty?`. " \
|
148
|
+
"For more info refer to: https://github.com/jnunemaker/httparty/issues/568\n" \
|
149
|
+
"#{trace_line}"
|
150
|
+
|
151
|
+
warn(warning)
|
152
|
+
end
|
102
153
|
end
|
103
154
|
end
|
104
155
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'delegate'
|
4
|
+
|
5
|
+
module HTTParty
|
6
|
+
# Allow access to http_response and code by delegation on fragment
|
7
|
+
class ResponseFragment < SimpleDelegator
|
8
|
+
attr_reader :http_response, :connection
|
9
|
+
|
10
|
+
def code
|
11
|
+
@http_response.code.to_i
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(fragment, http_response, connection)
|
15
|
+
@fragment = fragment
|
16
|
+
@http_response = http_response
|
17
|
+
@connection = connection
|
18
|
+
super fragment
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
class TextEncoder
|
5
|
+
attr_reader :text, :content_type, :assume_utf16_is_big_endian
|
6
|
+
|
7
|
+
def initialize(text, assume_utf16_is_big_endian: true, content_type: nil)
|
8
|
+
@text = +text
|
9
|
+
@content_type = content_type
|
10
|
+
@assume_utf16_is_big_endian = assume_utf16_is_big_endian
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
if can_encode?
|
15
|
+
encoded_text
|
16
|
+
else
|
17
|
+
text
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def can_encode?
|
24
|
+
''.respond_to?(:encoding) && charset
|
25
|
+
end
|
26
|
+
|
27
|
+
def encoded_text
|
28
|
+
if 'utf-16'.casecmp(charset) == 0
|
29
|
+
encode_utf_16
|
30
|
+
else
|
31
|
+
encode_with_ruby_encoding
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def encode_utf_16
|
36
|
+
if text.bytesize >= 2
|
37
|
+
if text.getbyte(0) == 0xFF && text.getbyte(1) == 0xFE
|
38
|
+
return text.force_encoding('UTF-16LE')
|
39
|
+
elsif text.getbyte(0) == 0xFE && text.getbyte(1) == 0xFF
|
40
|
+
return text.force_encoding('UTF-16BE')
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if assume_utf16_is_big_endian # option
|
45
|
+
text.force_encoding('UTF-16BE')
|
46
|
+
else
|
47
|
+
text.force_encoding('UTF-16LE')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def encode_with_ruby_encoding
|
52
|
+
# NOTE: This will raise an argument error if the
|
53
|
+
# charset does not exist
|
54
|
+
encoding = Encoding.find(charset)
|
55
|
+
text.force_encoding(encoding.to_s)
|
56
|
+
rescue ArgumentError
|
57
|
+
text
|
58
|
+
end
|
59
|
+
|
60
|
+
def charset
|
61
|
+
return nil if content_type.nil?
|
62
|
+
|
63
|
+
if (matchdata = content_type.match(/;\s*charset\s*=\s*([^=,;"\s]+)/i))
|
64
|
+
return matchdata.captures.first
|
65
|
+
end
|
66
|
+
|
67
|
+
if (matchdata = content_type.match(/;\s*charset\s*=\s*"((\\.|[^\\"])+)"/i))
|
68
|
+
return matchdata.captures.first.gsub(/\\(.)/, '\1')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
module Utils
|
5
|
+
def self.stringify_keys(hash)
|
6
|
+
return hash.transform_keys(&:to_s) if hash.respond_to?(:transform_keys)
|
7
|
+
|
8
|
+
hash.each_with_object({}) do |(key, value), new_hash|
|
9
|
+
new_hash[key.to_s] = value
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/httparty/version.rb
CHANGED