httparty 0.10.0 → 0.14.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.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +92 -0
- data/.rubocop_todo.yml +124 -0
- data/.simplecov +1 -0
- data/.travis.yml +5 -4
- data/CONTRIBUTING.md +23 -0
- data/Gemfile +9 -5
- data/Guardfile +3 -3
- data/History +109 -8
- data/README.md +21 -21
- data/Rakefile +5 -10
- data/bin/httparty +21 -14
- data/docs/README.md +100 -0
- data/examples/README.md +67 -0
- data/examples/aaws.rb +9 -9
- data/examples/basic.rb +6 -10
- data/examples/crack.rb +3 -3
- data/examples/custom_parsers.rb +1 -4
- data/examples/delicious.rb +12 -12
- data/examples/google.rb +2 -2
- data/examples/headers_and_user_agents.rb +2 -2
- data/examples/logging.rb +36 -0
- data/examples/nokogiri_html_parser.rb +0 -3
- data/examples/rescue_json.rb +17 -0
- data/examples/rubyurl.rb +3 -3
- data/examples/stackexchange.rb +24 -0
- data/examples/tripit_sign_in.rb +20 -9
- data/examples/twitter.rb +11 -11
- data/examples/whoismyrep.rb +2 -2
- data/features/command_line.feature +90 -2
- data/features/digest_authentication.feature +10 -0
- data/features/handles_compressed_responses.feature +8 -0
- data/features/handles_multiple_formats.feature +23 -0
- data/features/steps/env.rb +16 -11
- data/features/steps/httparty_response_steps.rb +40 -10
- data/features/steps/httparty_steps.rb +19 -3
- data/features/steps/mongrel_helper.rb +35 -2
- data/features/steps/remote_service_steps.rb +31 -8
- data/features/supports_read_timeout_option.feature +13 -0
- data/httparty.gemspec +9 -6
- data/lib/httparty/connection_adapter.rb +76 -11
- data/lib/httparty/cookie_hash.rb +3 -4
- data/lib/httparty/exceptions.rb +10 -4
- data/lib/httparty/hash_conversions.rb +19 -17
- data/lib/httparty/logger/apache_formatter.rb +22 -0
- data/lib/httparty/logger/curl_formatter.rb +91 -0
- data/lib/httparty/logger/logger.rb +26 -0
- data/lib/httparty/module_inheritable_attributes.rb +1 -1
- data/lib/httparty/net_digest_auth.rb +69 -18
- data/lib/httparty/parser.rb +15 -11
- data/lib/httparty/request.rb +186 -47
- data/lib/httparty/response/headers.rb +2 -2
- data/lib/httparty/response.rb +44 -9
- data/lib/httparty/version.rb +1 -1
- data/lib/httparty.rb +187 -65
- data/script/release +42 -0
- data/spec/fixtures/twitter.csv +2 -0
- data/spec/httparty/connection_adapter_spec.rb +334 -62
- data/spec/httparty/cookie_hash_spec.rb +53 -23
- data/spec/httparty/exception_spec.rb +45 -0
- data/spec/httparty/hash_conversions_spec.rb +49 -0
- data/spec/httparty/logger/apache_formatter_spec.rb +41 -0
- data/spec/httparty/logger/curl_formatter_spec.rb +119 -0
- data/spec/httparty/logger/logger_spec.rb +38 -0
- data/spec/httparty/net_digest_auth_spec.rb +148 -23
- data/spec/httparty/parser_spec.rb +48 -41
- data/spec/httparty/request_spec.rb +845 -151
- data/spec/httparty/response_spec.rb +147 -70
- data/spec/httparty/ssl_spec.rb +33 -21
- data/spec/httparty_spec.rb +337 -186
- data/spec/spec_helper.rb +38 -9
- data/spec/support/ssl_test_helper.rb +10 -10
- data/spec/support/ssl_test_server.rb +21 -21
- data/spec/support/stub_response.rb +20 -14
- data/website/index.html +3 -3
- metadata +46 -37
- data/lib/httparty/core_extensions.rb +0 -32
- data/spec/spec.opts +0 -2
@@ -1,7 +1,6 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
2
|
|
3
|
-
describe HTTParty::ConnectionAdapter do
|
4
|
-
|
3
|
+
RSpec.describe HTTParty::ConnectionAdapter do
|
5
4
|
describe "initialization" do
|
6
5
|
let(:uri) { URI 'http://www.google.com' }
|
7
6
|
it "takes a URI as input" do
|
@@ -18,7 +17,7 @@ describe HTTParty::ConnectionAdapter do
|
|
18
17
|
|
19
18
|
it "sets the uri" do
|
20
19
|
adapter = HTTParty::ConnectionAdapter.new(uri)
|
21
|
-
adapter.uri.
|
20
|
+
expect(adapter.uri).to be uri
|
22
21
|
end
|
23
22
|
|
24
23
|
it "also accepts an optional options hash" do
|
@@ -26,24 +25,24 @@ describe HTTParty::ConnectionAdapter do
|
|
26
25
|
end
|
27
26
|
|
28
27
|
it "sets the options" do
|
29
|
-
options = {:
|
28
|
+
options = {foo: :bar}
|
30
29
|
adapter = HTTParty::ConnectionAdapter.new(uri, options)
|
31
|
-
adapter.options.
|
30
|
+
expect(adapter.options.keys).to include(:verify, :verify_peer, :foo)
|
32
31
|
end
|
33
32
|
end
|
34
33
|
|
35
34
|
describe ".call" do
|
36
35
|
it "generates an HTTParty::ConnectionAdapter instance with the given uri and options" do
|
37
|
-
HTTParty::ConnectionAdapter.
|
36
|
+
expect(HTTParty::ConnectionAdapter).to receive(:new).with(@uri, @options).and_return(double(connection: nil))
|
38
37
|
HTTParty::ConnectionAdapter.call(@uri, @options)
|
39
38
|
end
|
40
39
|
|
41
40
|
it "calls #connection on the connection adapter" do
|
42
|
-
adapter =
|
43
|
-
connection =
|
44
|
-
adapter.
|
45
|
-
HTTParty::ConnectionAdapter.
|
46
|
-
HTTParty::ConnectionAdapter.call(@uri, @options).
|
41
|
+
adapter = double('Adapter')
|
42
|
+
connection = double('Connection')
|
43
|
+
expect(adapter).to receive(:connection).and_return(connection)
|
44
|
+
allow(HTTParty::ConnectionAdapter).to receive_messages(new: adapter)
|
45
|
+
expect(HTTParty::ConnectionAdapter.call(@uri, @options)).to be connection
|
47
46
|
end
|
48
47
|
end
|
49
48
|
|
@@ -54,36 +53,51 @@ describe HTTParty::ConnectionAdapter do
|
|
54
53
|
|
55
54
|
describe "the resulting connection" do
|
56
55
|
subject { adapter.connection }
|
57
|
-
it {
|
56
|
+
it { is_expected.to be_an_instance_of Net::HTTP }
|
58
57
|
|
59
58
|
context "using port 80" do
|
60
59
|
let(:uri) { URI 'http://foobar.com' }
|
61
|
-
it {
|
60
|
+
it { is_expected.not_to use_ssl }
|
62
61
|
end
|
63
62
|
|
64
63
|
context "when dealing with ssl" do
|
65
64
|
let(:uri) { URI 'https://foobar.com' }
|
66
65
|
|
66
|
+
context "uses the system cert_store, by default" do
|
67
|
+
let!(:system_cert_store) do
|
68
|
+
system_cert_store = double('default_cert_store')
|
69
|
+
expect(system_cert_store).to receive(:set_default_paths)
|
70
|
+
expect(OpenSSL::X509::Store).to receive(:new).and_return(system_cert_store)
|
71
|
+
system_cert_store
|
72
|
+
end
|
73
|
+
it { is_expected.to use_cert_store(system_cert_store) }
|
74
|
+
end
|
75
|
+
|
76
|
+
context "should use the specified cert store, when one is given" do
|
77
|
+
let(:custom_cert_store) { double('custom_cert_store') }
|
78
|
+
let(:options) { {cert_store: custom_cert_store} }
|
79
|
+
it { is_expected.to use_cert_store(custom_cert_store) }
|
80
|
+
end
|
81
|
+
|
67
82
|
context "using port 443 for ssl" do
|
68
83
|
let(:uri) { URI 'https://api.foo.com/v1:443' }
|
69
|
-
it {
|
84
|
+
it { is_expected.to use_ssl }
|
70
85
|
end
|
71
86
|
|
72
87
|
context "https scheme with default port" do
|
73
|
-
it {
|
88
|
+
it { is_expected.to use_ssl }
|
74
89
|
end
|
75
90
|
|
76
91
|
context "https scheme with non-standard port" do
|
77
92
|
let(:uri) { URI 'https://foobar.com:123456' }
|
78
|
-
it {
|
93
|
+
it { is_expected.to use_ssl }
|
79
94
|
end
|
80
95
|
|
81
|
-
|
82
96
|
context "when ssl version is set" do
|
83
|
-
let(:options) { {:
|
97
|
+
let(:options) { {ssl_version: :TLSv1} }
|
84
98
|
|
85
99
|
it "sets ssl version" do
|
86
|
-
subject.ssl_version.
|
100
|
+
expect(subject.ssl_version).to eq(:TLSv1)
|
87
101
|
end
|
88
102
|
end if RUBY_VERSION > '1.9'
|
89
103
|
end
|
@@ -92,24 +106,29 @@ describe HTTParty::ConnectionAdapter do
|
|
92
106
|
let(:uri) { URI 'http://[fd00::1]' }
|
93
107
|
|
94
108
|
it "strips brackets from the address" do
|
95
|
-
subject.address.
|
109
|
+
expect(subject.address).to eq('fd00::1')
|
96
110
|
end
|
97
111
|
end
|
98
112
|
|
99
113
|
context "specifying ciphers" do
|
100
|
-
let(:options) { {:
|
114
|
+
let(:options) { {ciphers: 'RC4-SHA' } }
|
101
115
|
|
102
116
|
it "should set the ciphers on the connection" do
|
103
|
-
subject.ciphers.
|
117
|
+
expect(subject.ciphers).to eq('RC4-SHA')
|
104
118
|
end
|
105
119
|
end if RUBY_VERSION > '1.9'
|
106
120
|
|
107
121
|
context "when timeout is not set" do
|
108
122
|
it "doesn't set the timeout" do
|
109
|
-
http =
|
110
|
-
|
111
|
-
|
112
|
-
|
123
|
+
http = double(
|
124
|
+
"http",
|
125
|
+
:null_object => true,
|
126
|
+
:use_ssl= => false,
|
127
|
+
:use_ssl? => false
|
128
|
+
)
|
129
|
+
expect(http).not_to receive(:open_timeout=)
|
130
|
+
expect(http).not_to receive(:read_timeout=)
|
131
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
113
132
|
|
114
133
|
adapter.connection
|
115
134
|
end
|
@@ -117,86 +136,268 @@ describe HTTParty::ConnectionAdapter do
|
|
117
136
|
|
118
137
|
context "when setting timeout" do
|
119
138
|
context "to 5 seconds" do
|
120
|
-
let(:options) { {:
|
139
|
+
let(:options) { {timeout: 5} }
|
121
140
|
|
122
|
-
|
123
|
-
|
141
|
+
describe '#open_timeout' do
|
142
|
+
subject { super().open_timeout }
|
143
|
+
it { is_expected.to eq(5) }
|
144
|
+
end
|
145
|
+
|
146
|
+
describe '#read_timeout' do
|
147
|
+
subject { super().read_timeout }
|
148
|
+
it { is_expected.to eq(5) }
|
149
|
+
end
|
124
150
|
end
|
125
151
|
|
126
152
|
context "and timeout is a string" do
|
127
|
-
let(:options) { {:
|
153
|
+
let(:options) { {timeout: "five seconds"} }
|
128
154
|
|
129
155
|
it "doesn't set the timeout" do
|
130
|
-
http =
|
131
|
-
|
132
|
-
|
133
|
-
|
156
|
+
http = double(
|
157
|
+
"http",
|
158
|
+
:null_object => true,
|
159
|
+
:use_ssl= => false,
|
160
|
+
:use_ssl? => false
|
161
|
+
)
|
162
|
+
expect(http).not_to receive(:open_timeout=)
|
163
|
+
expect(http).not_to receive(:read_timeout=)
|
164
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
134
165
|
|
135
166
|
adapter.connection
|
136
167
|
end
|
137
168
|
end
|
138
169
|
end
|
139
170
|
|
171
|
+
context "when timeout is not set and read_timeout is set to 6 seconds" do
|
172
|
+
let(:options) { {read_timeout: 6} }
|
173
|
+
|
174
|
+
describe '#read_timeout' do
|
175
|
+
subject { super().read_timeout }
|
176
|
+
it { is_expected.to eq(6) }
|
177
|
+
end
|
178
|
+
|
179
|
+
it "should not set the open_timeout" do
|
180
|
+
http = double(
|
181
|
+
"http",
|
182
|
+
:null_object => true,
|
183
|
+
:use_ssl= => false,
|
184
|
+
:use_ssl? => false,
|
185
|
+
:read_timeout= => 0
|
186
|
+
)
|
187
|
+
expect(http).not_to receive(:open_timeout=)
|
188
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
189
|
+
adapter.connection
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "when timeout is set and read_timeout is set to 6 seconds" do
|
194
|
+
let(:options) { {timeout: 5, read_timeout: 6} }
|
195
|
+
|
196
|
+
describe '#open_timeout' do
|
197
|
+
subject { super().open_timeout }
|
198
|
+
it { is_expected.to eq(5) }
|
199
|
+
end
|
200
|
+
|
201
|
+
describe '#read_timeout' do
|
202
|
+
subject { super().read_timeout }
|
203
|
+
it { is_expected.to eq(6) }
|
204
|
+
end
|
205
|
+
|
206
|
+
it "should override the timeout option" do
|
207
|
+
http = double(
|
208
|
+
"http",
|
209
|
+
:null_object => true,
|
210
|
+
:use_ssl= => false,
|
211
|
+
:use_ssl? => false,
|
212
|
+
:read_timeout= => 0,
|
213
|
+
:open_timeout= => 0
|
214
|
+
)
|
215
|
+
expect(http).to receive(:open_timeout=)
|
216
|
+
expect(http).to receive(:read_timeout=).twice
|
217
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
218
|
+
adapter.connection
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
context "when timeout is not set and open_timeout is set to 7 seconds" do
|
223
|
+
let(:options) { {open_timeout: 7} }
|
224
|
+
|
225
|
+
describe '#open_timeout' do
|
226
|
+
subject { super().open_timeout }
|
227
|
+
it { is_expected.to eq(7) }
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should not set the read_timeout" do
|
231
|
+
http = double(
|
232
|
+
"http",
|
233
|
+
:null_object => true,
|
234
|
+
:use_ssl= => false,
|
235
|
+
:use_ssl? => false,
|
236
|
+
:open_timeout= => 0
|
237
|
+
)
|
238
|
+
expect(http).not_to receive(:read_timeout=)
|
239
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
240
|
+
adapter.connection
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
context "when timeout is set and open_timeout is set to 7 seconds" do
|
245
|
+
let(:options) { {timeout: 5, open_timeout: 7} }
|
246
|
+
|
247
|
+
describe '#open_timeout' do
|
248
|
+
subject { super().open_timeout }
|
249
|
+
it { is_expected.to eq(7) }
|
250
|
+
end
|
251
|
+
|
252
|
+
describe '#read_timeout' do
|
253
|
+
subject { super().read_timeout }
|
254
|
+
it { is_expected.to eq(5) }
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should override the timeout option" do
|
258
|
+
http = double(
|
259
|
+
"http",
|
260
|
+
:null_object => true,
|
261
|
+
:use_ssl= => false,
|
262
|
+
:use_ssl? => false,
|
263
|
+
:read_timeout= => 0,
|
264
|
+
:open_timeout= => 0
|
265
|
+
)
|
266
|
+
expect(http).to receive(:open_timeout=).twice
|
267
|
+
expect(http).to receive(:read_timeout=)
|
268
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
269
|
+
adapter.connection
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
140
273
|
context "when debug_output" do
|
141
274
|
let(:http) { Net::HTTP.new(uri) }
|
142
275
|
before do
|
143
|
-
Net::HTTP.
|
276
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
144
277
|
end
|
145
278
|
|
146
279
|
context "is set to $stderr" do
|
147
|
-
let(:options) { {:
|
280
|
+
let(:options) { {debug_output: $stderr} }
|
148
281
|
it "has debug output set" do
|
149
|
-
http.
|
282
|
+
expect(http).to receive(:set_debug_output).with($stderr)
|
150
283
|
adapter.connection
|
151
284
|
end
|
152
285
|
end
|
153
286
|
|
154
287
|
context "is not provided" do
|
155
288
|
it "does not set_debug_output" do
|
156
|
-
http.
|
289
|
+
expect(http).not_to receive(:set_debug_output)
|
157
290
|
adapter.connection
|
158
291
|
end
|
159
292
|
end
|
160
293
|
end
|
161
294
|
|
162
295
|
context 'when providing proxy address and port' do
|
163
|
-
let(:options) { {:
|
296
|
+
let(:options) { {http_proxyaddr: '1.2.3.4', http_proxyport: 8080} }
|
164
297
|
|
165
|
-
it {
|
166
|
-
|
167
|
-
|
298
|
+
it { is_expected.to be_a_proxy }
|
299
|
+
|
300
|
+
describe '#proxy_address' do
|
301
|
+
subject { super().proxy_address }
|
302
|
+
it { is_expected.to eq('1.2.3.4') }
|
303
|
+
end
|
304
|
+
|
305
|
+
describe '#proxy_port' do
|
306
|
+
subject { super().proxy_port }
|
307
|
+
it { is_expected.to eq(8080) }
|
308
|
+
end
|
168
309
|
|
169
310
|
context 'as well as proxy user and password' do
|
170
311
|
let(:options) do
|
171
|
-
{:
|
172
|
-
:
|
312
|
+
{http_proxyaddr: '1.2.3.4', http_proxyport: 8080,
|
313
|
+
http_proxyuser: 'user', http_proxypass: 'pass'}
|
314
|
+
end
|
315
|
+
|
316
|
+
describe '#proxy_user' do
|
317
|
+
subject { super().proxy_user }
|
318
|
+
it { is_expected.to eq('user') }
|
319
|
+
end
|
320
|
+
|
321
|
+
describe '#proxy_pass' do
|
322
|
+
subject { super().proxy_pass }
|
323
|
+
it { is_expected.to eq('pass') }
|
173
324
|
end
|
174
|
-
its(:proxy_user) { should == 'user' }
|
175
|
-
its(:proxy_pass) { should == 'pass' }
|
176
325
|
end
|
177
326
|
end
|
178
327
|
|
328
|
+
context 'when providing nil as proxy address' do
|
329
|
+
let(:uri) { URI 'http://noproxytest.com' }
|
330
|
+
let(:options) { {http_proxyaddr: nil} }
|
331
|
+
|
332
|
+
it { is_expected.not_to be_a_proxy }
|
333
|
+
|
334
|
+
it "does pass nil proxy parameters to the connection, this forces to not use a proxy" do
|
335
|
+
http = Net::HTTP.new("noproxytest.com")
|
336
|
+
expect(Net::HTTP).to receive(:new).once.with("noproxytest.com", 80, nil, nil, nil, nil).and_return(http)
|
337
|
+
adapter.connection
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
341
|
+
context 'when not providing a proxy address' do
|
342
|
+
let(:uri) { URI 'http://proxytest.com' }
|
343
|
+
|
344
|
+
it "does not pass any proxy parameters to the connection" do
|
345
|
+
http = Net::HTTP.new("proxytest.com")
|
346
|
+
expect(Net::HTTP).to receive(:new).once.with("proxytest.com", 80).and_return(http)
|
347
|
+
adapter.connection
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context 'when providing a local bind address and port' do
|
352
|
+
let(:options) { {local_host: "127.0.0.1", local_port: 12345 } }
|
353
|
+
|
354
|
+
describe '#local_host' do
|
355
|
+
subject { super().local_host }
|
356
|
+
it { is_expected.to eq('127.0.0.1') }
|
357
|
+
end
|
358
|
+
|
359
|
+
describe '#local_port' do
|
360
|
+
subject { super().local_port }
|
361
|
+
it { is_expected.to eq(12345) }
|
362
|
+
end
|
363
|
+
end if RUBY_VERSION >= '2.0'
|
364
|
+
|
179
365
|
context "when providing PEM certificates" do
|
180
366
|
let(:pem) { :pem_contents }
|
181
|
-
let(:options) { {:
|
367
|
+
let(:options) { {pem: pem, pem_password: "password"} }
|
182
368
|
|
183
369
|
context "when scheme is https" do
|
184
370
|
let(:uri) { URI 'https://google.com' }
|
185
|
-
let(:cert) {
|
186
|
-
let(:key) {
|
371
|
+
let(:cert) { double("OpenSSL::X509::Certificate") }
|
372
|
+
let(:key) { double("OpenSSL::PKey::RSA") }
|
187
373
|
|
188
374
|
before do
|
189
|
-
OpenSSL::X509::Certificate.
|
190
|
-
OpenSSL::PKey::RSA.
|
375
|
+
expect(OpenSSL::X509::Certificate).to receive(:new).with(pem).and_return(cert)
|
376
|
+
expect(OpenSSL::PKey::RSA).to receive(:new).with(pem, "password").and_return(key)
|
191
377
|
end
|
192
378
|
|
193
|
-
it "uses the provided PEM certificate
|
194
|
-
subject.cert.
|
195
|
-
subject.key.
|
379
|
+
it "uses the provided PEM certificate" do
|
380
|
+
expect(subject.cert).to eq(cert)
|
381
|
+
expect(subject.key).to eq(key)
|
196
382
|
end
|
197
383
|
|
198
384
|
it "will verify the certificate" do
|
199
|
-
subject.verify_mode.
|
385
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
|
386
|
+
end
|
387
|
+
|
388
|
+
context "when options include verify=false" do
|
389
|
+
let(:options) { {pem: pem, pem_password: "password", verify: false} }
|
390
|
+
|
391
|
+
it "should not verify the certificate" do
|
392
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
context "when options include verify_peer=false" do
|
396
|
+
let(:options) { {pem: pem, pem_password: "password", verify_peer: false} }
|
397
|
+
|
398
|
+
it "should not verify the certificate" do
|
399
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
400
|
+
end
|
200
401
|
end
|
201
402
|
end
|
202
403
|
|
@@ -205,17 +406,88 @@ describe HTTParty::ConnectionAdapter do
|
|
205
406
|
let(:http) { Net::HTTP.new(uri) }
|
206
407
|
|
207
408
|
before do
|
208
|
-
Net::HTTP.
|
209
|
-
OpenSSL::X509::Certificate.
|
210
|
-
OpenSSL::PKey::RSA.
|
211
|
-
http.
|
212
|
-
http.
|
409
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
410
|
+
expect(OpenSSL::X509::Certificate).not_to receive(:new).with(pem)
|
411
|
+
expect(OpenSSL::PKey::RSA).not_to receive(:new).with(pem, "password")
|
412
|
+
expect(http).not_to receive(:cert=)
|
413
|
+
expect(http).not_to receive(:key=)
|
213
414
|
end
|
214
415
|
|
215
416
|
it "has no PEM certificate " do
|
216
|
-
subject.cert.
|
217
|
-
subject.key.
|
417
|
+
expect(subject.cert).to be_nil
|
418
|
+
expect(subject.key).to be_nil
|
419
|
+
end
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
context "when providing PKCS12 certificates" do
|
424
|
+
let(:p12) { :p12_contents }
|
425
|
+
let(:options) { {p12: p12, p12_password: "password"} }
|
426
|
+
|
427
|
+
context "when scheme is https" do
|
428
|
+
let(:uri) { URI 'https://google.com' }
|
429
|
+
let(:pkcs12) { double("OpenSSL::PKCS12", certificate: cert, key: key) }
|
430
|
+
let(:cert) { double("OpenSSL::X509::Certificate") }
|
431
|
+
let(:key) { double("OpenSSL::PKey::RSA") }
|
432
|
+
|
433
|
+
before do
|
434
|
+
expect(OpenSSL::PKCS12).to receive(:new).with(p12, "password").and_return(pkcs12)
|
435
|
+
end
|
436
|
+
|
437
|
+
it "uses the provided P12 certificate " do
|
438
|
+
expect(subject.cert).to eq(cert)
|
439
|
+
expect(subject.key).to eq(key)
|
440
|
+
end
|
441
|
+
|
442
|
+
it "will verify the certificate" do
|
443
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_PEER)
|
444
|
+
end
|
445
|
+
|
446
|
+
context "when options include verify=false" do
|
447
|
+
let(:options) { {p12: p12, p12_password: "password", verify: false} }
|
448
|
+
|
449
|
+
it "should not verify the certificate" do
|
450
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
451
|
+
end
|
452
|
+
end
|
453
|
+
context "when options include verify_peer=false" do
|
454
|
+
let(:options) { {p12: p12, p12_password: "password", verify_peer: false} }
|
455
|
+
|
456
|
+
it "should not verify the certificate" do
|
457
|
+
expect(subject.verify_mode).to eq(OpenSSL::SSL::VERIFY_NONE)
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
|
462
|
+
context "when scheme is not https" do
|
463
|
+
let(:uri) { URI 'http://google.com' }
|
464
|
+
let(:http) { Net::HTTP.new(uri) }
|
465
|
+
|
466
|
+
before do
|
467
|
+
allow(Net::HTTP).to receive_messages(new: http)
|
468
|
+
expect(OpenSSL::PKCS12).not_to receive(:new).with(p12, "password")
|
469
|
+
expect(http).not_to receive(:cert=)
|
470
|
+
expect(http).not_to receive(:key=)
|
218
471
|
end
|
472
|
+
|
473
|
+
it "has no PKCS12 certificate " do
|
474
|
+
expect(subject.cert).to be_nil
|
475
|
+
expect(subject.key).to be_nil
|
476
|
+
end
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
context "when uri port is not defined" do
|
481
|
+
context "falls back to 80 port on http" do
|
482
|
+
let(:uri) { URI 'http://foobar.com' }
|
483
|
+
before { allow(uri).to receive(:port).and_return(nil) }
|
484
|
+
it { expect(subject.port).to be 80 }
|
485
|
+
end
|
486
|
+
|
487
|
+
context "falls back to 443 port on https" do
|
488
|
+
let(:uri) { URI 'https://foobar.com' }
|
489
|
+
before { allow(uri).to receive(:port).and_return(nil) }
|
490
|
+
it { expect(subject.port).to be 443 }
|
219
491
|
end
|
220
492
|
end
|
221
493
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '../spec_helper'))
|
2
2
|
|
3
|
-
describe HTTParty::CookieHash do
|
3
|
+
RSpec.describe HTTParty::CookieHash do
|
4
4
|
before(:each) do
|
5
5
|
@cookie_hash = HTTParty::CookieHash.new
|
6
6
|
end
|
@@ -8,40 +8,47 @@ describe HTTParty::CookieHash do
|
|
8
8
|
describe "#add_cookies" do
|
9
9
|
describe "with a hash" do
|
10
10
|
it "should add new key/value pairs to the hash" do
|
11
|
-
@cookie_hash.add_cookies(:
|
12
|
-
@cookie_hash.add_cookies(:
|
13
|
-
@cookie_hash.length.
|
11
|
+
@cookie_hash.add_cookies(foo: "bar")
|
12
|
+
@cookie_hash.add_cookies(rofl: "copter")
|
13
|
+
expect(@cookie_hash.length).to eql(2)
|
14
14
|
end
|
15
15
|
|
16
16
|
it "should overwrite any existing key" do
|
17
|
-
@cookie_hash.add_cookies(:
|
18
|
-
@cookie_hash.add_cookies(:
|
19
|
-
@cookie_hash.length.
|
20
|
-
@cookie_hash[:foo].
|
17
|
+
@cookie_hash.add_cookies(foo: "bar")
|
18
|
+
@cookie_hash.add_cookies(foo: "copter")
|
19
|
+
expect(@cookie_hash.length).to eql(1)
|
20
|
+
expect(@cookie_hash[:foo]).to eql("copter")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "with a string" do
|
25
25
|
it "should add new key/value pairs to the hash" do
|
26
26
|
@cookie_hash.add_cookies("first=one; second=two; third")
|
27
|
-
@cookie_hash[:first].
|
28
|
-
@cookie_hash[:second].
|
29
|
-
@cookie_hash[:third].
|
27
|
+
expect(@cookie_hash[:first]).to eq('one')
|
28
|
+
expect(@cookie_hash[:second]).to eq('two')
|
29
|
+
expect(@cookie_hash[:third]).to eq(nil)
|
30
30
|
end
|
31
31
|
|
32
32
|
it "should overwrite any existing key" do
|
33
33
|
@cookie_hash[:foo] = 'bar'
|
34
34
|
@cookie_hash.add_cookies("foo=tar")
|
35
|
-
@cookie_hash.length.
|
36
|
-
@cookie_hash[:foo].
|
35
|
+
expect(@cookie_hash.length).to eql(1)
|
36
|
+
expect(@cookie_hash[:foo]).to eql("tar")
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should handle '=' within cookie value" do
|
40
|
+
@cookie_hash.add_cookies("first=one=1; second=two=2==")
|
41
|
+
expect(@cookie_hash.keys).to include(:first, :second)
|
42
|
+
expect(@cookie_hash[:first]).to eq('one=1')
|
43
|
+
expect(@cookie_hash[:second]).to eq('two=2==')
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
40
47
|
describe 'with other class' do
|
41
48
|
it "should error" do
|
42
|
-
|
43
|
-
@cookie_hash.add_cookies(
|
44
|
-
}.
|
49
|
+
expect {
|
50
|
+
@cookie_hash.add_cookies([])
|
51
|
+
}.to raise_error(RuntimeError)
|
45
52
|
end
|
46
53
|
end
|
47
54
|
end
|
@@ -50,21 +57,44 @@ describe HTTParty::CookieHash do
|
|
50
57
|
# a hardcoded string was randomly failing.
|
51
58
|
describe "#to_cookie_string" do
|
52
59
|
before(:each) do
|
53
|
-
@cookie_hash.add_cookies(:
|
54
|
-
@cookie_hash.add_cookies(:
|
60
|
+
@cookie_hash.add_cookies(foo: "bar")
|
61
|
+
@cookie_hash.add_cookies(rofl: "copter")
|
55
62
|
@s = @cookie_hash.to_cookie_string
|
56
63
|
end
|
57
64
|
|
58
65
|
it "should format the key/value pairs, delimited by semi-colons" do
|
59
|
-
@s.
|
60
|
-
@s.
|
61
|
-
@s.
|
66
|
+
expect(@s).to match(/foo=bar/)
|
67
|
+
expect(@s).to match(/rofl=copter/)
|
68
|
+
expect(@s).to match(/^\w+=\w+; \w+=\w+$/)
|
62
69
|
end
|
63
70
|
|
64
71
|
it "should not include client side only cookies" do
|
65
|
-
@cookie_hash.add_cookies(:
|
72
|
+
@cookie_hash.add_cookies(path: "/")
|
73
|
+
@s = @cookie_hash.to_cookie_string
|
74
|
+
expect(@s).not_to match(/path=\//)
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not include client side only cookies even when attributes use camal case" do
|
78
|
+
@cookie_hash.add_cookies(Path: "/")
|
66
79
|
@s = @cookie_hash.to_cookie_string
|
67
|
-
@s.
|
80
|
+
expect(@s).not_to match(/Path=\//)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should not mutate the hash" do
|
84
|
+
original_hash = {
|
85
|
+
"session" => "91e25e8b-6e32-418d-c72f-2d18adf041cd",
|
86
|
+
"Max-Age" => "15552000",
|
87
|
+
"cart" => "91e25e8b-6e32-418d-c72f-2d18adf041cd",
|
88
|
+
"httponly" => nil,
|
89
|
+
"Path" => "/",
|
90
|
+
"secure" => nil,
|
91
|
+
}
|
92
|
+
|
93
|
+
cookie_hash = HTTParty::CookieHash[original_hash]
|
94
|
+
|
95
|
+
cookie_hash.to_cookie_string
|
96
|
+
|
97
|
+
expect(cookie_hash).to eq(original_hash)
|
68
98
|
end
|
69
99
|
end
|
70
100
|
end
|