httparty 0.15.4 → 0.20.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of httparty might be problematic. Click here for more details.

Files changed (93) hide show
  1. checksums.yaml +5 -5
  2. data/.editorconfig +18 -0
  3. data/.github/workflows/ci.yml +23 -0
  4. data/.gitignore +2 -0
  5. data/.rubocop_todo.yml +1 -1
  6. data/Changelog.md +105 -0
  7. data/Gemfile +6 -1
  8. data/README.md +6 -6
  9. data/docs/README.md +100 -38
  10. data/examples/README.md +28 -11
  11. data/examples/aaws.rb +6 -2
  12. data/examples/body_stream.rb +14 -0
  13. data/examples/custom_parsers.rb +4 -0
  14. data/examples/headers_and_user_agents.rb +7 -3
  15. data/examples/idn.rb +10 -0
  16. data/examples/logging.rb +3 -3
  17. data/examples/microsoft_graph.rb +52 -0
  18. data/examples/multipart.rb +22 -0
  19. data/examples/peer_cert.rb +9 -0
  20. data/examples/stream_download.rb +8 -2
  21. data/httparty.gemspec +3 -3
  22. data/lib/httparty/connection_adapter.rb +59 -16
  23. data/lib/httparty/cookie_hash.rb +10 -8
  24. data/lib/httparty/decompressor.rb +92 -0
  25. data/lib/httparty/exceptions.rb +4 -1
  26. data/lib/httparty/hash_conversions.rb +28 -12
  27. data/lib/httparty/headers_processor.rb +32 -0
  28. data/lib/httparty/logger/apache_formatter.rb +31 -6
  29. data/lib/httparty/logger/curl_formatter.rb +9 -7
  30. data/lib/httparty/logger/logger.rb +5 -1
  31. data/lib/httparty/logger/logstash_formatter.rb +61 -0
  32. data/lib/httparty/module_inheritable_attributes.rb +6 -4
  33. data/lib/httparty/net_digest_auth.rb +15 -15
  34. data/lib/httparty/parser.rb +22 -16
  35. data/lib/httparty/request/body.rb +98 -0
  36. data/lib/httparty/request/multipart_boundary.rb +13 -0
  37. data/lib/httparty/request.rb +82 -95
  38. data/lib/httparty/response/headers.rb +4 -2
  39. data/lib/httparty/response.rb +59 -8
  40. data/lib/httparty/response_fragment.rb +21 -0
  41. data/lib/httparty/text_encoder.rb +72 -0
  42. data/lib/httparty/utils.rb +13 -0
  43. data/lib/httparty/version.rb +3 -1
  44. data/lib/httparty.rb +70 -24
  45. data/website/css/common.css +1 -1
  46. metadata +35 -100
  47. data/.travis.yml +0 -8
  48. data/features/basic_authentication.feature +0 -20
  49. data/features/command_line.feature +0 -95
  50. data/features/deals_with_http_error_codes.feature +0 -26
  51. data/features/digest_authentication.feature +0 -30
  52. data/features/handles_compressed_responses.feature +0 -27
  53. data/features/handles_multiple_formats.feature +0 -57
  54. data/features/steps/env.rb +0 -27
  55. data/features/steps/httparty_response_steps.rb +0 -56
  56. data/features/steps/httparty_steps.rb +0 -43
  57. data/features/steps/mongrel_helper.rb +0 -127
  58. data/features/steps/remote_service_steps.rb +0 -92
  59. data/features/supports_read_timeout_option.feature +0 -13
  60. data/features/supports_redirection.feature +0 -22
  61. data/features/supports_timeout_option.feature +0 -13
  62. data/spec/fixtures/delicious.xml +0 -23
  63. data/spec/fixtures/empty.xml +0 -0
  64. data/spec/fixtures/google.html +0 -3
  65. data/spec/fixtures/ssl/generate.sh +0 -29
  66. data/spec/fixtures/ssl/generated/bogushost.crt +0 -13
  67. data/spec/fixtures/ssl/generated/ca.crt +0 -16
  68. data/spec/fixtures/ssl/generated/ca.key +0 -15
  69. data/spec/fixtures/ssl/generated/selfsigned.crt +0 -14
  70. data/spec/fixtures/ssl/generated/server.crt +0 -13
  71. data/spec/fixtures/ssl/generated/server.key +0 -15
  72. data/spec/fixtures/ssl/openssl-exts.cnf +0 -9
  73. data/spec/fixtures/twitter.csv +0 -2
  74. data/spec/fixtures/twitter.json +0 -1
  75. data/spec/fixtures/twitter.xml +0 -403
  76. data/spec/fixtures/undefined_method_add_node_for_nil.xml +0 -2
  77. data/spec/httparty/connection_adapter_spec.rb +0 -495
  78. data/spec/httparty/cookie_hash_spec.rb +0 -100
  79. data/spec/httparty/exception_spec.rb +0 -45
  80. data/spec/httparty/hash_conversions_spec.rb +0 -49
  81. data/spec/httparty/logger/apache_formatter_spec.rb +0 -41
  82. data/spec/httparty/logger/curl_formatter_spec.rb +0 -119
  83. data/spec/httparty/logger/logger_spec.rb +0 -38
  84. data/spec/httparty/net_digest_auth_spec.rb +0 -268
  85. data/spec/httparty/parser_spec.rb +0 -185
  86. data/spec/httparty/request_spec.rb +0 -1251
  87. data/spec/httparty/response_spec.rb +0 -347
  88. data/spec/httparty/ssl_spec.rb +0 -74
  89. data/spec/httparty_spec.rb +0 -877
  90. data/spec/spec_helper.rb +0 -59
  91. data/spec/support/ssl_test_helper.rb +0 -47
  92. data/spec/support/ssl_test_server.rb +0 -80
  93. data/spec/support/stub_response.rb +0 -49
@@ -1,347 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
-
3
- RSpec.describe HTTParty::Response do
4
- before do
5
- @last_modified = Date.new(2010, 1, 15).to_s
6
- @content_length = '1024'
7
- @request_object = HTTParty::Request.new Net::HTTP::Get, '/'
8
- @response_object = Net::HTTPOK.new('1.1', 200, 'OK')
9
- allow(@response_object).to receive_messages(body: "{foo:'bar'}")
10
- @response_object['last-modified'] = @last_modified
11
- @response_object['content-length'] = @content_length
12
- @parsed_response = lambda { {"foo" => "bar"} }
13
- @response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
14
- end
15
-
16
- describe ".underscore" do
17
- it "works with one capitalized word" do
18
- expect(HTTParty::Response.underscore("Accepted")).to eq("accepted")
19
- end
20
-
21
- it "works with titlecase" do
22
- expect(HTTParty::Response.underscore("BadGateway")).to eq("bad_gateway")
23
- end
24
-
25
- it "works with all caps" do
26
- expect(HTTParty::Response.underscore("OK")).to eq("ok")
27
- end
28
- end
29
-
30
- describe "initialization" do
31
- it "should set the Net::HTTP Response" do
32
- expect(@response.response).to eq(@response_object)
33
- end
34
-
35
- it "should set body" do
36
- expect(@response.body).to eq(@response_object.body)
37
- end
38
-
39
- it "should set code" do
40
- expect(@response.code).to eq(@response_object.code)
41
- end
42
-
43
- it "should set code as a Fixnum" do
44
- expect(@response.code).to be_an_instance_of(Fixnum)
45
- end
46
-
47
- context 'when raise_on is supplied' do
48
- let(:request) { HTTParty::Request.new(Net::HTTP::Get, '/', raise_on: [404]) }
49
-
50
- context "and response's status code is in range" do
51
- let(:body) { 'Not Found' }
52
- let(:response) { Net::HTTPNotFound.new('1.1', 404, body) }
53
-
54
- before do
55
- allow(response).to receive(:body).and_return(body)
56
- end
57
-
58
- subject { described_class.new(request, response, @parsed_response) }
59
-
60
- it 'throws exception' do
61
- expect{ subject }.to raise_error(HTTParty::ResponseError, "Code 404 - #{body}")
62
- end
63
- end
64
-
65
- context "and response's status code is not in range" do
66
- subject { described_class.new(request, @response_object, @parsed_response) }
67
-
68
- it 'does not throw exception' do
69
- expect{ subject }.not_to raise_error(HTTParty::ResponseError)
70
- end
71
- end
72
- end
73
- end
74
-
75
- it 'does raise an error about itself when using #method' do
76
- expect {
77
- HTTParty::Response.new(@request_object, @response_object, @parsed_response).method(:qux)
78
- }.to raise_error(NameError, /HTTParty\:\:Response/)
79
- end
80
-
81
- it 'does raise an error about itself when invoking a method that does not exist' do
82
- expect {
83
- HTTParty::Response.new(@request_object, @response_object, @parsed_response).qux
84
- }.to raise_error(NoMethodError, /HTTParty\:\:Response/)
85
- end
86
-
87
- it "returns response headers" do
88
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
89
- expect(response.headers).to eq({'last-modified' => [@last_modified], 'content-length' => [@content_length]})
90
- end
91
-
92
- it "should send missing methods to delegate" do
93
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
94
- expect(response['foo']).to eq('bar')
95
- end
96
-
97
- it "response to request" do
98
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
99
- expect(response.respond_to?(:request)).to be_truthy
100
- end
101
-
102
- it "responds to response" do
103
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
104
- expect(response.respond_to?(:response)).to be_truthy
105
- end
106
-
107
- it "responds to body" do
108
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
109
- expect(response.respond_to?(:body)).to be_truthy
110
- end
111
-
112
- it "responds to headers" do
113
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
114
- expect(response.respond_to?(:headers)).to be_truthy
115
- end
116
-
117
- it "responds to parsed_response" do
118
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
119
- expect(response.respond_to?(:parsed_response)).to be_truthy
120
- end
121
-
122
- it "responds to predicates" do
123
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
124
- expect(response.respond_to?(:success?)).to be_truthy
125
- end
126
-
127
- it "responds to anything parsed_response responds to" do
128
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
129
- expect(response.respond_to?(:[])).to be_truthy
130
- end
131
-
132
- context 'response is array' do
133
- let(:response_value) { [{'foo' => 'bar'}, {'foo' => 'baz'}] }
134
- let(:response) { HTTParty::Response.new(@request_object, @response_object, lambda { response_value }) }
135
- it "should be able to iterate" do
136
- expect(response.size).to eq(2)
137
- expect {
138
- response.each { |item| }
139
- }.to_not raise_error
140
- end
141
-
142
- it 'should respond to array methods' do
143
- expect(response).to respond_to(:bsearch, :compact, :cycle, :delete, :each, :flatten, :flatten!, :compact, :join)
144
- end
145
-
146
- it 'should equal the string response object body' do
147
- expect(response.to_s).to eq(@response_object.body.to_s)
148
- end
149
-
150
- it 'should display the same as an array' do
151
- a = StringIO.new
152
- b = StringIO.new
153
- response_value.display(b)
154
- response.display(a)
155
-
156
- expect(a.string).to eq(b.string)
157
- end
158
- end
159
-
160
- it "allows headers to be accessed by mixed-case names in hash notation" do
161
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
162
- expect(response.headers['Content-LENGTH']).to eq(@content_length)
163
- end
164
-
165
- it "returns a comma-delimited value when multiple values exist" do
166
- @response_object.add_field 'set-cookie', 'csrf_id=12345; path=/'
167
- @response_object.add_field 'set-cookie', '_github_ses=A123CdE; path=/'
168
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
169
- expect(response.headers['set-cookie']).to eq("csrf_id=12345; path=/, _github_ses=A123CdE; path=/")
170
- end
171
-
172
- # Backwards-compatibility - previously, #headers returned a Hash
173
- it "responds to hash methods" do
174
- response = HTTParty::Response.new(@request_object, @response_object, @parsed_response)
175
- hash_methods = {}.methods - response.headers.methods
176
- hash_methods.each do |method_name|
177
- expect(response.headers.respond_to?(method_name)).to be_truthy
178
- end
179
- end
180
-
181
- describe "#is_a?" do
182
- subject { HTTParty::Response.new(@request_object, @response_object, @parsed_response) }
183
-
184
- it { is_expected.to respond_to(:is_a?).with(1).arguments }
185
- it { expect(subject.is_a?(HTTParty::Response)).to be_truthy }
186
- it { expect(subject.is_a?(Object)).to be_truthy }
187
- end
188
-
189
- describe "#kind_of?" do
190
- subject { HTTParty::Response.new(@request_object, @response_object, @parsed_response) }
191
-
192
- it { is_expected.to respond_to(:kind_of?).with(1).arguments }
193
- it { expect(subject.kind_of?(HTTParty::Response)).to be_truthy }
194
- it { expect(subject.kind_of?(Object)).to be_truthy }
195
- end
196
-
197
- describe "semantic methods for response codes" do
198
- def response_mock(klass)
199
- response = klass.new('', '', '')
200
- allow(response).to receive(:body)
201
- response
202
- end
203
-
204
- context "major codes" do
205
- it "is information" do
206
- net_response = response_mock(Net::HTTPInformation)
207
- response = HTTParty::Response.new(@request_object, net_response, '')
208
- expect(response.information?).to be_truthy
209
- end
210
-
211
- it "is success" do
212
- net_response = response_mock(Net::HTTPSuccess)
213
- response = HTTParty::Response.new(@request_object, net_response, '')
214
- expect(response.success?).to be_truthy
215
- end
216
-
217
- it "is redirection" do
218
- net_response = response_mock(Net::HTTPRedirection)
219
- response = HTTParty::Response.new(@request_object, net_response, '')
220
- expect(response.redirection?).to be_truthy
221
- end
222
-
223
- it "is client error" do
224
- net_response = response_mock(Net::HTTPClientError)
225
- response = HTTParty::Response.new(@request_object, net_response, '')
226
- expect(response.client_error?).to be_truthy
227
- end
228
-
229
- it "is server error" do
230
- net_response = response_mock(Net::HTTPServerError)
231
- response = HTTParty::Response.new(@request_object, net_response, '')
232
- expect(response.server_error?).to be_truthy
233
- end
234
- end
235
-
236
- context "for specific codes" do
237
- SPECIFIC_CODES = {
238
- accepted?: Net::HTTPAccepted,
239
- bad_gateway?: Net::HTTPBadGateway,
240
- bad_request?: Net::HTTPBadRequest,
241
- conflict?: Net::HTTPConflict,
242
- continue?: Net::HTTPContinue,
243
- created?: Net::HTTPCreated,
244
- expectation_failed?: Net::HTTPExpectationFailed,
245
- forbidden?: Net::HTTPForbidden,
246
- found?: Net::HTTPFound,
247
- gateway_time_out?: Net::HTTPGatewayTimeOut,
248
- gone?: Net::HTTPGone,
249
- internal_server_error?: Net::HTTPInternalServerError,
250
- length_required?: Net::HTTPLengthRequired,
251
- method_not_allowed?: Net::HTTPMethodNotAllowed,
252
- moved_permanently?: Net::HTTPMovedPermanently,
253
- multiple_choice?: Net::HTTPMultipleChoice,
254
- no_content?: Net::HTTPNoContent,
255
- non_authoritative_information?: Net::HTTPNonAuthoritativeInformation,
256
- not_acceptable?: Net::HTTPNotAcceptable,
257
- not_found?: Net::HTTPNotFound,
258
- not_implemented?: Net::HTTPNotImplemented,
259
- not_modified?: Net::HTTPNotModified,
260
- ok?: Net::HTTPOK,
261
- partial_content?: Net::HTTPPartialContent,
262
- payment_required?: Net::HTTPPaymentRequired,
263
- precondition_failed?: Net::HTTPPreconditionFailed,
264
- proxy_authentication_required?: Net::HTTPProxyAuthenticationRequired,
265
- request_entity_too_large?: Net::HTTPRequestEntityTooLarge,
266
- request_time_out?: Net::HTTPRequestTimeOut,
267
- request_uri_too_long?: Net::HTTPRequestURITooLong,
268
- requested_range_not_satisfiable?: Net::HTTPRequestedRangeNotSatisfiable,
269
- reset_content?: Net::HTTPResetContent,
270
- see_other?: Net::HTTPSeeOther,
271
- service_unavailable?: Net::HTTPServiceUnavailable,
272
- switch_protocol?: Net::HTTPSwitchProtocol,
273
- temporary_redirect?: Net::HTTPTemporaryRedirect,
274
- unauthorized?: Net::HTTPUnauthorized,
275
- unsupported_media_type?: Net::HTTPUnsupportedMediaType,
276
- use_proxy?: Net::HTTPUseProxy,
277
- version_not_supported?: Net::HTTPVersionNotSupported
278
- }
279
-
280
- # Ruby 2.0, new name for this response.
281
- if RUBY_VERSION >= "2.0.0" && ::RUBY_PLATFORM != "java"
282
- SPECIFIC_CODES[:multiple_choices?] = Net::HTTPMultipleChoices
283
- end
284
-
285
- SPECIFIC_CODES.each do |method, klass|
286
- it "responds to #{method}" do
287
- net_response = response_mock(klass)
288
- response = HTTParty::Response.new(@request_object, net_response, '')
289
- expect(response.__send__(method)).to be_truthy
290
- end
291
- end
292
- end
293
- end
294
-
295
- describe "headers" do
296
- let (:empty_headers) { HTTParty::Response::Headers.new }
297
- let (:some_headers_hash) do
298
- {'Cookie' => 'bob',
299
- 'Content-Encoding' => 'meow'}
300
- end
301
- let (:some_headers) do
302
- HTTParty::Response::Headers.new.tap do |h|
303
- some_headers_hash.each_pair do |k,v|
304
- h[k] = v
305
- end
306
- end
307
- end
308
- it "can initialize without headers" do
309
- expect(empty_headers).to eq({})
310
- end
311
-
312
- it 'always equals itself' do
313
- expect(empty_headers).to eq(empty_headers)
314
- expect(some_headers).to eq(some_headers)
315
- end
316
-
317
- it 'does not equal itself when not equivalent' do
318
- expect(empty_headers).to_not eq(some_headers)
319
- end
320
-
321
- it 'does equal a hash' do
322
- expect(empty_headers).to eq({})
323
-
324
- expect(some_headers).to eq(some_headers_hash)
325
- end
326
- end
327
-
328
- describe "#tap" do
329
- it "is possible to tap into a response" do
330
- result = @response.tap(&:code)
331
-
332
- expect(result).to eq @response
333
- end
334
- end
335
-
336
- describe "#inspect" do
337
- it "works" do
338
- inspect = @response.inspect
339
- expect(inspect).to include("HTTParty::Response:0x")
340
- expect(inspect).to include("parsed_response={\"foo\"=>\"bar\"}")
341
- expect(inspect).to include("@response=#<Net::HTTPOK 200 OK readbody=false>")
342
- expect(inspect).to include("@headers={")
343
- expect(inspect).to include("last-modified")
344
- expect(inspect).to include("content-length")
345
- end
346
- end
347
- end
@@ -1,74 +0,0 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
-
3
- RSpec.describe HTTParty::Request do
4
- context "SSL certificate verification" do
5
- before do
6
- FakeWeb.allow_net_connect = true
7
- end
8
-
9
- after do
10
- FakeWeb.allow_net_connect = false
11
- end
12
-
13
- it "should fail when no trusted CA list is specified, by default" do
14
- expect do
15
- ssl_verify_test(nil, nil, "selfsigned.crt")
16
- end.to raise_error OpenSSL::SSL::SSLError
17
- end
18
-
19
- it "should work when no trusted CA list is specified, when the verify option is set to false" do
20
- expect(ssl_verify_test(nil, nil, "selfsigned.crt", verify: false).parsed_response).to eq({'success' => true})
21
- end
22
-
23
- it "should fail when no trusted CA list is specified, with a bogus hostname, by default" do
24
- expect do
25
- ssl_verify_test(nil, nil, "bogushost.crt")
26
- end.to raise_error OpenSSL::SSL::SSLError
27
- end
28
-
29
- it "should work when no trusted CA list is specified, even with a bogus hostname, when the verify option is set to true" do
30
- expect(ssl_verify_test(nil, nil, "bogushost.crt", verify: false).parsed_response).to eq({'success' => true})
31
- end
32
-
33
- it "should work when using ssl_ca_file with a self-signed CA" do
34
- expect(ssl_verify_test(:ssl_ca_file, "selfsigned.crt", "selfsigned.crt").parsed_response).to eq({'success' => true})
35
- end
36
-
37
- it "should work when using ssl_ca_file with a certificate authority" do
38
- expect(ssl_verify_test(:ssl_ca_file, "ca.crt", "server.crt").parsed_response).to eq({'success' => true})
39
- end
40
-
41
- it "should work when using ssl_ca_path with a certificate authority" do
42
- http = Net::HTTP.new('www.google.com', 443)
43
- response = double(Net::HTTPResponse, :[] => '', body: '', to_hash: {})
44
- allow(http).to receive(:request).and_return(response)
45
- expect(Net::HTTP).to receive(:new).with('www.google.com', 443).and_return(http)
46
- expect(http).to receive(:ca_path=).with('/foo/bar')
47
- HTTParty.get('https://www.google.com', ssl_ca_path: '/foo/bar')
48
- end
49
-
50
- it "should fail when using ssl_ca_file and the server uses an unrecognized certificate authority" do
51
- expect do
52
- ssl_verify_test(:ssl_ca_file, "ca.crt", "selfsigned.crt")
53
- end.to raise_error(OpenSSL::SSL::SSLError)
54
- end
55
-
56
- it "should fail when using ssl_ca_path and the server uses an unrecognized certificate authority" do
57
- expect do
58
- ssl_verify_test(:ssl_ca_path, ".", "selfsigned.crt")
59
- end.to raise_error(OpenSSL::SSL::SSLError)
60
- end
61
-
62
- it "should fail when using ssl_ca_file and the server uses a bogus hostname" do
63
- expect do
64
- ssl_verify_test(:ssl_ca_file, "ca.crt", "bogushost.crt")
65
- end.to raise_error(OpenSSL::SSL::SSLError)
66
- end
67
-
68
- it "should fail when using ssl_ca_path and the server uses a bogus hostname" do
69
- expect do
70
- ssl_verify_test(:ssl_ca_path, ".", "bogushost.crt")
71
- end.to raise_error(OpenSSL::SSL::SSLError)
72
- end
73
- end
74
- end