rest-client 1.7.2 → 2.1.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.
Files changed (55) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/.mailmap +10 -0
  4. data/.rspec +2 -1
  5. data/.rubocop +2 -0
  6. data/.rubocop-disables.yml +386 -0
  7. data/.rubocop.yml +8 -0
  8. data/.travis.yml +56 -8
  9. data/AUTHORS +26 -1
  10. data/README.md +901 -0
  11. data/Rakefile +27 -3
  12. data/bin/restclient +3 -5
  13. data/history.md +199 -0
  14. data/lib/restclient/abstract_response.rb +196 -50
  15. data/lib/restclient/exceptions.rb +96 -55
  16. data/lib/restclient/params_array.rb +72 -0
  17. data/lib/restclient/payload.rb +70 -74
  18. data/lib/restclient/platform.rb +20 -1
  19. data/lib/restclient/raw_response.rb +21 -6
  20. data/lib/restclient/request.rb +572 -284
  21. data/lib/restclient/resource.rb +19 -9
  22. data/lib/restclient/response.rb +75 -9
  23. data/lib/restclient/utils.rb +274 -0
  24. data/lib/restclient/version.rb +2 -1
  25. data/lib/restclient.rb +21 -3
  26. data/rest-client.gemspec +13 -10
  27. data/spec/ISS.jpg +0 -0
  28. data/spec/helpers.rb +54 -0
  29. data/spec/integration/_lib.rb +1 -0
  30. data/spec/integration/capath_digicert/3513523f.0 +22 -0
  31. data/spec/integration/capath_digicert/399e7759.0 +22 -0
  32. data/spec/integration/capath_digicert/digicert.crt +20 -17
  33. data/spec/integration/certs/digicert.crt +20 -17
  34. data/spec/integration/httpbin_spec.rb +128 -0
  35. data/spec/integration/integration_spec.rb +97 -14
  36. data/spec/integration/request_spec.rb +29 -6
  37. data/spec/spec_helper.rb +28 -1
  38. data/spec/unit/_lib.rb +1 -0
  39. data/spec/unit/abstract_response_spec.rb +95 -35
  40. data/spec/unit/exceptions_spec.rb +41 -28
  41. data/spec/unit/params_array_spec.rb +36 -0
  42. data/spec/unit/payload_spec.rb +118 -68
  43. data/spec/unit/raw_response_spec.rb +10 -5
  44. data/spec/unit/request2_spec.rb +34 -12
  45. data/spec/unit/request_spec.rb +751 -418
  46. data/spec/unit/resource_spec.rb +31 -27
  47. data/spec/unit/response_spec.rb +144 -58
  48. data/spec/unit/restclient_spec.rb +16 -15
  49. data/spec/unit/utils_spec.rb +147 -0
  50. data/spec/unit/windows/root_certs_spec.rb +3 -3
  51. metadata +121 -70
  52. data/README.rdoc +0 -324
  53. data/spec/integration/capath_digicert/244b5494.0 +0 -19
  54. data/spec/integration/capath_digicert/81b9768f.0 +0 -19
  55. data/spec/unit/master_shake.jpg +0 -0
@@ -1,120 +1,206 @@
1
- require 'spec_helper'
1
+ require_relative './_lib'
2
2
 
3
- describe RestClient::Request do
3
+ describe RestClient::Request, :include_helpers do
4
4
  before do
5
5
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
6
6
 
7
7
  @uri = double("uri")
8
- @uri.stub(:request_uri).and_return('/resource')
9
- @uri.stub(:host).and_return('some')
10
- @uri.stub(:port).and_return(80)
8
+ allow(@uri).to receive(:request_uri).and_return('/resource')
9
+ allow(@uri).to receive(:hostname).and_return('some')
10
+ allow(@uri).to receive(:port).and_return(80)
11
11
 
12
12
  @net = double("net::http base")
13
13
  @http = double("net::http connection")
14
- Net::HTTP.stub(:new).and_return(@net)
15
- @net.stub(:start).and_yield(@http)
16
- @net.stub(:use_ssl=)
17
- @net.stub(:verify_mode=)
18
- @net.stub(:verify_callback=)
14
+
15
+ allow(Net::HTTP).to receive(:new).and_return(@net)
16
+
17
+ allow(@net).to receive(:start).and_yield(@http)
18
+ allow(@net).to receive(:use_ssl=)
19
+ allow(@net).to receive(:verify_mode=)
20
+ allow(@net).to receive(:verify_callback=)
19
21
  allow(@net).to receive(:ciphers=)
20
22
  allow(@net).to receive(:cert_store=)
21
23
  RestClient.log = nil
22
24
  end
23
25
 
24
- it "accept */* mimetype, preferring xml" do
25
- @request.default_headers[:accept].should eq '*/*; q=0.5, application/xml'
26
+ it "accept */* mimetype" do
27
+ expect(@request.default_headers[:accept]).to eq '*/*'
26
28
  end
27
29
 
28
- describe "compression" do
30
+ it "processes a successful result" do
31
+ res = res_double
32
+ allow(res).to receive(:code).and_return("200")
33
+ allow(res).to receive(:body).and_return('body')
34
+ allow(res).to receive(:[]).with('content-encoding').and_return(nil)
35
+ expect(@request.send(:process_result, res, Time.now).body).to eq 'body'
36
+ expect(@request.send(:process_result, res, Time.now).to_s).to eq 'body'
37
+ end
29
38
 
30
- it "decodes an uncompressed result body by passing it straight through" do
31
- RestClient::Request.decode(nil, 'xyz').should eq 'xyz'
39
+ it "doesn't classify successful requests as failed" do
40
+ 203.upto(207) do |code|
41
+ res = res_double
42
+ allow(res).to receive(:code).and_return(code.to_s)
43
+ allow(res).to receive(:body).and_return("")
44
+ allow(res).to receive(:[]).with('content-encoding').and_return(nil)
45
+ expect(@request.send(:process_result, res, Time.now)).to be_empty
32
46
  end
47
+ end
33
48
 
34
- it "doesn't fail for nil bodies" do
35
- RestClient::Request.decode('gzip', nil).should be_nil
49
+ describe '.normalize_url' do
50
+ it "adds http:// to the front of resources specified in the syntax example.com/resource" do
51
+ expect(@request.normalize_url('example.com/resource')).to eq 'http://example.com/resource'
36
52
  end
37
53
 
38
-
39
- it "decodes a gzip body" do
40
- RestClient::Request.decode('gzip', "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000").should eq "i'm gziped\n"
54
+ it 'adds http:// to resources containing a colon' do
55
+ expect(@request.normalize_url('example.com:1234')).to eq 'http://example.com:1234'
41
56
  end
42
57
 
43
- it "ingores gzip for empty bodies" do
44
- RestClient::Request.decode('gzip', '').should be_empty
58
+ it 'does not add http:// to the front of https resources' do
59
+ expect(@request.normalize_url('https://example.com/resource')).to eq 'https://example.com/resource'
45
60
  end
46
61
 
47
- it "decodes a deflated body" do
48
- RestClient::Request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should eq "some deflated text"
62
+ it 'does not add http:// to the front of capital HTTP resources' do
63
+ expect(@request.normalize_url('HTTP://example.com/resource')).to eq 'HTTP://example.com/resource'
49
64
  end
50
- end
51
65
 
52
- it "processes a successful result" do
53
- res = double("result")
54
- res.stub(:code).and_return("200")
55
- res.stub(:body).and_return('body')
56
- res.stub(:[]).with('content-encoding').and_return(nil)
57
- @request.process_result(res).body.should eq 'body'
58
- @request.process_result(res).to_s.should eq 'body'
59
- end
60
-
61
- it "doesn't classify successful requests as failed" do
62
- 203.upto(207) do |code|
63
- res = double("result")
64
- res.stub(:code).and_return(code.to_s)
65
- res.stub(:body).and_return("")
66
- res.stub(:[]).with('content-encoding').and_return(nil)
67
- @request.process_result(res).should be_empty
66
+ it 'does not add http:// to the front of capital HTTPS resources' do
67
+ expect(@request.normalize_url('HTTPS://example.com/resource')).to eq 'HTTPS://example.com/resource'
68
68
  end
69
- end
70
69
 
71
- it "parses a url into a URI object" do
72
- URI.should_receive(:parse).with('http://example.com/resource')
73
- @request.parse_url('http://example.com/resource')
74
- end
75
-
76
- it "adds http:// to the front of resources specified in the syntax example.com/resource" do
77
- URI.should_receive(:parse).with('http://example.com/resource')
78
- @request.parse_url('example.com/resource')
70
+ it 'raises with invalid URI' do
71
+ expect {
72
+ RestClient::Request.new(method: :get, url: 'http://a@b:c')
73
+ }.to raise_error(URI::InvalidURIError)
74
+ expect {
75
+ RestClient::Request.new(method: :get, url: 'http://::')
76
+ }.to raise_error(URI::InvalidURIError)
77
+ end
79
78
  end
80
79
 
81
80
  describe "user - password" do
82
81
  it "extracts the username and password when parsing http://user:password@example.com/" do
83
- URI.stub(:parse).and_return(double('uri', :user => 'joe', :password => 'pass1'))
84
- @request.parse_url_with_auth('http://joe:pass1@example.com/resource')
85
- @request.user.should eq 'joe'
86
- @request.password.should eq 'pass1'
82
+ @request.send(:parse_url_with_auth!, 'http://joe:pass1@example.com/resource')
83
+ expect(@request.user).to eq 'joe'
84
+ expect(@request.password).to eq 'pass1'
87
85
  end
88
86
 
89
87
  it "extracts with escaping the username and password when parsing http://user:password@example.com/" do
90
- URI.stub(:parse).and_return(double('uri', :user => 'joe%20', :password => 'pass1'))
91
- @request.parse_url_with_auth('http://joe%20:pass1@example.com/resource')
92
- @request.user.should eq 'joe '
93
- @request.password.should eq 'pass1'
88
+ @request.send(:parse_url_with_auth!, 'http://joe%20:pass1@example.com/resource')
89
+ expect(@request.user).to eq 'joe '
90
+ expect(@request.password).to eq 'pass1'
94
91
  end
95
92
 
96
93
  it "doesn't overwrite user and password (which may have already been set by the Resource constructor) if there is no user/password in the url" do
97
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil))
98
- @request = RestClient::Request.new(:method => 'get', :url => 'example.com', :user => 'beth', :password => 'pass2')
99
- @request.parse_url_with_auth('http://example.com/resource')
100
- @request.user.should eq 'beth'
101
- @request.password.should eq 'pass2'
94
+ request = RestClient::Request.new(method: :get, url: 'http://example.com/resource', user: 'beth', password: 'pass2')
95
+ expect(request.user).to eq 'beth'
96
+ expect(request.password).to eq 'pass2'
97
+ end
98
+
99
+ it 'uses the username and password from the URL' do
100
+ request = RestClient::Request.new(method: :get, url: 'http://person:secret@example.com/resource')
101
+ expect(request.user).to eq 'person'
102
+ expect(request.password).to eq 'secret'
103
+ end
104
+
105
+ it 'overrides URL user/pass with explicit options' do
106
+ request = RestClient::Request.new(method: :get, url: 'http://person:secret@example.com/resource', user: 'beth', password: 'pass2')
107
+ expect(request.user).to eq 'beth'
108
+ expect(request.password).to eq 'pass2'
102
109
  end
103
110
  end
104
111
 
105
112
  it "correctly formats cookies provided to the constructor" do
106
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil))
107
- @request = RestClient::Request.new(:method => 'get', :url => 'example.com', :cookies => {:session_id => '1', :user_id => "someone" })
108
- @request.should_receive(:default_headers).and_return({'Foo' => 'bar'})
109
- @request.make_headers({}).should eq({ 'Foo' => 'bar', 'Cookie' => 'session_id=1; user_id=someone'})
113
+ cookies_arr = [
114
+ HTTP::Cookie.new('session_id', '1', domain: 'example.com', path: '/'),
115
+ HTTP::Cookie.new('user_id', 'someone', domain: 'example.com', path: '/'),
116
+ ]
117
+
118
+ jar = HTTP::CookieJar.new
119
+ cookies_arr.each {|c| jar << c }
120
+
121
+ # test Hash, HTTP::CookieJar, and Array<HTTP::Cookie> modes
122
+ [
123
+ {session_id: '1', user_id: 'someone'},
124
+ jar,
125
+ cookies_arr
126
+ ].each do |cookies|
127
+ [true, false].each do |in_headers|
128
+ if in_headers
129
+ opts = {headers: {cookies: cookies}}
130
+ else
131
+ opts = {cookies: cookies}
132
+ end
133
+
134
+ request = RestClient::Request.new(method: :get, url: 'example.com', **opts)
135
+ expect(request).to receive(:default_headers).and_return({'Foo' => 'bar'})
136
+ expect(request.make_headers({})).to eq({'Foo' => 'bar', 'Cookie' => 'session_id=1; user_id=someone'})
137
+ expect(request.make_cookie_header).to eq 'session_id=1; user_id=someone'
138
+ expect(request.cookies).to eq({'session_id' => '1', 'user_id' => 'someone'})
139
+ expect(request.cookie_jar.cookies.length).to eq 2
140
+ expect(request.cookie_jar.object_id).not_to eq jar.object_id # make sure we dup it
141
+ end
142
+ end
143
+
144
+ # test with no cookies
145
+ request = RestClient::Request.new(method: :get, url: 'example.com')
146
+ expect(request).to receive(:default_headers).and_return({'Foo' => 'bar'})
147
+ expect(request.make_headers({})).to eq({'Foo' => 'bar'})
148
+ expect(request.make_cookie_header).to be_nil
149
+ expect(request.cookies).to eq({})
150
+ expect(request.cookie_jar.cookies.length).to eq 0
151
+ end
152
+
153
+ it 'strips out cookies set for a different domain name' do
154
+ jar = HTTP::CookieJar.new
155
+ jar << HTTP::Cookie.new('session_id', '1', domain: 'other.example.com', path: '/')
156
+ jar << HTTP::Cookie.new('user_id', 'someone', domain: 'other.example.com', path: '/')
157
+
158
+ request = RestClient::Request.new(method: :get, url: 'www.example.com', cookies: jar)
159
+ expect(request).to receive(:default_headers).and_return({'Foo' => 'bar'})
160
+ expect(request.make_headers({})).to eq({'Foo' => 'bar'})
161
+ expect(request.make_cookie_header).to eq nil
162
+ expect(request.cookies).to eq({})
163
+ expect(request.cookie_jar.cookies.length).to eq 2
164
+ end
165
+
166
+ it 'assumes default domain and path for cookies set by hash' do
167
+ request = RestClient::Request.new(method: :get, url: 'www.example.com', cookies: {'session_id' => '1'})
168
+ expect(request.cookie_jar.cookies.length).to eq 1
169
+
170
+ cookie = request.cookie_jar.cookies.first
171
+ expect(cookie).to be_a(HTTP::Cookie)
172
+ expect(cookie.domain).to eq('www.example.com')
173
+ expect(cookie.for_domain?).to be_truthy
174
+ expect(cookie.path).to eq('/')
175
+ end
176
+
177
+ it 'rejects or warns with contradictory cookie options' do
178
+ # same opt in two different places
179
+ expect {
180
+ RestClient::Request.new(method: :get, url: 'example.com',
181
+ cookies: {bar: '456'},
182
+ headers: {cookies: {foo: '123'}})
183
+ }.to raise_error(ArgumentError, /Cannot pass :cookies in Request.*headers/)
184
+
185
+ # :cookies opt and Cookie header
186
+ [
187
+ {cookies: {foo: '123'}, headers: {cookie: 'foo'}},
188
+ {cookies: {foo: '123'}, headers: {'Cookie' => 'foo'}},
189
+ {headers: {cookies: {foo: '123'}, cookie: 'foo'}},
190
+ {headers: {cookies: {foo: '123'}, 'Cookie' => 'foo'}},
191
+ ].each do |opts|
192
+ expect(fake_stderr {
193
+ RestClient::Request.new(method: :get, url: 'example.com', **opts)
194
+ }).to match(/warning: overriding "Cookie" header with :cookies option/)
195
+ end
110
196
  end
111
197
 
112
198
  it "does not escape or unescape cookies" do
113
199
  cookie = 'Foo%20:Bar%0A~'
114
200
  @request = RestClient::Request.new(:method => 'get', :url => 'example.com',
115
201
  :cookies => {:test => cookie})
116
- @request.should_receive(:default_headers).and_return({'Foo' => 'bar'})
117
- @request.make_headers({}).should eq({
202
+ expect(@request).to receive(:default_headers).and_return({'Foo' => 'bar'})
203
+ expect(@request.make_headers({})).to eq({
118
204
  'Foo' => 'bar',
119
205
  'Cookie' => "test=#{cookie}"
120
206
  })
@@ -124,244 +210,409 @@ describe RestClient::Request do
124
210
  # Cookie validity is something of a mess, but we should reject the worst of
125
211
  # the RFC 6265 (4.1.1) prohibited characters such as control characters.
126
212
 
127
- ['', 'foo=bar', 'foo;bar', "foo\nbar"].each do |cookie_name|
128
- lambda {
213
+ ['foo=bar', 'foo;bar', "foo\nbar"].each do |cookie_name|
214
+ expect {
129
215
  RestClient::Request.new(:method => 'get', :url => 'example.com',
130
216
  :cookies => {cookie_name => 'value'})
131
- }.should raise_error(ArgumentError, /\AInvalid cookie name/)
217
+ }.to raise_error(ArgumentError, /\AInvalid cookie name/i)
132
218
  end
219
+
220
+ cookie_name = ''
221
+ expect {
222
+ RestClient::Request.new(:method => 'get', :url => 'example.com',
223
+ :cookies => {cookie_name => 'value'})
224
+ }.to raise_error(ArgumentError, /cookie name cannot be empty/i)
133
225
  end
134
226
 
135
227
  it "rejects cookie values containing invalid characters" do
136
228
  # Cookie validity is something of a mess, but we should reject the worst of
137
229
  # the RFC 6265 (4.1.1) prohibited characters such as control characters.
138
230
 
139
- ['foo,bar', 'foo;bar', "foo\nbar"].each do |cookie_value|
140
- lambda {
231
+ ["foo\tbar", "foo\nbar"].each do |cookie_value|
232
+ expect {
141
233
  RestClient::Request.new(:method => 'get', :url => 'example.com',
142
234
  :cookies => {'test' => cookie_value})
143
- }.should raise_error(ArgumentError, /\AInvalid cookie value/)
235
+ }.to raise_error(ArgumentError, /\AInvalid cookie value/i)
144
236
  end
145
237
  end
146
238
 
239
+ it 'warns when overriding existing headers via payload' do
240
+ expect(fake_stderr {
241
+ RestClient::Request.new(method: :post, url: 'example.com',
242
+ payload: {'foo' => 1}, headers: {content_type: :json})
243
+ }).to match(/warning: Overriding "Content-Type" header/i)
244
+ expect(fake_stderr {
245
+ RestClient::Request.new(method: :post, url: 'example.com',
246
+ payload: {'foo' => 1}, headers: {'Content-Type' => 'application/json'})
247
+ }).to match(/warning: Overriding "Content-Type" header/i)
248
+
249
+ expect(fake_stderr {
250
+ RestClient::Request.new(method: :post, url: 'example.com',
251
+ payload: '123456', headers: {content_length: '20'})
252
+ }).to match(/warning: Overriding "Content-Length" header/i)
253
+ expect(fake_stderr {
254
+ RestClient::Request.new(method: :post, url: 'example.com',
255
+ payload: '123456', headers: {'Content-Length' => '20'})
256
+ }).to match(/warning: Overriding "Content-Length" header/i)
257
+ end
258
+
259
+ it "does not warn when overriding user header with header derived from payload if those header values were identical" do
260
+ expect(fake_stderr {
261
+ RestClient::Request.new(method: :post, url: 'example.com',
262
+ payload: {'foo' => '123456'}, headers: { 'Content-Type' => 'application/x-www-form-urlencoded' })
263
+ }).not_to match(/warning: Overriding "Content-Type" header/i)
264
+ end
265
+
266
+ it 'does not warn for a normal looking payload' do
267
+ expect(fake_stderr {
268
+ RestClient::Request.new(method: :post, url: 'example.com', payload: 'payload')
269
+ RestClient::Request.new(method: :post, url: 'example.com', payload: 'payload', headers: {content_type: :json})
270
+ RestClient::Request.new(method: :post, url: 'example.com', payload: {'foo' => 'bar'})
271
+ }).to eq ''
272
+ end
273
+
147
274
  it "uses netrc credentials" do
148
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil, :host => 'example.com'))
149
- Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
150
- @request.parse_url_with_auth('http://example.com/resource')
151
- @request.user.should eq 'a'
152
- @request.password.should eq 'b'
275
+ expect(Netrc).to receive(:read).and_return('example.com' => ['a', 'b'])
276
+ request = RestClient::Request.new(:method => :put, :url => 'http://example.com/', :payload => 'payload')
277
+ expect(request.user).to eq 'a'
278
+ expect(request.password).to eq 'b'
153
279
  end
154
280
 
155
281
  it "uses credentials in the url in preference to netrc" do
156
- URI.stub(:parse).and_return(double('uri', :user => 'joe%20', :password => 'pass1', :host => 'example.com'))
157
- Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
158
- @request.parse_url_with_auth('http://joe%20:pass1@example.com/resource')
159
- @request.user.should eq 'joe '
160
- @request.password.should eq 'pass1'
282
+ allow(Netrc).to receive(:read).and_return('example.com' => ['a', 'b'])
283
+ request = RestClient::Request.new(:method => :put, :url => 'http://joe%20:pass1@example.com/', :payload => 'payload')
284
+ expect(request.user).to eq 'joe '
285
+ expect(request.password).to eq 'pass1'
161
286
  end
162
287
 
163
288
  it "determines the Net::HTTP class to instantiate by the method name" do
164
- @request.net_http_request_class(:put).should eq Net::HTTP::Put
289
+ expect(@request.net_http_request_class(:put)).to eq Net::HTTP::Put
165
290
  end
166
291
 
167
292
  describe "user headers" do
168
293
  it "merges user headers with the default headers" do
169
- @request.should_receive(:default_headers).and_return({ :accept => '*/*; q=0.5, application/xml', :accept_encoding => 'gzip, deflate' })
294
+ expect(@request).to receive(:default_headers).and_return({:accept => '*/*'})
170
295
  headers = @request.make_headers("Accept" => "application/json", :accept_encoding => 'gzip')
171
- headers.should have_key "Accept-Encoding"
172
- headers["Accept-Encoding"].should eq "gzip"
173
- headers.should have_key "Accept"
174
- headers["Accept"].should eq "application/json"
296
+ expect(headers).to have_key "Accept-Encoding"
297
+ expect(headers["Accept-Encoding"]).to eq "gzip"
298
+ expect(headers).to have_key "Accept"
299
+ expect(headers["Accept"]).to eq "application/json"
175
300
  end
176
301
 
177
302
  it "prefers the user header when the same header exists in the defaults" do
178
- @request.should_receive(:default_headers).and_return({ '1' => '2' })
303
+ expect(@request).to receive(:default_headers).and_return({ '1' => '2' })
179
304
  headers = @request.make_headers('1' => '3')
180
- headers.should have_key('1')
181
- headers['1'].should eq '3'
305
+ expect(headers).to have_key('1')
306
+ expect(headers['1']).to eq '3'
182
307
  end
183
308
 
184
309
  it "converts user headers to string before calling CGI::unescape which fails on non string values" do
185
- @request.should_receive(:default_headers).and_return({ '1' => '2' })
310
+ expect(@request).to receive(:default_headers).and_return({ '1' => '2' })
186
311
  headers = @request.make_headers('1' => 3)
187
- headers.should have_key('1')
188
- headers['1'].should eq '3'
312
+ expect(headers).to have_key('1')
313
+ expect(headers['1']).to eq '3'
189
314
  end
190
315
  end
191
316
 
192
317
  describe "header symbols" do
193
318
 
194
319
  it "converts header symbols from :content_type to 'Content-Type'" do
195
- @request.should_receive(:default_headers).and_return({})
320
+ expect(@request).to receive(:default_headers).and_return({})
196
321
  headers = @request.make_headers(:content_type => 'abc')
197
- headers.should have_key('Content-Type')
198
- headers['Content-Type'].should eq 'abc'
322
+ expect(headers).to have_key('Content-Type')
323
+ expect(headers['Content-Type']).to eq 'abc'
199
324
  end
200
325
 
201
326
  it "converts content-type from extension to real content-type" do
202
- @request.should_receive(:default_headers).and_return({})
327
+ expect(@request).to receive(:default_headers).and_return({})
203
328
  headers = @request.make_headers(:content_type => 'json')
204
- headers.should have_key('Content-Type')
205
- headers['Content-Type'].should eq 'application/json'
329
+ expect(headers).to have_key('Content-Type')
330
+ expect(headers['Content-Type']).to eq 'application/json'
206
331
  end
207
332
 
208
333
  it "converts accept from extension(s) to real content-type(s)" do
209
- @request.should_receive(:default_headers).and_return({})
334
+ expect(@request).to receive(:default_headers).and_return({})
210
335
  headers = @request.make_headers(:accept => 'json, mp3')
211
- headers.should have_key('Accept')
212
- headers['Accept'].should eq 'application/json, audio/mpeg'
336
+ expect(headers).to have_key('Accept')
337
+ expect(headers['Accept']).to eq 'application/json, audio/mpeg'
213
338
 
214
- @request.should_receive(:default_headers).and_return({})
339
+ expect(@request).to receive(:default_headers).and_return({})
215
340
  headers = @request.make_headers(:accept => :json)
216
- headers.should have_key('Accept')
217
- headers['Accept'].should eq 'application/json'
341
+ expect(headers).to have_key('Accept')
342
+ expect(headers['Accept']).to eq 'application/json'
218
343
  end
219
344
 
220
345
  it "only convert symbols in header" do
221
- @request.should_receive(:default_headers).and_return({})
346
+ expect(@request).to receive(:default_headers).and_return({})
222
347
  headers = @request.make_headers({:foo_bar => 'value', "bar_bar" => 'value'})
223
- headers['Foo-Bar'].should eq 'value'
224
- headers['bar_bar'].should eq 'value'
348
+ expect(headers['Foo-Bar']).to eq 'value'
349
+ expect(headers['bar_bar']).to eq 'value'
225
350
  end
226
351
 
227
352
  it "converts header values to strings" do
228
- @request.make_headers('A' => 1)['A'].should eq '1'
353
+ expect(@request.make_headers('A' => 1)['A']).to eq '1'
229
354
  end
230
355
  end
231
356
 
232
357
  it "executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
233
- @request.should_receive(:parse_url_with_auth).with('http://some/resource').and_return(@uri)
234
358
  klass = double("net:http class")
235
- @request.should_receive(:net_http_request_class).with(:put).and_return(klass)
236
- klass.should_receive(:new).and_return('result')
237
- @request.should_receive(:transmit).with(@uri, 'result', kind_of(RestClient::Payload::Base))
359
+ expect(@request).to receive(:net_http_request_class).with('put').and_return(klass)
360
+ expect(klass).to receive(:new).and_return('result')
361
+ expect(@request).to receive(:transmit).with(@request.uri, 'result', kind_of(RestClient::Payload::Base))
362
+ @request.execute
363
+ end
364
+
365
+ it "IPv6: executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
366
+ @request = RestClient::Request.new(:method => :put, :url => 'http://[::1]/some/resource', :payload => 'payload')
367
+ klass = double("net:http class")
368
+ expect(@request).to receive(:net_http_request_class).with('put').and_return(klass)
369
+
370
+ if RUBY_VERSION >= "2.0.0"
371
+ expect(klass).to receive(:new).with(kind_of(URI), kind_of(Hash)).and_return('result')
372
+ else
373
+ expect(klass).to receive(:new).with(kind_of(String), kind_of(Hash)).and_return('result')
374
+ end
375
+
376
+ expect(@request).to receive(:transmit)
238
377
  @request.execute
239
378
  end
240
379
 
380
+ # TODO: almost none of these tests should actually call transmit, which is
381
+ # part of the private API
382
+
241
383
  it "transmits the request with Net::HTTP" do
242
- @http.should_receive(:request).with('req', 'payload')
243
- @request.should_receive(:process_result)
244
- @request.transmit(@uri, 'req', 'payload')
384
+ expect(@http).to receive(:request).with('req', 'payload')
385
+ expect(@request).to receive(:process_result)
386
+ @request.send(:transmit, @uri, 'req', 'payload')
245
387
  end
246
388
 
389
+ # TODO: most of these payload tests are historical relics that actually
390
+ # belong in payload_spec.rb. Or we need new tests that actually cover the way
391
+ # that Request#initialize or Request#execute uses the payload.
247
392
  describe "payload" do
248
393
  it "sends nil payloads" do
249
- @http.should_receive(:request).with('req', nil)
250
- @request.should_receive(:process_result)
251
- @request.stub(:response_log)
252
- @request.transmit(@uri, 'req', nil)
394
+ expect(@http).to receive(:request).with('req', nil)
395
+ expect(@request).to receive(:process_result)
396
+ allow(@request).to receive(:response_log)
397
+ @request.send(:transmit, @uri, 'req', nil)
253
398
  end
254
399
 
255
400
  it "passes non-hash payloads straight through" do
256
- @request.process_payload("x").should eq "x"
401
+ expect(RestClient::Payload.generate("x").to_s).to eq "x"
257
402
  end
258
403
 
259
404
  it "converts a hash payload to urlencoded data" do
260
- @request.process_payload(:a => 'b c+d').should eq "a=b%20c%2Bd"
405
+ expect(RestClient::Payload.generate(:a => 'b c+d').to_s).to eq "a=b+c%2Bd"
261
406
  end
262
407
 
263
408
  it "accepts nested hashes in payload" do
264
- payload = @request.process_payload(:user => { :name => 'joe', :location => { :country => 'USA', :state => 'CA' }})
265
- payload.should include('user[name]=joe')
266
- payload.should include('user[location][country]=USA')
267
- payload.should include('user[location][state]=CA')
409
+ payload = RestClient::Payload.generate(:user => { :name => 'joe', :location => { :country => 'USA', :state => 'CA' }}).to_s
410
+ expect(payload).to include('user[name]=joe')
411
+ expect(payload).to include('user[location][country]=USA')
412
+ expect(payload).to include('user[location][state]=CA')
268
413
  end
269
414
  end
270
415
 
271
416
  it "set urlencoded content_type header on hash payloads" do
272
- @request.process_payload(:a => 1)
273
- @request.headers[:content_type].should eq 'application/x-www-form-urlencoded'
417
+ req = RestClient::Request.new(method: :post, url: 'http://some/resource', payload: {a: 1})
418
+ expect(req.processed_headers.fetch('Content-Type')).to eq 'application/x-www-form-urlencoded'
274
419
  end
275
420
 
276
421
  describe "credentials" do
277
422
  it "sets up the credentials prior to the request" do
278
- @http.stub(:request)
423
+ allow(@http).to receive(:request)
279
424
 
280
- @request.stub(:process_result)
281
- @request.stub(:response_log)
425
+ allow(@request).to receive(:process_result)
426
+ allow(@request).to receive(:response_log)
282
427
 
283
- @request.stub(:user).and_return('joe')
284
- @request.stub(:password).and_return('mypass')
285
- @request.should_receive(:setup_credentials).with('req')
428
+ allow(@request).to receive(:user).and_return('joe')
429
+ allow(@request).to receive(:password).and_return('mypass')
430
+ expect(@request).to receive(:setup_credentials).with('req')
286
431
 
287
- @request.transmit(@uri, 'req', nil)
432
+ @request.send(:transmit, @uri, 'req', nil)
288
433
  end
289
434
 
290
435
  it "does not attempt to send any credentials if user is nil" do
291
- @request.stub(:user).and_return(nil)
436
+ allow(@request).to receive(:user).and_return(nil)
292
437
  req = double("request")
293
- req.should_not_receive(:basic_auth)
294
- @request.setup_credentials(req)
438
+ expect(req).not_to receive(:basic_auth)
439
+ @request.send(:setup_credentials, req)
295
440
  end
296
441
 
297
442
  it "setup credentials when there's a user" do
298
- @request.stub(:user).and_return('joe')
299
- @request.stub(:password).and_return('mypass')
443
+ allow(@request).to receive(:user).and_return('joe')
444
+ allow(@request).to receive(:password).and_return('mypass')
300
445
  req = double("request")
301
- req.should_receive(:basic_auth).with('joe', 'mypass')
302
- @request.setup_credentials(req)
446
+ expect(req).to receive(:basic_auth).with('joe', 'mypass')
447
+ @request.send(:setup_credentials, req)
448
+ end
449
+
450
+ it "does not attempt to send credentials if Authorization header is set" do
451
+ ['Authorization', 'authorization', 'auTHORization', :authorization].each do |authorization|
452
+ headers = {authorization => 'Token abc123'}
453
+ request = RestClient::Request.new(method: :get, url: 'http://some/resource', headers: headers, user: 'joe', password: 'mypass')
454
+ req = double("net::http request")
455
+ expect(req).not_to receive(:basic_auth)
456
+ request.send(:setup_credentials, req)
457
+ end
303
458
  end
304
459
  end
305
460
 
306
461
  it "catches EOFError and shows the more informative ServerBrokeConnection" do
307
- @http.stub(:request).and_raise(EOFError)
308
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::ServerBrokeConnection)
462
+ allow(@http).to receive(:request).and_raise(EOFError)
463
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::ServerBrokeConnection)
309
464
  end
310
465
 
311
466
  it "catches OpenSSL::SSL::SSLError and raise it back without more informative message" do
312
- @http.stub(:request).and_raise(OpenSSL::SSL::SSLError)
313
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(OpenSSL::SSL::SSLError)
467
+ allow(@http).to receive(:request).and_raise(OpenSSL::SSL::SSLError)
468
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(OpenSSL::SSL::SSLError)
469
+ end
470
+
471
+ it "catches Timeout::Error and raise the more informative ReadTimeout" do
472
+ allow(@http).to receive(:request).and_raise(Timeout::Error)
473
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout)
474
+ end
475
+
476
+ it "catches Errno::ETIMEDOUT and raise the more informative ReadTimeout" do
477
+ allow(@http).to receive(:request).and_raise(Errno::ETIMEDOUT)
478
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout)
314
479
  end
315
480
 
316
- it "catches Timeout::Error and raise the more informative RequestTimeout" do
317
- @http.stub(:request).and_raise(Timeout::Error)
318
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
481
+ it "catches Net::ReadTimeout and raises RestClient's ReadTimeout",
482
+ :if => defined?(Net::ReadTimeout) do
483
+ allow(@http).to receive(:request).and_raise(Net::ReadTimeout)
484
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout)
319
485
  end
320
486
 
321
- it "catches Timeout::Error and raise the more informative RequestTimeout" do
322
- @http.stub(:request).and_raise(Errno::ETIMEDOUT)
323
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
487
+ it "catches Net::OpenTimeout and raises RestClient's OpenTimeout",
488
+ :if => defined?(Net::OpenTimeout) do
489
+ allow(@http).to receive(:request).and_raise(Net::OpenTimeout)
490
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::OpenTimeout)
324
491
  end
325
492
 
493
+ it "uses correct error message for ReadTimeout",
494
+ :if => defined?(Net::ReadTimeout) do
495
+ allow(@http).to receive(:request).and_raise(Net::ReadTimeout)
496
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::ReadTimeout, 'Timed out reading data from server')
497
+ end
498
+
499
+ it "uses correct error message for OpenTimeout",
500
+ :if => defined?(Net::OpenTimeout) do
501
+ allow(@http).to receive(:request).and_raise(Net::OpenTimeout)
502
+ expect { @request.send(:transmit, @uri, 'req', nil) }.to raise_error(RestClient::Exceptions::OpenTimeout, 'Timed out connecting to server')
503
+ end
504
+
505
+
326
506
  it "class method execute wraps constructor" do
327
507
  req = double("rest request")
328
- RestClient::Request.should_receive(:new).with(1 => 2).and_return(req)
329
- req.should_receive(:execute)
508
+ expect(RestClient::Request).to receive(:new).with(1 => 2).and_return(req)
509
+ expect(req).to receive(:execute)
330
510
  RestClient::Request.execute(1 => 2)
331
511
  end
332
512
 
333
513
  describe "exception" do
334
514
  it "raises Unauthorized when the response is 401" do
335
- res = double('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
336
- lambda { @request.process_result(res) }.should raise_error(RestClient::Unauthorized)
515
+ res = res_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
516
+ expect { @request.send(:process_result, res, Time.now) }.to raise_error(RestClient::Unauthorized)
337
517
  end
338
518
 
339
519
  it "raises ResourceNotFound when the response is 404" do
340
- res = double('response', :code => '404', :[] => ['content-encoding' => ''], :body => '' )
341
- lambda { @request.process_result(res) }.should raise_error(RestClient::ResourceNotFound)
520
+ res = res_double(:code => '404', :[] => ['content-encoding' => ''], :body => '' )
521
+ expect { @request.send(:process_result, res, Time.now) }.to raise_error(RestClient::ResourceNotFound)
342
522
  end
343
523
 
344
524
  it "raises RequestFailed otherwise" do
345
- res = double('response', :code => '500', :[] => ['content-encoding' => ''], :body => '' )
346
- lambda { @request.process_result(res) }.should raise_error(RestClient::InternalServerError)
525
+ res = res_double(:code => '500', :[] => ['content-encoding' => ''], :body => '' )
526
+ expect { @request.send(:process_result, res, Time.now) }.to raise_error(RestClient::InternalServerError)
347
527
  end
348
528
  end
349
529
 
350
530
  describe "block usage" do
351
531
  it "returns what asked to" do
352
- res = double('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
353
- @request.process_result(res){|response, request| "foo"}.should eq "foo"
532
+ res = res_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
533
+ expect(@request.send(:process_result, res, Time.now){|response, request| "foo"}).to eq "foo"
354
534
  end
355
535
  end
356
536
 
357
537
  describe "proxy" do
538
+ before do
539
+ # unstub Net::HTTP creation since we need to test it
540
+ allow(Net::HTTP).to receive(:new).and_call_original
541
+
542
+ @proxy_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
543
+ end
544
+
358
545
  it "creates a proxy class if a proxy url is given" do
359
- RestClient.stub(:proxy).and_return("http://example.com/")
360
- @request.net_http_class.proxy_class?.should be_true
546
+ allow(RestClient).to receive(:proxy).and_return("http://example.com/")
547
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
548
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be true
549
+ end
550
+
551
+ it "creates a proxy class with the correct address if a IPv6 proxy url is given" do
552
+ allow(RestClient).to receive(:proxy).and_return("http://[::1]/")
553
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
554
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be true
555
+ expect(@proxy_req.net_http_object('host', 80).proxy_address).to eq('::1')
361
556
  end
362
557
 
363
558
  it "creates a non-proxy class if a proxy url is not given" do
364
- @request.net_http_class.proxy_class?.should be_false
559
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be_falsey
560
+ end
561
+
562
+ it "disables proxy on a per-request basis" do
563
+ allow(RestClient).to receive(:proxy).and_return('http://example.com')
564
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
565
+ expect(@proxy_req.net_http_object('host', 80).proxy?).to be true
566
+
567
+ disabled_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
568
+ expect(disabled_req.net_http_object('host', 80).proxy?).to be_falsey
569
+ end
570
+
571
+ it "sets proxy on a per-request basis" do
572
+ expect(@proxy_req.net_http_object('some', 80).proxy?).to be_falsey
573
+
574
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://example.com')
575
+ expect(req.net_http_object('host', 80).proxy?).to be true
576
+ end
577
+
578
+ it "overrides proxy from environment", if: RUBY_VERSION >= '2.0' do
579
+ allow(ENV).to receive(:[]).with("http_proxy").and_return("http://127.0.0.1")
580
+ allow(ENV).to receive(:[]).with("no_proxy").and_return(nil)
581
+ allow(ENV).to receive(:[]).with("NO_PROXY").and_return(nil)
582
+ allow(Netrc).to receive(:read).and_return({})
583
+
584
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
585
+ obj = req.net_http_object('host', 80)
586
+ expect(obj.proxy?).to be true
587
+ expect(obj.proxy_address).to eq '127.0.0.1'
588
+
589
+ # test original method .proxy?
590
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
591
+ obj = req.net_http_object('host', 80)
592
+ expect(obj.proxy?).to be_falsey
593
+
594
+ # stub RestClient.proxy_set? to peek into implementation
595
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
596
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
597
+ obj = req.net_http_object('host', 80)
598
+ expect(obj.proxy?).to be_falsey
599
+
600
+ # test stubbed Net::HTTP.new
601
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
602
+ expect(Net::HTTP).to receive(:new).with('host', 80, nil, nil, nil, nil)
603
+ req.net_http_object('host', 80)
604
+ end
605
+
606
+ it "overrides global proxy with per-request proxy" do
607
+ allow(RestClient).to receive(:proxy).and_return('http://example.com')
608
+ allow(RestClient).to receive(:proxy_set?).and_return(true)
609
+ obj = @proxy_req.net_http_object('host', 80)
610
+ expect(obj.proxy?).to be true
611
+ expect(obj.proxy_address).to eq 'example.com'
612
+
613
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://127.0.0.1/')
614
+ expect(req.net_http_object('host', 80).proxy?).to be true
615
+ expect(req.net_http_object('host', 80).proxy_address).to eq('127.0.0.1')
365
616
  end
366
617
  end
367
618
 
@@ -369,177 +620,231 @@ describe RestClient::Request do
369
620
  describe "logging" do
370
621
  it "logs a get request" do
371
622
  log = RestClient.log = []
372
- RestClient::Request.new(:method => :get, :url => 'http://url').log_request
373
- log[0].should eq %Q{RestClient.get "http://url", "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate"\n}
623
+ RestClient::Request.new(:method => :get, :url => 'http://url', :headers => {:user_agent => 'rest-client'}).log_request
624
+ expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"*/*", "User-Agent"=>"rest-client"\n}
374
625
  end
375
626
 
376
627
  it "logs a post request with a small payload" do
377
628
  log = RestClient.log = []
378
- RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo').log_request
379
- log[0].should eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"3"\n}
629
+ RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo', :headers => {:user_agent => 'rest-client'}).log_request
630
+ expect(log[0]).to eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*", "Content-Length"=>"3", "User-Agent"=>"rest-client"\n}
380
631
  end
381
632
 
382
633
  it "logs a post request with a large payload" do
383
634
  log = RestClient.log = []
384
- RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000)).log_request
385
- log[0].should eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*; q=0.5, application/xml", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"1000"\n}
635
+ RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000), :headers => {:user_agent => 'rest-client'}).log_request
636
+ expect(log[0]).to eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*", "Content-Length"=>"1000", "User-Agent"=>"rest-client"\n}
386
637
  end
387
638
 
388
639
  it "logs input headers as a hash" do
389
640
  log = RestClient.log = []
390
- RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain' }).log_request
391
- log[0].should eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "Accept-Encoding"=>"gzip, deflate"\n}
641
+ RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain', :user_agent => 'rest-client' }).log_request
642
+ expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "User-Agent"=>"rest-client"\n}
392
643
  end
393
644
 
394
645
  it "logs a response including the status code, content type, and result body size in bytes" do
395
646
  log = RestClient.log = []
396
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
397
- res.stub(:[]).with('Content-type').and_return('text/html')
398
- @request.log_response res
399
- log[0].should eq "# => 200 OK | text/html 4 bytes\n"
647
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
648
+ allow(res).to receive(:[]).with('Content-type').and_return('text/html')
649
+ response = response_from_res_double(res, @request)
650
+ response.log_response
651
+ expect(log).to eq ["# => 200 OK | text/html 4 bytes, 1.00s\n"]
400
652
  end
401
653
 
402
654
  it "logs a response with a nil Content-type" do
403
655
  log = RestClient.log = []
404
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
405
- res.stub(:[]).with('Content-type').and_return(nil)
406
- @request.log_response res
407
- log[0].should eq "# => 200 OK | 4 bytes\n"
656
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
657
+ allow(res).to receive(:[]).with('Content-type').and_return(nil)
658
+ response = response_from_res_double(res, @request)
659
+ response.log_response
660
+ expect(log).to eq ["# => 200 OK | 4 bytes, 1.00s\n"]
408
661
  end
409
662
 
410
663
  it "logs a response with a nil body" do
411
664
  log = RestClient.log = []
412
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => nil)
413
- res.stub(:[]).with('Content-type').and_return('text/html; charset=utf-8')
414
- @request.log_response res
415
- log[0].should eq "# => 200 OK | text/html 0 bytes\n"
665
+ res = res_double(code: '200', class: Net::HTTPOK, body: nil)
666
+ allow(res).to receive(:[]).with('Content-type').and_return('text/html; charset=utf-8')
667
+ response = response_from_res_double(res, @request)
668
+ response.log_response
669
+ expect(log).to eq ["# => 200 OK | text/html 0 bytes, 1.00s\n"]
670
+ end
671
+
672
+ it 'does not log request password' do
673
+ log = RestClient.log = []
674
+ RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client'}).log_request
675
+ expect(log[0]).to eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "User-Agent"=>"rest-client"\n}
676
+ end
677
+
678
+ it 'logs to a passed logger, if provided' do
679
+ logger = double('logger', '<<' => true)
680
+ expect(logger).to receive(:<<)
681
+ RestClient::Request.new(:method => :get, :url => 'http://user:password@url', log: logger).log_request
416
682
  end
417
683
  end
418
684
 
419
685
  it "strips the charset from the response content type" do
420
686
  log = RestClient.log = []
421
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
422
- res.stub(:[]).with('Content-type').and_return('text/html; charset=utf-8')
423
- @request.log_response res
424
- log[0].should eq "# => 200 OK | text/html 4 bytes\n"
687
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
688
+ allow(res).to receive(:[]).with('Content-type').and_return('text/html; charset=utf-8')
689
+ response = response_from_res_double(res, @request)
690
+ response.log_response
691
+ expect(log).to eq ["# => 200 OK | text/html 4 bytes, 1.00s\n"]
425
692
  end
426
693
 
427
694
  describe "timeout" do
428
695
  it "does not set timeouts if not specified" do
429
696
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
430
- @http.stub(:request)
431
- @request.stub(:process_result)
432
- @request.stub(:response_log)
697
+ allow(@http).to receive(:request)
698
+ allow(@request).to receive(:process_result)
699
+ allow(@request).to receive(:response_log)
433
700
 
434
- @net.should_not_receive(:read_timeout=)
435
- @net.should_not_receive(:open_timeout=)
701
+ expect(@net).not_to receive(:read_timeout=)
702
+ expect(@net).not_to receive(:open_timeout=)
436
703
 
437
- @request.transmit(@uri, 'req', nil)
704
+ @request.send(:transmit, @uri, 'req', nil)
438
705
  end
439
706
 
440
- it "set read_timeout" do
441
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
442
- @http.stub(:request)
443
- @request.stub(:process_result)
444
- @request.stub(:response_log)
707
+ it 'sets read_timeout' do
708
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => 123)
709
+ allow(@http).to receive(:request)
710
+ allow(@request).to receive(:process_result)
711
+ allow(@request).to receive(:response_log)
445
712
 
446
- @net.should_receive(:read_timeout=).with(123)
713
+ expect(@net).to receive(:read_timeout=).with(123)
447
714
 
448
- @request.transmit(@uri, 'req', nil)
715
+ @request.send(:transmit, @uri, 'req', nil)
449
716
  end
450
717
 
451
- it "set open_timeout" do
718
+ it "sets open_timeout" do
452
719
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :open_timeout => 123)
453
- @http.stub(:request)
454
- @request.stub(:process_result)
455
- @request.stub(:response_log)
720
+ allow(@http).to receive(:request)
721
+ allow(@request).to receive(:process_result)
722
+ allow(@request).to receive(:response_log)
723
+
724
+ expect(@net).to receive(:open_timeout=).with(123)
725
+
726
+ @request.send(:transmit, @uri, 'req', nil)
727
+ end
728
+
729
+ it 'sets both timeouts with :timeout' do
730
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
731
+ allow(@http).to receive(:request)
732
+ allow(@request).to receive(:process_result)
733
+ allow(@request).to receive(:response_log)
456
734
 
457
- @net.should_receive(:open_timeout=).with(123)
735
+ expect(@net).to receive(:open_timeout=).with(123)
736
+ expect(@net).to receive(:read_timeout=).with(123)
458
737
 
459
- @request.transmit(@uri, 'req', nil)
738
+ @request.send(:transmit, @uri, 'req', nil)
460
739
  end
461
740
 
741
+ it 'supersedes :timeout with open/read_timeout' do
742
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123, :open_timeout => 34, :read_timeout => 56)
743
+ allow(@http).to receive(:request)
744
+ allow(@request).to receive(:process_result)
745
+ allow(@request).to receive(:response_log)
746
+
747
+ expect(@net).to receive(:open_timeout=).with(34)
748
+ expect(@net).to receive(:read_timeout=).with(56)
749
+
750
+ @request.send(:transmit, @uri, 'req', nil)
751
+ end
752
+
753
+
462
754
  it "disable timeout by setting it to nil" do
463
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => nil, :open_timeout => nil)
464
- @http.stub(:request)
465
- @request.stub(:process_result)
466
- @request.stub(:response_log)
755
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => nil, :open_timeout => nil)
756
+ allow(@http).to receive(:request)
757
+ allow(@request).to receive(:process_result)
758
+ allow(@request).to receive(:response_log)
759
+
760
+ expect(@net).to receive(:read_timeout=).with(nil)
761
+ expect(@net).to receive(:open_timeout=).with(nil)
762
+
763
+ @request.send(:transmit, @uri, 'req', nil)
764
+ end
765
+
766
+ it 'deprecated: warns when disabling timeout by setting it to -1' do
767
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1)
768
+ allow(@http).to receive(:request)
769
+ allow(@request).to receive(:process_result)
770
+ allow(@request).to receive(:response_log)
467
771
 
468
- @net.should_receive(:read_timeout=).with(nil)
469
- @net.should_receive(:open_timeout=).with(nil)
772
+ expect(@net).to receive(:read_timeout=).with(nil)
470
773
 
471
- @request.transmit(@uri, 'req', nil)
774
+ expect(fake_stderr {
775
+ @request.send(:transmit, @uri, 'req', nil)
776
+ }).to match(/^Deprecated: .*timeout.* nil instead of -1$/)
472
777
  end
473
778
 
474
779
  it "deprecated: disable timeout by setting it to -1" do
475
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => -1, :open_timeout => -1)
476
- @http.stub(:request)
477
- @request.stub(:process_result)
478
- @request.stub(:response_log)
780
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1, :open_timeout => -1)
781
+ allow(@http).to receive(:request)
782
+ allow(@request).to receive(:process_result)
783
+ allow(@request).to receive(:response_log)
479
784
 
480
- @request.should_receive(:warn)
481
- @net.should_receive(:read_timeout=).with(nil)
785
+ expect(@request).to receive(:warn)
786
+ expect(@net).to receive(:read_timeout=).with(nil)
482
787
 
483
- @request.should_receive(:warn)
484
- @net.should_receive(:open_timeout=).with(nil)
788
+ expect(@request).to receive(:warn)
789
+ expect(@net).to receive(:open_timeout=).with(nil)
485
790
 
486
- @request.transmit(@uri, 'req', nil)
791
+ @request.send(:transmit, @uri, 'req', nil)
487
792
  end
488
793
  end
489
794
 
490
795
  describe "ssl" do
491
796
  it "uses SSL when the URI refers to a https address" do
492
- @uri.stub(:is_a?).with(URI::HTTPS).and_return(true)
493
- @net.should_receive(:use_ssl=).with(true)
494
- @http.stub(:request)
495
- @request.stub(:process_result)
496
- @request.stub(:response_log)
497
- @request.transmit(@uri, 'req', 'payload')
797
+ allow(@uri).to receive(:is_a?).with(URI::HTTPS).and_return(true)
798
+ expect(@net).to receive(:use_ssl=).with(true)
799
+ allow(@http).to receive(:request)
800
+ allow(@request).to receive(:process_result)
801
+ allow(@request).to receive(:response_log)
802
+ @request.send(:transmit, @uri, 'req', 'payload')
498
803
  end
499
804
 
500
805
  it "should default to verifying ssl certificates" do
501
- @request.verify_ssl.should eq OpenSSL::SSL::VERIFY_PEER
806
+ expect(@request.verify_ssl).to eq OpenSSL::SSL::VERIFY_PEER
502
807
  end
503
808
 
504
809
  it "should have expected values for VERIFY_PEER and VERIFY_NONE" do
505
- OpenSSL::SSL::VERIFY_NONE.should eq(0)
506
- OpenSSL::SSL::VERIFY_PEER.should eq(1)
810
+ expect(OpenSSL::SSL::VERIFY_NONE).to eq(0)
811
+ expect(OpenSSL::SSL::VERIFY_PEER).to eq(1)
507
812
  end
508
813
 
509
814
  it "should set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is false" do
510
815
  @request = RestClient::Request.new(:method => :put, :verify_ssl => false, :url => 'http://some/resource', :payload => 'payload')
511
- @net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
512
- @http.stub(:request)
513
- @request.stub(:process_result)
514
- @request.stub(:response_log)
515
- @request.transmit(@uri, 'req', 'payload')
816
+ expect(@net).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
817
+ allow(@http).to receive(:request)
818
+ allow(@request).to receive(:process_result)
819
+ allow(@request).to receive(:response_log)
820
+ @request.send(:transmit, @uri, 'req', 'payload')
516
821
  end
517
822
 
518
823
  it "should not set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is true" do
519
824
  @request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload', :verify_ssl => true)
520
- @net.should_not_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
521
- @http.stub(:request)
522
- @request.stub(:process_result)
523
- @request.stub(:response_log)
524
- @request.transmit(@uri, 'req', 'payload')
825
+ expect(@net).not_to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
826
+ allow(@http).to receive(:request)
827
+ allow(@request).to receive(:process_result)
828
+ allow(@request).to receive(:response_log)
829
+ @request.send(:transmit, @uri, 'req', 'payload')
525
830
  end
526
831
 
527
832
  it "should set net.verify_mode to OpenSSL::SSL::VERIFY_PEER if verify_ssl is true" do
528
833
  @request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload', :verify_ssl => true)
529
- @net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
530
- @http.stub(:request)
531
- @request.stub(:process_result)
532
- @request.stub(:response_log)
533
- @request.transmit(@uri, 'req', 'payload')
834
+ expect(@net).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
835
+ allow(@http).to receive(:request)
836
+ allow(@request).to receive(:process_result)
837
+ allow(@request).to receive(:response_log)
838
+ @request.send(:transmit, @uri, 'req', 'payload')
534
839
  end
535
840
 
536
841
  it "should set net.verify_mode to OpenSSL::SSL::VERIFY_PEER if verify_ssl is not given" do
537
842
  @request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload')
538
- @net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
539
- @http.stub(:request)
540
- @request.stub(:process_result)
541
- @request.stub(:response_log)
542
- @request.transmit(@uri, 'req', 'payload')
843
+ expect(@net).to receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
844
+ allow(@http).to receive(:request)
845
+ allow(@request).to receive(:process_result)
846
+ allow(@request).to receive(:response_log)
847
+ @request.send(:transmit, @uri, 'req', 'payload')
543
848
  end
544
849
 
545
850
  it "should set net.verify_mode to the passed value if verify_ssl is an OpenSSL constant" do
@@ -548,15 +853,15 @@ describe RestClient::Request do
548
853
  :url => 'https://some/resource',
549
854
  :payload => 'payload',
550
855
  :verify_ssl => mode )
551
- @net.should_receive(:verify_mode=).with(mode)
552
- @http.stub(:request)
553
- @request.stub(:process_result)
554
- @request.stub(:response_log)
555
- @request.transmit(@uri, 'req', 'payload')
856
+ expect(@net).to receive(:verify_mode=).with(mode)
857
+ allow(@http).to receive(:request)
858
+ allow(@request).to receive(:process_result)
859
+ allow(@request).to receive(:response_log)
860
+ @request.send(:transmit, @uri, 'req', 'payload')
556
861
  end
557
862
 
558
863
  it "should default to not having an ssl_client_cert" do
559
- @request.ssl_client_cert.should be(nil)
864
+ expect(@request.ssl_client_cert).to be(nil)
560
865
  end
561
866
 
562
867
  it "should set the ssl_version if provided" do
@@ -566,11 +871,11 @@ describe RestClient::Request do
566
871
  :payload => 'payload',
567
872
  :ssl_version => "TLSv1"
568
873
  )
569
- @net.should_receive(:ssl_version=).with("TLSv1")
570
- @http.stub(:request)
571
- @request.stub(:process_result)
572
- @request.stub(:response_log)
573
- @request.transmit(@uri, 'req', 'payload')
874
+ expect(@net).to receive(:ssl_version=).with("TLSv1")
875
+ allow(@http).to receive(:request)
876
+ allow(@request).to receive(:process_result)
877
+ allow(@request).to receive(:response_log)
878
+ @request.send(:transmit, @uri, 'req', 'payload')
574
879
  end
575
880
 
576
881
  it "should not set the ssl_version if not provided" do
@@ -579,11 +884,11 @@ describe RestClient::Request do
579
884
  :url => 'https://some/resource',
580
885
  :payload => 'payload'
581
886
  )
582
- @net.should_not_receive(:ssl_version=).with("TLSv1")
583
- @http.stub(:request)
584
- @request.stub(:process_result)
585
- @request.stub(:response_log)
586
- @request.transmit(@uri, 'req', 'payload')
887
+ expect(@net).not_to receive(:ssl_version=).with("TLSv1")
888
+ allow(@http).to receive(:request)
889
+ allow(@request).to receive(:process_result)
890
+ allow(@request).to receive(:response_log)
891
+ @request.send(:transmit, @uri, 'req', 'payload')
587
892
  end
588
893
 
589
894
  it "should set the ssl_ciphers if provided" do
@@ -594,11 +899,11 @@ describe RestClient::Request do
594
899
  :payload => 'payload',
595
900
  :ssl_ciphers => ciphers
596
901
  )
597
- @net.should_receive(:ciphers=).with(ciphers)
598
- @http.stub(:request)
599
- @request.stub(:process_result)
600
- @request.stub(:response_log)
601
- @request.transmit(@uri, 'req', 'payload')
902
+ expect(@net).to receive(:ciphers=).with(ciphers)
903
+ allow(@http).to receive(:request)
904
+ allow(@request).to receive(:process_result)
905
+ allow(@request).to receive(:response_log)
906
+ @request.send(:transmit, @uri, 'req', 'payload')
602
907
  end
603
908
 
604
909
  it "should not set the ssl_ciphers if set to nil" do
@@ -608,61 +913,11 @@ describe RestClient::Request do
608
913
  :payload => 'payload',
609
914
  :ssl_ciphers => nil,
610
915
  )
611
- @net.should_not_receive(:ciphers=)
612
- @http.stub(:request)
613
- @request.stub(:process_result)
614
- @request.stub(:response_log)
615
- @request.transmit(@uri, 'req', 'payload')
616
- end
617
-
618
- it "should override ssl_ciphers with better defaults with weak default ciphers" do
619
- stub_const(
620
- '::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
621
- {
622
- :ssl_version=>"SSLv23",
623
- :verify_mode=>1,
624
- :ciphers=>"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
625
- :options=>-2147480577,
626
- }
627
- )
628
-
629
- @request = RestClient::Request.new(
630
- :method => :put,
631
- :url => 'https://some/resource',
632
- :payload => 'payload',
633
- )
634
-
635
- @net.should_receive(:ciphers=).with(RestClient::Request::DefaultCiphers)
636
-
637
- @http.stub(:request)
638
- @request.stub(:process_result)
639
- @request.stub(:response_log)
640
- @request.transmit(@uri, 'req', 'payload')
641
- end
642
-
643
- it "should not override ssl_ciphers with better defaults with different default ciphers" do
644
- stub_const(
645
- '::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
646
- {
647
- :ssl_version=>"SSLv23",
648
- :verify_mode=>1,
649
- :ciphers=>"HIGH:!aNULL:!eNULL:!EXPORT:!LOW:!MEDIUM:!SSLv2",
650
- :options=>-2147480577,
651
- }
652
- )
653
-
654
- @request = RestClient::Request.new(
655
- :method => :put,
656
- :url => 'https://some/resource',
657
- :payload => 'payload',
658
- )
659
-
660
- @net.should_not_receive(:ciphers=)
661
-
662
- @http.stub(:request)
663
- @request.stub(:process_result)
664
- @request.stub(:response_log)
665
- @request.transmit(@uri, 'req', 'payload')
916
+ expect(@net).not_to receive(:ciphers=)
917
+ allow(@http).to receive(:request)
918
+ allow(@request).to receive(:process_result)
919
+ allow(@request).to receive(:response_log)
920
+ @request.send(:transmit, @uri, 'req', 'payload')
666
921
  end
667
922
 
668
923
  it "should set the ssl_client_cert if provided" do
@@ -672,11 +927,11 @@ describe RestClient::Request do
672
927
  :payload => 'payload',
673
928
  :ssl_client_cert => "whatsupdoc!"
674
929
  )
675
- @net.should_receive(:cert=).with("whatsupdoc!")
676
- @http.stub(:request)
677
- @request.stub(:process_result)
678
- @request.stub(:response_log)
679
- @request.transmit(@uri, 'req', 'payload')
930
+ expect(@net).to receive(:cert=).with("whatsupdoc!")
931
+ allow(@http).to receive(:request)
932
+ allow(@request).to receive(:process_result)
933
+ allow(@request).to receive(:response_log)
934
+ @request.send(:transmit, @uri, 'req', 'payload')
680
935
  end
681
936
 
682
937
  it "should not set the ssl_client_cert if it is not provided" do
@@ -685,15 +940,15 @@ describe RestClient::Request do
685
940
  :url => 'https://some/resource',
686
941
  :payload => 'payload'
687
942
  )
688
- @net.should_not_receive(:cert=)
689
- @http.stub(:request)
690
- @request.stub(:process_result)
691
- @request.stub(:response_log)
692
- @request.transmit(@uri, 'req', 'payload')
943
+ expect(@net).not_to receive(:cert=)
944
+ allow(@http).to receive(:request)
945
+ allow(@request).to receive(:process_result)
946
+ allow(@request).to receive(:response_log)
947
+ @request.send(:transmit, @uri, 'req', 'payload')
693
948
  end
694
949
 
695
950
  it "should default to not having an ssl_client_key" do
696
- @request.ssl_client_key.should be(nil)
951
+ expect(@request.ssl_client_key).to be(nil)
697
952
  end
698
953
 
699
954
  it "should set the ssl_client_key if provided" do
@@ -703,11 +958,11 @@ describe RestClient::Request do
703
958
  :payload => 'payload',
704
959
  :ssl_client_key => "whatsupdoc!"
705
960
  )
706
- @net.should_receive(:key=).with("whatsupdoc!")
707
- @http.stub(:request)
708
- @request.stub(:process_result)
709
- @request.stub(:response_log)
710
- @request.transmit(@uri, 'req', 'payload')
961
+ expect(@net).to receive(:key=).with("whatsupdoc!")
962
+ allow(@http).to receive(:request)
963
+ allow(@request).to receive(:process_result)
964
+ allow(@request).to receive(:response_log)
965
+ @request.send(:transmit, @uri, 'req', 'payload')
711
966
  end
712
967
 
713
968
  it "should not set the ssl_client_key if it is not provided" do
@@ -716,15 +971,15 @@ describe RestClient::Request do
716
971
  :url => 'https://some/resource',
717
972
  :payload => 'payload'
718
973
  )
719
- @net.should_not_receive(:key=)
720
- @http.stub(:request)
721
- @request.stub(:process_result)
722
- @request.stub(:response_log)
723
- @request.transmit(@uri, 'req', 'payload')
974
+ expect(@net).not_to receive(:key=)
975
+ allow(@http).to receive(:request)
976
+ allow(@request).to receive(:process_result)
977
+ allow(@request).to receive(:response_log)
978
+ @request.send(:transmit, @uri, 'req', 'payload')
724
979
  end
725
980
 
726
981
  it "should default to not having an ssl_ca_file" do
727
- @request.ssl_ca_file.should be(nil)
982
+ expect(@request.ssl_ca_file).to be(nil)
728
983
  end
729
984
 
730
985
  it "should set the ssl_ca_file if provided" do
@@ -734,12 +989,12 @@ describe RestClient::Request do
734
989
  :payload => 'payload',
735
990
  :ssl_ca_file => "Certificate Authority File"
736
991
  )
737
- @net.should_receive(:ca_file=).with("Certificate Authority File")
738
- @net.should_not_receive(:cert_store=)
739
- @http.stub(:request)
740
- @request.stub(:process_result)
741
- @request.stub(:response_log)
742
- @request.transmit(@uri, 'req', 'payload')
992
+ expect(@net).to receive(:ca_file=).with("Certificate Authority File")
993
+ expect(@net).not_to receive(:cert_store=)
994
+ allow(@http).to receive(:request)
995
+ allow(@request).to receive(:process_result)
996
+ allow(@request).to receive(:response_log)
997
+ @request.send(:transmit, @uri, 'req', 'payload')
743
998
  end
744
999
 
745
1000
  it "should not set the ssl_ca_file if it is not provided" do
@@ -748,15 +1003,15 @@ describe RestClient::Request do
748
1003
  :url => 'https://some/resource',
749
1004
  :payload => 'payload'
750
1005
  )
751
- @net.should_not_receive(:ca_file=)
752
- @http.stub(:request)
753
- @request.stub(:process_result)
754
- @request.stub(:response_log)
755
- @request.transmit(@uri, 'req', 'payload')
1006
+ expect(@net).not_to receive(:ca_file=)
1007
+ allow(@http).to receive(:request)
1008
+ allow(@request).to receive(:process_result)
1009
+ allow(@request).to receive(:response_log)
1010
+ @request.send(:transmit, @uri, 'req', 'payload')
756
1011
  end
757
1012
 
758
1013
  it "should default to not having an ssl_ca_path" do
759
- @request.ssl_ca_path.should be(nil)
1014
+ expect(@request.ssl_ca_path).to be(nil)
760
1015
  end
761
1016
 
762
1017
  it "should set the ssl_ca_path if provided" do
@@ -766,12 +1021,12 @@ describe RestClient::Request do
766
1021
  :payload => 'payload',
767
1022
  :ssl_ca_path => "Certificate Authority Path"
768
1023
  )
769
- @net.should_receive(:ca_path=).with("Certificate Authority Path")
770
- @net.should_not_receive(:cert_store=)
771
- @http.stub(:request)
772
- @request.stub(:process_result)
773
- @request.stub(:response_log)
774
- @request.transmit(@uri, 'req', 'payload')
1024
+ expect(@net).to receive(:ca_path=).with("Certificate Authority Path")
1025
+ expect(@net).not_to receive(:cert_store=)
1026
+ allow(@http).to receive(:request)
1027
+ allow(@request).to receive(:process_result)
1028
+ allow(@request).to receive(:response_log)
1029
+ @request.send(:transmit, @uri, 'req', 'payload')
775
1030
  end
776
1031
 
777
1032
  it "should not set the ssl_ca_path if it is not provided" do
@@ -780,11 +1035,11 @@ describe RestClient::Request do
780
1035
  :url => 'https://some/resource',
781
1036
  :payload => 'payload'
782
1037
  )
783
- @net.should_not_receive(:ca_path=)
784
- @http.stub(:request)
785
- @request.stub(:process_result)
786
- @request.stub(:response_log)
787
- @request.transmit(@uri, 'req', 'payload')
1038
+ expect(@net).not_to receive(:ca_path=)
1039
+ allow(@http).to receive(:request)
1040
+ allow(@request).to receive(:process_result)
1041
+ allow(@request).to receive(:response_log)
1042
+ @request.send(:transmit, @uri, 'req', 'payload')
788
1043
  end
789
1044
 
790
1045
  it "should set the ssl_cert_store if provided" do
@@ -797,13 +1052,13 @@ describe RestClient::Request do
797
1052
  :payload => 'payload',
798
1053
  :ssl_cert_store => store
799
1054
  )
800
- @net.should_receive(:cert_store=).with(store)
801
- @net.should_not_receive(:ca_path=)
802
- @net.should_not_receive(:ca_file=)
803
- @http.stub(:request)
804
- @request.stub(:process_result)
805
- @request.stub(:response_log)
806
- @request.transmit(@uri, 'req', 'payload')
1055
+ expect(@net).to receive(:cert_store=).with(store)
1056
+ expect(@net).not_to receive(:ca_path=)
1057
+ expect(@net).not_to receive(:ca_file=)
1058
+ allow(@http).to receive(:request)
1059
+ allow(@request).to receive(:process_result)
1060
+ allow(@request).to receive(:response_log)
1061
+ @request.send(:transmit, @uri, 'req', 'payload')
807
1062
  end
808
1063
 
809
1064
  it "should by default set the ssl_cert_store if no CA info is provided" do
@@ -812,13 +1067,13 @@ describe RestClient::Request do
812
1067
  :url => 'https://some/resource',
813
1068
  :payload => 'payload'
814
1069
  )
815
- @net.should_receive(:cert_store=)
816
- @net.should_not_receive(:ca_path=)
817
- @net.should_not_receive(:ca_file=)
818
- @http.stub(:request)
819
- @request.stub(:process_result)
820
- @request.stub(:response_log)
821
- @request.transmit(@uri, 'req', 'payload')
1070
+ expect(@net).to receive(:cert_store=)
1071
+ expect(@net).not_to receive(:ca_path=)
1072
+ expect(@net).not_to receive(:ca_file=)
1073
+ allow(@http).to receive(:request)
1074
+ allow(@request).to receive(:process_result)
1075
+ allow(@request).to receive(:response_log)
1076
+ @request.send(:transmit, @uri, 'req', 'payload')
822
1077
  end
823
1078
 
824
1079
  it "should not set the ssl_cert_store if it is set falsy" do
@@ -828,11 +1083,11 @@ describe RestClient::Request do
828
1083
  :payload => 'payload',
829
1084
  :ssl_cert_store => nil,
830
1085
  )
831
- @net.should_not_receive(:cert_store=)
832
- @http.stub(:request)
833
- @request.stub(:process_result)
834
- @request.stub(:response_log)
835
- @request.transmit(@uri, 'req', 'payload')
1086
+ expect(@net).not_to receive(:cert_store=)
1087
+ allow(@http).to receive(:request)
1088
+ allow(@request).to receive(:process_result)
1089
+ allow(@request).to receive(:response_log)
1090
+ @request.send(:transmit, @uri, 'req', 'payload')
836
1091
  end
837
1092
 
838
1093
  it "should not set the ssl_verify_callback by default" do
@@ -841,11 +1096,11 @@ describe RestClient::Request do
841
1096
  :url => 'https://some/resource',
842
1097
  :payload => 'payload',
843
1098
  )
844
- @net.should_not_receive(:verify_callback=)
845
- @http.stub(:request)
846
- @request.stub(:process_result)
847
- @request.stub(:response_log)
848
- @request.transmit(@uri, 'req', 'payload')
1099
+ expect(@net).not_to receive(:verify_callback=)
1100
+ allow(@http).to receive(:request)
1101
+ allow(@request).to receive(:process_result)
1102
+ allow(@request).to receive(:response_log)
1103
+ @request.send(:transmit, @uri, 'req', 'payload')
849
1104
  end
850
1105
 
851
1106
  it "should set the ssl_verify_callback if passed" do
@@ -856,7 +1111,7 @@ describe RestClient::Request do
856
1111
  :payload => 'payload',
857
1112
  :ssl_verify_callback => callback,
858
1113
  )
859
- @net.should_receive(:verify_callback=).with(callback)
1114
+ expect(@net).to receive(:verify_callback=).with(callback)
860
1115
 
861
1116
  # we'll read cert_store on jruby
862
1117
  # https://github.com/jruby/jruby/issues/597
@@ -864,10 +1119,10 @@ describe RestClient::Request do
864
1119
  allow(@net).to receive(:cert_store)
865
1120
  end
866
1121
 
867
- @http.stub(:request)
868
- @request.stub(:process_result)
869
- @request.stub(:response_log)
870
- @request.transmit(@uri, 'req', 'payload')
1122
+ allow(@http).to receive(:request)
1123
+ allow(@request).to receive(:process_result)
1124
+ allow(@request).to receive(:response_log)
1125
+ @request.send(:transmit, @uri, 'req', 'payload')
871
1126
  end
872
1127
 
873
1128
  # </ssl>
@@ -880,11 +1135,11 @@ describe RestClient::Request do
880
1135
  :payload => 'payload'
881
1136
  )
882
1137
  net_http_res = Net::HTTPNoContent.new("", "204", "No Content")
883
- net_http_res.stub(:read_body).and_return(nil)
884
- @http.should_receive(:request).and_return(@request.fetch_body(net_http_res))
885
- response = @request.transmit(@uri, 'req', 'payload')
886
- response.should_not be_nil
887
- response.code.should eq 204
1138
+ allow(net_http_res).to receive(:read_body).and_return(nil)
1139
+ expect(@http).to receive(:request).and_return(net_http_res)
1140
+ response = @request.send(:transmit, @uri, 'req', 'payload')
1141
+ expect(response).not_to be_nil
1142
+ expect(response.code).to eq 204
888
1143
  end
889
1144
 
890
1145
  describe "raw response" do
@@ -892,14 +1147,92 @@ describe RestClient::Request do
892
1147
  @request = RestClient::Request.new(:method => "get", :url => "example.com", :raw_response => true)
893
1148
 
894
1149
  tempfile = double("tempfile")
895
- tempfile.should_receive(:binmode)
896
- tempfile.stub(:open)
897
- tempfile.stub(:close)
898
- Tempfile.should_receive(:new).with("rest-client").and_return(tempfile)
1150
+ expect(tempfile).to receive(:binmode)
1151
+ allow(tempfile).to receive(:open)
1152
+ allow(tempfile).to receive(:close)
1153
+ expect(Tempfile).to receive(:new).with("rest-client.").and_return(tempfile)
899
1154
 
900
1155
  net_http_res = Net::HTTPOK.new(nil, "200", "body")
901
- net_http_res.stub(:read_body).and_return("body")
902
- @request.fetch_body(net_http_res)
1156
+ allow(net_http_res).to receive(:read_body).and_return("body")
1157
+ received_tempfile = @request.send(:fetch_body_to_tempfile, net_http_res)
1158
+ expect(received_tempfile).to eq tempfile
1159
+ end
1160
+ end
1161
+
1162
+ describe 'payloads' do
1163
+ it 'should accept string payloads' do
1164
+ payload = 'Foo'
1165
+ @request = RestClient::Request.new(method: :get, url: 'example.com', :payload => payload)
1166
+ expect(@request).to receive(:process_result)
1167
+ expect(@http).to receive(:request).with('req', payload)
1168
+ @request.send(:transmit, @uri, 'req', payload)
1169
+ end
1170
+
1171
+ it 'should accept streaming IO payloads' do
1172
+ payload = StringIO.new('streamed')
1173
+
1174
+ @request = RestClient::Request.new(method: :get, url: 'example.com', :payload => payload)
1175
+ expect(@request).to receive(:process_result)
1176
+
1177
+ @get = double('net::http::get')
1178
+ expect(@get).to receive(:body_stream=).with(instance_of(RestClient::Payload::Streamed))
1179
+
1180
+ allow(@request.net_http_request_class(:GET)).to receive(:new).and_return(@get)
1181
+ expect(@http).to receive(:request).with(@get, nil)
1182
+ @request.execute
1183
+ end
1184
+ end
1185
+
1186
+ describe 'constructor' do
1187
+ it 'should reject valid URIs with no hostname' do
1188
+ expect(URI.parse('http:///').hostname).to be_nil
1189
+
1190
+ expect {
1191
+ RestClient::Request.new(method: :get, url: 'http:///')
1192
+ }.to raise_error(URI::InvalidURIError, /\Abad URI/)
1193
+ end
1194
+
1195
+ it 'should reject invalid URIs' do
1196
+ expect {
1197
+ RestClient::Request.new(method: :get, url: 'http://::')
1198
+ }.to raise_error(URI::InvalidURIError)
1199
+ end
1200
+ end
1201
+
1202
+ describe 'process_url_params' do
1203
+ it 'should handle basic URL params' do
1204
+ expect(@request.process_url_params('https://example.com/foo', params: {key1: 123, key2: 'abc'})).
1205
+ to eq 'https://example.com/foo?key1=123&key2=abc'
1206
+
1207
+ expect(@request.process_url_params('https://example.com/foo', params: {'key1' => 123})).
1208
+ to eq 'https://example.com/foo?key1=123'
1209
+
1210
+ expect(@request.process_url_params('https://example.com/path',
1211
+ params: {foo: 'one two', bar: 'three + four == seven'})).
1212
+ to eq 'https://example.com/path?foo=one+two&bar=three+%2B+four+%3D%3D+seven'
1213
+ end
1214
+
1215
+ it 'should combine with & when URL params already exist' do
1216
+ expect(@request.process_url_params('https://example.com/path?foo=1', params: {bar: 2})).
1217
+ to eq 'https://example.com/path?foo=1&bar=2'
1218
+ end
1219
+
1220
+ it 'should handle complex nested URL params per Rack / Rails conventions' do
1221
+ expect(@request.process_url_params('https://example.com/', params: {
1222
+ foo: [1,2,3],
1223
+ null: nil,
1224
+ falsy: false,
1225
+ math: '2+2=4',
1226
+ nested: {'key + escaped' => 'value + escaped', other: [], arr: [1,2]},
1227
+ })).to eq 'https://example.com/?foo[]=1&foo[]=2&foo[]=3&null&falsy=false&math=2%2B2%3D4' \
1228
+ '&nested[key+%2B+escaped]=value+%2B+escaped&nested[other]' \
1229
+ '&nested[arr][]=1&nested[arr][]=2'
1230
+ end
1231
+
1232
+ it 'should handle ParamsArray objects' do
1233
+ expect(@request.process_url_params('https://example.com/',
1234
+ params: RestClient::ParamsArray.new([[:foo, 1], [:foo, 2]])
1235
+ )).to eq 'https://example.com/?foo=1&foo=2'
903
1236
  end
904
1237
  end
905
1238
  end