rest-client 2.0.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 (43) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/.mailmap +10 -0
  4. data/.rubocop +2 -0
  5. data/.rubocop-disables.yml +46 -44
  6. data/.rubocop.yml +5 -0
  7. data/.travis.yml +31 -17
  8. data/AUTHORS +8 -0
  9. data/README.md +126 -9
  10. data/Rakefile +12 -4
  11. data/history.md +53 -0
  12. data/lib/restclient.rb +0 -1
  13. data/lib/restclient/abstract_response.rb +28 -2
  14. data/lib/restclient/exceptions.rb +3 -3
  15. data/lib/restclient/payload.rb +29 -4
  16. data/lib/restclient/raw_response.rb +17 -6
  17. data/lib/restclient/request.rb +94 -67
  18. data/lib/restclient/resource.rb +16 -6
  19. data/lib/restclient/response.rb +14 -4
  20. data/lib/restclient/utils.rb +47 -8
  21. data/lib/restclient/version.rb +2 -2
  22. data/rest-client.gemspec +3 -2
  23. data/spec/ISS.jpg +0 -0
  24. data/spec/helpers.rb +37 -5
  25. data/spec/integration/capath_digicert/3513523f.0 +22 -0
  26. data/spec/integration/capath_digicert/399e7759.0 +22 -0
  27. data/spec/integration/capath_digicert/digicert.crt +20 -17
  28. data/spec/integration/certs/digicert.crt +20 -17
  29. data/spec/integration/httpbin_spec.rb +41 -0
  30. data/spec/integration/integration_spec.rb +0 -7
  31. data/spec/unit/abstract_response_spec.rb +7 -7
  32. data/spec/unit/payload_spec.rb +51 -19
  33. data/spec/unit/raw_response_spec.rb +6 -2
  34. data/spec/unit/request2_spec.rb +8 -8
  35. data/spec/unit/request_spec.rb +53 -65
  36. data/spec/unit/resource_spec.rb +7 -7
  37. data/spec/unit/response_spec.rb +33 -22
  38. data/spec/unit/restclient_spec.rb +3 -2
  39. data/spec/unit/utils_spec.rb +10 -10
  40. metadata +34 -13
  41. data/spec/integration/capath_digicert/244b5494.0 +0 -19
  42. data/spec/integration/capath_digicert/81b9768f.0 +0 -19
  43. data/spec/unit/master_shake.jpg +0 -0
@@ -12,13 +12,6 @@ describe RestClient do
12
12
  expect(response.body).to eq body
13
13
  end
14
14
 
15
- it "a simple request with gzipped content" do
16
- stub_request(:get, "www.example.com").with(:headers => { 'Accept-Encoding' => 'gzip, deflate' }).to_return(:body => "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000", :status => 200, :headers => { 'Content-Encoding' => 'gzip' } )
17
- response = RestClient.get "www.example.com"
18
- expect(response.code).to eq 200
19
- expect(response.body).to eq "i'm gziped\n"
20
- end
21
-
22
15
  it "a 404" do
23
16
  body = "Ho hai ! I'm not here !"
24
17
  stub_request(:get, "www.example.com").to_return(:body => body, :status => 404)
@@ -2,21 +2,21 @@ require_relative '_lib'
2
2
 
3
3
  describe RestClient::AbstractResponse, :include_helpers do
4
4
 
5
+ # Sample class implementing AbstractResponse used for testing.
5
6
  class MyAbstractResponse
6
7
 
7
8
  include RestClient::AbstractResponse
8
9
 
9
10
  attr_accessor :size
10
11
 
11
- def initialize net_http_res, request
12
- @net_http_res = net_http_res
13
- @request = request
12
+ def initialize(net_http_res, request)
13
+ response_set_vars(net_http_res, request, Time.now - 1)
14
14
  end
15
15
 
16
16
  end
17
17
 
18
18
  before do
19
- @net_http_res = double('net http response')
19
+ @net_http_res = res_double()
20
20
  @request = request_double(url: 'http://example.com', method: 'get')
21
21
  @response = MyAbstractResponse.new(@net_http_res, @request)
22
22
  end
@@ -92,8 +92,8 @@ describe RestClient::AbstractResponse, :include_helpers do
92
92
  it 'handles cookies when URI scheme is implicit' do
93
93
  net_http_res = double('net http response')
94
94
  expect(net_http_res).to receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
95
- request = double(url: 'example.com', uri: URI.parse('http://example.com'),
96
- method: 'get', cookie_jar: HTTP::CookieJar.new)
95
+ request = double('request', url: 'example.com', uri: URI.parse('http://example.com'),
96
+ method: 'get', cookie_jar: HTTP::CookieJar.new, redirection_history: nil)
97
97
  response = MyAbstractResponse.new(net_http_res, request)
98
98
  expect(response.cookie_jar).to be_a HTTP::CookieJar
99
99
 
@@ -135,7 +135,7 @@ describe RestClient::AbstractResponse, :include_helpers do
135
135
  end
136
136
 
137
137
  it "should gracefully handle 302 redirect with no location header" do
138
- @net_http_res = response_double(code: 302, location: nil)
138
+ @net_http_res = res_double(code: 302)
139
139
  @request = request_double()
140
140
  @response = MyAbstractResponse.new(@net_http_res, @request)
141
141
  expect(@response).to receive(:check_max_redirects).and_return('fake-check')
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative '_lib'
4
4
 
5
- describe RestClient::Payload do
5
+ describe RestClient::Payload, :include_helpers do
6
6
  context "Base Payload" do
7
7
  it "should reset stream after to_s" do
8
8
  payload = RestClient::Payload::Base.new('foobar')
@@ -80,7 +80,7 @@ describe RestClient::Payload do
80
80
  end
81
81
 
82
82
  it 'should not error on close if stream already closed' do
83
- m = RestClient::Payload::Multipart.new(:file => File.new(File.join(File.dirname(File.expand_path(__FILE__)), 'master_shake.jpg')))
83
+ m = RestClient::Payload::Multipart.new(:file => File.new(test_image_path))
84
84
  3.times {m.close}
85
85
  end
86
86
 
@@ -111,11 +111,11 @@ baz\r
111
111
  end
112
112
 
113
113
  it "should form properly separated multipart data" do
114
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
114
+ f = File.new(test_image_path)
115
115
  m = RestClient::Payload::Multipart.new({:foo => f})
116
116
  expect(m.to_s).to eq <<-EOS
117
117
  --#{m.boundary}\r
118
- Content-Disposition: form-data; name="foo"; filename="master_shake.jpg"\r
118
+ Content-Disposition: form-data; name="foo"; filename="ISS.jpg"\r
119
119
  Content-Type: image/jpeg\r
120
120
  \r
121
121
  #{File.open(f.path, 'rb'){|bin| bin.read}}\r
@@ -124,11 +124,11 @@ Content-Type: image/jpeg\r
124
124
  end
125
125
 
126
126
  it "should ignore the name attribute when it's not set" do
127
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
127
+ f = File.new(test_image_path)
128
128
  m = RestClient::Payload::Multipart.new({nil => f})
129
129
  expect(m.to_s).to eq <<-EOS
130
130
  --#{m.boundary}\r
131
- Content-Disposition: form-data; filename="master_shake.jpg"\r
131
+ Content-Disposition: form-data; filename="ISS.jpg"\r
132
132
  Content-Type: image/jpeg\r
133
133
  \r
134
134
  #{File.open(f.path, 'rb'){|bin| bin.read}}\r
@@ -137,9 +137,9 @@ Content-Type: image/jpeg\r
137
137
  end
138
138
 
139
139
  it "should detect optional (original) content type and filename" do
140
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
141
- f.instance_eval "def content_type; 'text/plain'; end"
142
- f.instance_eval "def original_filename; 'foo.txt'; end"
140
+ f = File.new(test_image_path)
141
+ expect(f).to receive(:content_type).and_return('text/plain')
142
+ expect(f).to receive(:original_filename).and_return('foo.txt')
143
143
  m = RestClient::Payload::Multipart.new({:foo => f})
144
144
  expect(m.to_s).to eq <<-EOS
145
145
  --#{m.boundary}\r
@@ -161,7 +161,7 @@ foo\r
161
161
  --#{m.boundary}--\r
162
162
  EOS
163
163
 
164
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
164
+ f = File.new(test_image_path)
165
165
  f.instance_eval "def content_type; 'text/plain'; end"
166
166
  f.instance_eval "def original_filename; 'foo.txt'; end"
167
167
  m = RestClient::Payload::Multipart.new({:foo => {:bar => f}})
@@ -177,7 +177,7 @@ Content-Type: text/plain\r
177
177
 
178
178
  it 'should correctly format hex boundary' do
179
179
  allow(SecureRandom).to receive(:base64).with(12).and_return('TGs89+ttw/xna6TV')
180
- f = File.new(File.dirname(__FILE__) + '/master_shake.jpg')
180
+ f = File.new(test_image_path)
181
181
  m = RestClient::Payload::Multipart.new({:foo => f})
182
182
  expect(m.boundary).to eq('-' * 4 + 'RubyFormBoundary' + 'TGs89AttwBxna6TV')
183
183
  end
@@ -186,10 +186,10 @@ Content-Type: text/plain\r
186
186
 
187
187
  context "streamed payloads" do
188
188
  it "should properly determine the size of file payloads" do
189
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
189
+ f = File.new(test_image_path)
190
190
  payload = RestClient::Payload.generate(f)
191
- expect(payload.size).to eq 76_988
192
- expect(payload.length).to eq 76_988
191
+ expect(payload.size).to eq 72_463
192
+ expect(payload.length).to eq 72_463
193
193
  end
194
194
 
195
195
  it "should properly determine the size of other kinds of streaming payloads" do
@@ -209,6 +209,14 @@ Content-Type: text/plain\r
209
209
  f.close
210
210
  end
211
211
  end
212
+
213
+ it "should have a closed? method" do
214
+ f = File.new(test_image_path)
215
+ payload = RestClient::Payload.generate(f)
216
+ expect(payload.closed?).to be_falsey
217
+ payload.close
218
+ expect(payload.closed?).to be_truthy
219
+ end
212
220
  end
213
221
 
214
222
  context "Payload generation" do
@@ -217,7 +225,7 @@ Content-Type: text/plain\r
217
225
  end
218
226
 
219
227
  it "should recognize multipart params" do
220
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
228
+ f = File.new(test_image_path)
221
229
  expect(RestClient::Payload.generate({"foo" => f})).to be_kind_of(RestClient::Payload::Multipart)
222
230
  end
223
231
 
@@ -226,7 +234,7 @@ Content-Type: text/plain\r
226
234
  end
227
235
 
228
236
  it "should handle deeply nested multipart" do
229
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
237
+ f = File.new(test_image_path)
230
238
  params = {foo: RestClient::ParamsArray.new({nested: f})}
231
239
  expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::Multipart)
232
240
  end
@@ -237,17 +245,17 @@ Content-Type: text/plain\r
237
245
  end
238
246
 
239
247
  it "should recognize nested multipart payloads in hashes" do
240
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
248
+ f = File.new(test_image_path)
241
249
  expect(RestClient::Payload.generate({"foo" => {"file" => f}})).to be_kind_of(RestClient::Payload::Multipart)
242
250
  end
243
251
 
244
252
  it "should recognize nested multipart payloads in arrays" do
245
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
253
+ f = File.new(test_image_path)
246
254
  expect(RestClient::Payload.generate({"foo" => [f]})).to be_kind_of(RestClient::Payload::Multipart)
247
255
  end
248
256
 
249
257
  it "should recognize file payloads that can be streamed" do
250
- f = File.new(File.dirname(__FILE__) + "/master_shake.jpg")
258
+ f = File.new(test_image_path)
251
259
  expect(RestClient::Payload.generate(f)).to be_kind_of(RestClient::Payload::Streamed)
252
260
  end
253
261
 
@@ -259,5 +267,29 @@ Content-Type: text/plain\r
259
267
  it "shouldn't treat hashes as streameable" do
260
268
  expect(RestClient::Payload.generate({"foo" => 'bar'})).to be_kind_of(RestClient::Payload::UrlEncoded)
261
269
  end
270
+
271
+ it "should recognize multipart payload wrapped in ParamsArray" do
272
+ f = File.new(test_image_path)
273
+ params = RestClient::ParamsArray.new([[:image, f]])
274
+ expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::Multipart)
275
+ end
276
+
277
+ it "should handle non-multipart payload wrapped in ParamsArray" do
278
+ params = RestClient::ParamsArray.new([[:arg, 'value1'], [:arg, 'value2']])
279
+ expect(RestClient::Payload.generate(params)).to be_kind_of(RestClient::Payload::UrlEncoded)
280
+ end
281
+
282
+ it "should pass through Payload::Base and subclasses unchanged" do
283
+ payloads = [
284
+ RestClient::Payload::Base.new('foobar'),
285
+ RestClient::Payload::UrlEncoded.new({:foo => 'bar'}),
286
+ RestClient::Payload::Streamed.new(File.new(test_image_path)),
287
+ RestClient::Payload::Multipart.new({myfile: File.new(test_image_path)}),
288
+ ]
289
+
290
+ payloads.each do |payload|
291
+ expect(RestClient::Payload.generate(payload)).to equal(payload)
292
+ end
293
+ end
262
294
  end
263
295
  end
@@ -2,9 +2,9 @@ require_relative '_lib'
2
2
 
3
3
  describe RestClient::RawResponse do
4
4
  before do
5
- @tf = double("Tempfile", :read => "the answer is 42", :open => true)
5
+ @tf = double("Tempfile", :read => "the answer is 42", :open => true, :rewind => true)
6
6
  @net_http_res = double('net http response')
7
- @request = double('http request')
7
+ @request = double('restclient request', :redirection_history => nil)
8
8
  @response = RestClient::RawResponse.new(@tf, @net_http_res, @request)
9
9
  end
10
10
 
@@ -15,4 +15,8 @@ describe RestClient::RawResponse do
15
15
  it "exposes a Tempfile" do
16
16
  expect(@response.file).to eq @tf
17
17
  end
18
+
19
+ it "includes AbstractResponse" do
20
+ expect(RestClient::RawResponse.ancestors).to include(RestClient::AbstractResponse)
21
+ end
18
22
  end
@@ -1,23 +1,23 @@
1
1
  require_relative '_lib'
2
2
 
3
- describe RestClient::Request do
3
+ describe RestClient::Request, :include_helpers do
4
4
 
5
5
  context 'params for GET requests' do
6
6
  it "manage params for get requests" do
7
- stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
7
+ stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
8
8
  expect(RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => {:a => :b, 'c' => 'd'}}).body).to eq 'foo'
9
9
 
10
- stub_request(:get, 'http://some/resource').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
10
+ stub_request(:get, 'http://some/resource').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
11
11
  expect(RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => :a}).body).to eq 'foo'
12
12
  end
13
13
 
14
14
  it 'adds GET params when params are present in URL' do
15
- stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
15
+ stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
16
16
  expect(RestClient::Request.execute(:url => 'http://some/resource?a=b', :method => :get, :headers => {:foo => :bar, :params => {:c => 'd'}}).body).to eq 'foo'
17
17
  end
18
18
 
19
19
  it 'encodes nested GET params' do
20
- stub_request(:get, 'http://some/resource?a[foo][]=1&a[foo][]=2&a[bar]&b=foo+bar&math=2+%2B+2+%3D%3D+4').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate'}).to_return(:body => 'foo', :status => 200)
20
+ stub_request(:get, 'http://some/resource?a[foo][]=1&a[foo][]=2&a[bar]&b=foo+bar&math=2+%2B+2+%3D%3D+4').with(:headers => {'Accept'=>'*/*',}).to_return(:body => 'foo', :status => 200)
21
21
  expect(RestClient::Request.execute(url: 'http://some/resource', method: :get, headers: {
22
22
  params: {
23
23
  a: {
@@ -37,15 +37,15 @@ describe RestClient::Request do
37
37
  block = proc do |http_response|
38
38
  response_value = http_response.body
39
39
  end
40
- stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
40
+ stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
41
41
  RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => {:a => :b, 'c' => 'd'}}, :block_response => block)
42
42
  expect(response_value).to eq "foo"
43
43
  end
44
44
 
45
45
  it 'closes payload if not nil' do
46
- test_file = File.new(File.join( File.dirname(File.expand_path(__FILE__)), 'master_shake.jpg'))
46
+ test_file = File.new(test_image_path)
47
47
 
48
- stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate'}).to_return(:body => 'foo', :status => 200)
48
+ stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'*/*'}).to_return(:body => 'foo', :status => 200)
49
49
  RestClient::Request.execute(:url => 'http://some/resource', :method => :post, :payload => {:file => test_file})
50
50
 
51
51
  expect(test_file.closed?).to be true
@@ -27,46 +27,22 @@ describe RestClient::Request, :include_helpers do
27
27
  expect(@request.default_headers[:accept]).to eq '*/*'
28
28
  end
29
29
 
30
- describe "compression" do
31
-
32
- it "decodes an uncompressed result body by passing it straight through" do
33
- expect(RestClient::Request.decode(nil, 'xyz')).to eq 'xyz'
34
- end
35
-
36
- it "doesn't fail for nil bodies" do
37
- expect(RestClient::Request.decode('gzip', nil)).to be_nil
38
- end
39
-
40
-
41
- it "decodes a gzip body" do
42
- expect(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")).to eq "i'm gziped\n"
43
- end
44
-
45
- it "ingores gzip for empty bodies" do
46
- expect(RestClient::Request.decode('gzip', '')).to be_empty
47
- end
48
-
49
- it "decodes a deflated body" do
50
- expect(RestClient::Request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363")).to eq "some deflated text"
51
- end
52
- end
53
-
54
30
  it "processes a successful result" do
55
- res = response_double
31
+ res = res_double
56
32
  allow(res).to receive(:code).and_return("200")
57
33
  allow(res).to receive(:body).and_return('body')
58
34
  allow(res).to receive(:[]).with('content-encoding').and_return(nil)
59
- expect(@request.send(:process_result, res).body).to eq 'body'
60
- expect(@request.send(:process_result, res).to_s).to eq 'body'
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'
61
37
  end
62
38
 
63
39
  it "doesn't classify successful requests as failed" do
64
40
  203.upto(207) do |code|
65
- res = response_double
41
+ res = res_double
66
42
  allow(res).to receive(:code).and_return(code.to_s)
67
43
  allow(res).to receive(:body).and_return("")
68
44
  allow(res).to receive(:[]).with('content-encoding').and_return(nil)
69
- expect(@request.send(:process_result, res)).to be_empty
45
+ expect(@request.send(:process_result, res, Time.now)).to be_empty
70
46
  end
71
47
  end
72
48
 
@@ -315,7 +291,7 @@ describe RestClient::Request, :include_helpers do
315
291
 
316
292
  describe "user headers" do
317
293
  it "merges user headers with the default headers" do
318
- expect(@request).to receive(:default_headers).and_return({ :accept => '*/*', :accept_encoding => 'gzip, deflate' })
294
+ expect(@request).to receive(:default_headers).and_return({:accept => '*/*'})
319
295
  headers = @request.make_headers("Accept" => "application/json", :accept_encoding => 'gzip')
320
296
  expect(headers).to have_key "Accept-Encoding"
321
297
  expect(headers["Accept-Encoding"]).to eq "gzip"
@@ -472,12 +448,13 @@ describe RestClient::Request, :include_helpers do
472
448
  end
473
449
 
474
450
  it "does not attempt to send credentials if Authorization header is set" do
475
- @request.headers['Authorization'] = 'Token abc123'
476
- allow(@request).to receive(:user).and_return('joe')
477
- allow(@request).to receive(:password).and_return('mypass')
478
- req = double("request")
479
- expect(req).not_to receive(:basic_auth)
480
- @request.send(:setup_credentials, req)
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
481
458
  end
482
459
  end
483
460
 
@@ -535,25 +512,25 @@ describe RestClient::Request, :include_helpers do
535
512
 
536
513
  describe "exception" do
537
514
  it "raises Unauthorized when the response is 401" do
538
- res = response_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
539
- expect { @request.send(:process_result, res) }.to 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)
540
517
  end
541
518
 
542
519
  it "raises ResourceNotFound when the response is 404" do
543
- res = response_double(:code => '404', :[] => ['content-encoding' => ''], :body => '' )
544
- expect { @request.send(:process_result, res) }.to 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)
545
522
  end
546
523
 
547
524
  it "raises RequestFailed otherwise" do
548
- res = response_double(:code => '500', :[] => ['content-encoding' => ''], :body => '' )
549
- expect { @request.send(:process_result, res) }.to 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)
550
527
  end
551
528
  end
552
529
 
553
530
  describe "block usage" do
554
531
  it "returns what asked to" do
555
- res = response_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
556
- expect(@request.send(:process_result, res){|response, request| "foo"}).to 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"
557
534
  end
558
535
  end
559
536
 
@@ -644,64 +621,74 @@ describe RestClient::Request, :include_helpers do
644
621
  it "logs a get request" do
645
622
  log = RestClient.log = []
646
623
  RestClient::Request.new(:method => :get, :url => 'http://url', :headers => {:user_agent => 'rest-client'}).log_request
647
- expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
624
+ expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"*/*", "User-Agent"=>"rest-client"\n}
648
625
  end
649
626
 
650
627
  it "logs a post request with a small payload" do
651
628
  log = RestClient.log = []
652
629
  RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo', :headers => {:user_agent => 'rest-client'}).log_request
653
- expect(log[0]).to eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"3", "User-Agent"=>"rest-client"\n}
630
+ expect(log[0]).to eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*", "Content-Length"=>"3", "User-Agent"=>"rest-client"\n}
654
631
  end
655
632
 
656
633
  it "logs a post request with a large payload" do
657
634
  log = RestClient.log = []
658
635
  RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000), :headers => {:user_agent => 'rest-client'}).log_request
659
- expect(log[0]).to eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"1000", "User-Agent"=>"rest-client"\n}
636
+ expect(log[0]).to eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*", "Content-Length"=>"1000", "User-Agent"=>"rest-client"\n}
660
637
  end
661
638
 
662
639
  it "logs input headers as a hash" do
663
640
  log = RestClient.log = []
664
641
  RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain', :user_agent => 'rest-client' }).log_request
665
- expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
642
+ expect(log[0]).to eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "User-Agent"=>"rest-client"\n}
666
643
  end
667
644
 
668
645
  it "logs a response including the status code, content type, and result body size in bytes" do
669
646
  log = RestClient.log = []
670
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
647
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
671
648
  allow(res).to receive(:[]).with('Content-type').and_return('text/html')
672
- @request.log_response res
673
- expect(log[0]).to eq "# => 200 OK | text/html 4 bytes\n"
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"]
674
652
  end
675
653
 
676
654
  it "logs a response with a nil Content-type" do
677
655
  log = RestClient.log = []
678
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
656
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
679
657
  allow(res).to receive(:[]).with('Content-type').and_return(nil)
680
- @request.log_response res
681
- expect(log[0]).to eq "# => 200 OK | 4 bytes\n"
658
+ response = response_from_res_double(res, @request)
659
+ response.log_response
660
+ expect(log).to eq ["# => 200 OK | 4 bytes, 1.00s\n"]
682
661
  end
683
662
 
684
663
  it "logs a response with a nil body" do
685
664
  log = RestClient.log = []
686
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => nil)
665
+ res = res_double(code: '200', class: Net::HTTPOK, body: nil)
687
666
  allow(res).to receive(:[]).with('Content-type').and_return('text/html; charset=utf-8')
688
- @request.log_response res
689
- expect(log[0]).to eq "# => 200 OK | text/html 0 bytes\n"
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"]
690
670
  end
691
671
 
692
672
  it 'does not log request password' do
693
673
  log = RestClient.log = []
694
674
  RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client'}).log_request
695
- expect(log[0]).to eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
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
696
682
  end
697
683
  end
698
684
 
699
685
  it "strips the charset from the response content type" do
700
686
  log = RestClient.log = []
701
- res = double('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
687
+ res = res_double(code: '200', class: Net::HTTPOK, body: 'abcd')
702
688
  allow(res).to receive(:[]).with('Content-type').and_return('text/html; charset=utf-8')
703
- @request.log_response res
704
- expect(log[0]).to eq "# => 200 OK | text/html 4 bytes\n"
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"]
705
692
  end
706
693
 
707
694
  describe "timeout" do
@@ -1149,7 +1136,7 @@ describe RestClient::Request, :include_helpers do
1149
1136
  )
1150
1137
  net_http_res = Net::HTTPNoContent.new("", "204", "No Content")
1151
1138
  allow(net_http_res).to receive(:read_body).and_return(nil)
1152
- expect(@http).to receive(:request).and_return(@request.send(:fetch_body, net_http_res))
1139
+ expect(@http).to receive(:request).and_return(net_http_res)
1153
1140
  response = @request.send(:transmit, @uri, 'req', 'payload')
1154
1141
  expect(response).not_to be_nil
1155
1142
  expect(response.code).to eq 204
@@ -1167,7 +1154,8 @@ describe RestClient::Request, :include_helpers do
1167
1154
 
1168
1155
  net_http_res = Net::HTTPOK.new(nil, "200", "body")
1169
1156
  allow(net_http_res).to receive(:read_body).and_return("body")
1170
- @request.send(:fetch_body, net_http_res)
1157
+ received_tempfile = @request.send(:fetch_body_to_tempfile, net_http_res)
1158
+ expect(received_tempfile).to eq tempfile
1171
1159
  end
1172
1160
  end
1173
1161
 
@@ -1233,10 +1221,10 @@ describe RestClient::Request, :include_helpers do
1233
1221
  expect(@request.process_url_params('https://example.com/', params: {
1234
1222
  foo: [1,2,3],
1235
1223
  null: nil,
1236
- false: false,
1224
+ falsy: false,
1237
1225
  math: '2+2=4',
1238
1226
  nested: {'key + escaped' => 'value + escaped', other: [], arr: [1,2]},
1239
- })).to eq 'https://example.com/?foo[]=1&foo[]=2&foo[]=3&null&false=false&math=2%2B2%3D4' \
1227
+ })).to eq 'https://example.com/?foo[]=1&foo[]=2&foo[]=3&null&falsy=false&math=2%2B2%3D4' \
1240
1228
  '&nested[key+%2B+escaped]=value+%2B+escaped&nested[other]' \
1241
1229
  '&nested[arr][]=1&nested[arr][]=2'
1242
1230
  end