rest-client 1.8.0 → 2.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1 @@
1
+ require_relative '../spec_helper'
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require_relative '_lib'
2
2
 
3
3
  describe RestClient::AbstractResponse do
4
4
 
@@ -33,14 +33,28 @@ describe RestClient::AbstractResponse do
33
33
  @response.description.should eq "200 OK | application/pdf bytes\n"
34
34
  end
35
35
 
36
- it "beautifies the headers by turning the keys to symbols" do
37
- h = RestClient::AbstractResponse.beautify_headers('content-type' => [ 'x' ])
38
- h.keys.first.should eq :content_type
39
- end
36
+ describe '.beautify_headers' do
37
+ it "beautifies the headers by turning the keys to symbols" do
38
+ h = RestClient::AbstractResponse.beautify_headers('content-type' => [ 'x' ])
39
+ h.keys.first.should eq :content_type
40
+ end
41
+
42
+ it "beautifies the headers by turning the values to strings instead of one-element arrays" do
43
+ h = RestClient::AbstractResponse.beautify_headers('x' => [ 'text/html' ] )
44
+ h.values.first.should eq 'text/html'
45
+ end
40
46
 
41
- it "beautifies the headers by turning the values to strings instead of one-element arrays" do
42
- h = RestClient::AbstractResponse.beautify_headers('x' => [ 'text/html' ] )
43
- h.values.first.should eq 'text/html'
47
+ it 'joins multiple header values by comma' do
48
+ RestClient::AbstractResponse.beautify_headers(
49
+ {'My-Header' => ['one', 'two']}
50
+ ).should eq({:my_header => 'one, two'})
51
+ end
52
+
53
+ it 'leaves set-cookie headers as array' do
54
+ RestClient::AbstractResponse.beautify_headers(
55
+ {'Set-Cookie' => ['cookie1=foo', 'cookie2=bar']}
56
+ ).should eq({:set_cookie => ['cookie1=foo', 'cookie2=bar']})
57
+ end
44
58
  end
45
59
 
46
60
  it "fetches the headers" do
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require_relative '_lib'
2
2
 
3
3
  describe RestClient::Exception do
4
4
  it "returns a 'message' equal to the class name if the message is not set, because 'message' should not be nil" do
@@ -14,7 +14,7 @@ describe RestClient::Exception do
14
14
  end
15
15
 
16
16
  it "sets the exception message to ErrorMessage" do
17
- RestClient::ResourceNotFound.new.message.should eq 'Resource Not Found'
17
+ RestClient::ResourceNotFound.new.message.should eq 'Not Found'
18
18
  end
19
19
 
20
20
  it "contains exceptions in RestClient" do
@@ -67,22 +67,8 @@ describe RestClient::ResourceNotFound do
67
67
  e.response.should eq response
68
68
  end
69
69
  end
70
- end
71
-
72
- describe "backwards compatibility" do
73
- it "alias RestClient::Request::Redirect to RestClient::Redirect" do
74
- RestClient::Request::Redirect.should eq RestClient::Redirect
75
- end
76
-
77
- it "alias RestClient::Request::Unauthorized to RestClient::Unauthorized" do
78
- RestClient::Request::Unauthorized.should eq RestClient::Unauthorized
79
- end
80
70
 
81
- it "alias RestClient::Request::RequestFailed to RestClient::RequestFailed" do
82
- RestClient::Request::RequestFailed.should eq RestClient::RequestFailed
83
- end
84
-
85
- it "make the exception's response act like an Net::HTTPResponse" do
71
+ it 'stores the body on the response of the exception' do
86
72
  body = "body"
87
73
  stub_request(:get, "www.example.com").to_return(:body => body, :status => 404)
88
74
  begin
@@ -93,3 +79,9 @@ describe "backwards compatibility" do
93
79
  end
94
80
  end
95
81
  end
82
+
83
+ describe "backwards compatibility" do
84
+ it 'aliases RestClient::NotFound as ResourceNotFound' do
85
+ RestClient::ResourceNotFound.should eq RestClient::NotFound
86
+ end
87
+ end
@@ -1,31 +1,31 @@
1
1
  # encoding: binary
2
2
 
3
- require 'spec_helper'
3
+ require_relative '_lib'
4
4
 
5
5
  describe RestClient::Payload do
6
6
  context "A regular Payload" do
7
7
  it "should use standard enctype as default content-type" do
8
8
  RestClient::Payload::UrlEncoded.new({}).headers['Content-Type'].
9
- should eq 'application/x-www-form-urlencoded'
9
+ should eq 'application/x-www-form-urlencoded'
10
10
  end
11
11
 
12
12
  it "should form properly encoded params" do
13
13
  RestClient::Payload::UrlEncoded.new({:foo => 'bar'}).to_s.
14
- should eq "foo=bar"
14
+ should eq "foo=bar"
15
15
  ["foo=bar&baz=qux", "baz=qux&foo=bar"].should include(
16
16
  RestClient::Payload::UrlEncoded.new({:foo => 'bar', :baz => 'qux'}).to_s)
17
17
  end
18
18
 
19
19
  it "should escape parameters" do
20
20
  RestClient::Payload::UrlEncoded.new({'foo ' => 'bar'}).to_s.
21
- should eq "foo%20=bar"
21
+ should eq "foo%20=bar"
22
22
  end
23
23
 
24
24
  it "should properly handle hashes as parameter" do
25
25
  RestClient::Payload::UrlEncoded.new({:foo => {:bar => 'baz'}}).to_s.
26
- should eq "foo[bar]=baz"
26
+ should eq "foo[bar]=baz"
27
27
  RestClient::Payload::UrlEncoded.new({:foo => {:bar => {:baz => 'qux'}}}).to_s.
28
- should eq "foo[bar][baz]=qux"
28
+ should eq "foo[bar][baz]=qux"
29
29
  end
30
30
 
31
31
  it "should handle many attributes inside a hash" do
@@ -45,16 +45,16 @@ describe RestClient::Payload do
45
45
 
46
46
  it "should form properly use symbols as parameters" do
47
47
  RestClient::Payload::UrlEncoded.new({:foo => :bar}).to_s.
48
- should eq "foo=bar"
48
+ should eq "foo=bar"
49
49
  RestClient::Payload::UrlEncoded.new({:foo => {:bar => :baz}}).to_s.
50
- should eq "foo[bar]=baz"
50
+ should eq "foo[bar]=baz"
51
51
  end
52
52
 
53
53
  it "should properly handle arrays as repeated parameters" do
54
54
  RestClient::Payload::UrlEncoded.new({:foo => ['bar']}).to_s.
55
- should eq "foo[]=bar"
55
+ should eq "foo[]=bar"
56
56
  RestClient::Payload::UrlEncoded.new({:foo => ['bar', 'baz']}).to_s.
57
- should eq "foo[]=bar&foo[]=baz"
57
+ should eq "foo[]=bar&foo[]=baz"
58
58
  end
59
59
 
60
60
  it 'should not close if stream already closed' do
@@ -1,4 +1,4 @@
1
- require 'spec_helper'
1
+ require_relative '_lib'
2
2
 
3
3
  describe RestClient::RawResponse do
4
4
  before do
@@ -1,12 +1,12 @@
1
- require 'spec_helper'
1
+ require_relative '_lib'
2
2
 
3
3
  describe RestClient::Request do
4
4
 
5
5
  it "manage params for get requests" do
6
- stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
6
+ 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
7
  RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => {:a => :b, 'c' => 'd'}}).body.should eq 'foo'
8
8
 
9
- stub_request(:get, 'http://some/resource').with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar', 'params' => 'a'}).to_return(:body => 'foo', :status => 200)
9
+ stub_request(:get, 'http://some/resource').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar', 'params' => 'a'}).to_return(:body => 'foo', :status => 200)
10
10
  RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => :a}).body.should eq 'foo'
11
11
  end
12
12
 
@@ -15,7 +15,7 @@ describe RestClient::Request do
15
15
  block = proc do |http_response|
16
16
  response_value = http_response.body
17
17
  end
18
- stub_request(:get, 'http://some/resource?a=b&c=d').with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate', 'Foo'=>'bar'}).to_return(:body => 'foo', :status => 200)
18
+ 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)
19
19
  RestClient::Request.execute(:url => 'http://some/resource', :method => :get, :headers => {:foo => :bar, :params => {:a => :b, 'c' => 'd'}}, :block_response => block)
20
20
  response_value.should eq "foo"
21
21
  end
@@ -23,10 +23,10 @@ describe RestClient::Request do
23
23
  it 'closes payload if not nil' do
24
24
  test_file = File.new(File.join( File.dirname(File.expand_path(__FILE__)), 'master_shake.jpg'))
25
25
 
26
- stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'*/*; q=0.5, application/xml', 'Accept-Encoding'=>'gzip, deflate'}).to_return(:body => 'foo', :status => 200)
26
+ stub_request(:post, 'http://some/resource').with(:headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip, deflate'}).to_return(:body => 'foo', :status => 200)
27
27
  RestClient::Request.execute(:url => 'http://some/resource', :method => :post, :payload => {:file => test_file})
28
28
 
29
- test_file.closed?.should be_true
29
+ test_file.closed?.should be true
30
30
  end
31
31
 
32
32
  end
@@ -1,17 +1,19 @@
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
8
  @uri.stub(:request_uri).and_return('/resource')
9
- @uri.stub(:host).and_return('some')
9
+ @uri.stub(:hostname).and_return('some')
10
10
  @uri.stub(:port).and_return(80)
11
11
 
12
12
  @net = double("net::http base")
13
13
  @http = double("net::http connection")
14
+
14
15
  Net::HTTP.stub(:new).and_return(@net)
16
+
15
17
  @net.stub(:start).and_yield(@http)
16
18
  @net.stub(:use_ssl=)
17
19
  @net.stub(:verify_mode=)
@@ -21,8 +23,8 @@ describe RestClient::Request do
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
+ @request.default_headers[:accept].should eq '*/*'
26
28
  end
27
29
 
28
30
  describe "compression" do
@@ -50,7 +52,7 @@ describe RestClient::Request do
50
52
  end
51
53
 
52
54
  it "processes a successful result" do
53
- res = double("result")
55
+ res = response_double
54
56
  res.stub(:code).and_return("200")
55
57
  res.stub(:body).and_return('body')
56
58
  res.stub(:[]).with('content-encoding').and_return(nil)
@@ -60,7 +62,7 @@ describe RestClient::Request do
60
62
 
61
63
  it "doesn't classify successful requests as failed" do
62
64
  203.upto(207) do |code|
63
- res = double("result")
65
+ res = response_double
64
66
  res.stub(:code).and_return(code.to_s)
65
67
  res.stub(:body).and_return("")
66
68
  res.stub(:[]).with('content-encoding').and_return(nil)
@@ -68,14 +70,36 @@ describe RestClient::Request do
68
70
  end
69
71
  end
70
72
 
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
73
+ describe '.parse_url' do
74
+ it "parses a url into a URI object" do
75
+ URI.should_receive(:parse).with('http://example.com/resource')
76
+ @request.parse_url('http://example.com/resource')
77
+ end
78
+
79
+ it "adds http:// to the front of resources specified in the syntax example.com/resource" do
80
+ URI.should_receive(:parse).with('http://example.com/resource')
81
+ @request.parse_url('example.com/resource')
82
+ end
83
+
84
+ it 'adds http:// to resources containing a colon' do
85
+ URI.should_receive(:parse).with('http://example.com:1234')
86
+ @request.parse_url('example.com:1234')
87
+ end
88
+
89
+ it 'does not add http:// to the front of https resources' do
90
+ URI.should_receive(:parse).with('https://example.com/resource')
91
+ @request.parse_url('https://example.com/resource')
92
+ end
93
+
94
+ it 'does not add http:// to the front of capital HTTP resources' do
95
+ URI.should_receive(:parse).with('HTTP://example.com/resource')
96
+ @request.parse_url('HTTP://example.com/resource')
97
+ end
75
98
 
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')
99
+ it 'does not add http:// to the front of capital HTTPS resources' do
100
+ URI.should_receive(:parse).with('HTTPS://example.com/resource')
101
+ @request.parse_url('HTTPS://example.com/resource')
102
+ end
79
103
  end
80
104
 
81
105
  describe "user - password" do
@@ -145,7 +169,7 @@ describe RestClient::Request do
145
169
  end
146
170
 
147
171
  it "uses netrc credentials" do
148
- URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil, :host => 'example.com'))
172
+ URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil, :hostname => 'example.com'))
149
173
  Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
150
174
  @request.parse_url_with_auth('http://example.com/resource')
151
175
  @request.user.should eq 'a'
@@ -153,7 +177,7 @@ describe RestClient::Request do
153
177
  end
154
178
 
155
179
  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'))
180
+ URI.stub(:parse).and_return(double('uri', :user => 'joe%20', :password => 'pass1', :hostname => 'example.com'))
157
181
  Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
158
182
  @request.parse_url_with_auth('http://joe%20:pass1@example.com/resource')
159
183
  @request.user.should eq 'joe '
@@ -166,7 +190,7 @@ describe RestClient::Request do
166
190
 
167
191
  describe "user headers" do
168
192
  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' })
193
+ @request.should_receive(:default_headers).and_return({ :accept => '*/*', :accept_encoding => 'gzip, deflate' })
170
194
  headers = @request.make_headers("Accept" => "application/json", :accept_encoding => 'gzip')
171
195
  headers.should have_key "Accept-Encoding"
172
196
  headers["Accept-Encoding"].should eq "gzip"
@@ -238,6 +262,21 @@ describe RestClient::Request do
238
262
  @request.execute
239
263
  end
240
264
 
265
+ it "IPv6: executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
266
+ @request = RestClient::Request.new(:method => :put, :url => 'http://[::1]/some/resource', :payload => 'payload')
267
+ klass = double("net:http class")
268
+ @request.should_receive(:net_http_request_class).with(:put).and_return(klass)
269
+
270
+ if RUBY_VERSION >= "2.0.0"
271
+ klass.should_receive(:new).with(kind_of(URI), kind_of(Hash)).and_return('result')
272
+ else
273
+ klass.should_receive(:new).with(kind_of(String), kind_of(Hash)).and_return('result')
274
+ end
275
+
276
+ @request.should_receive(:transmit)
277
+ @request.execute
278
+ end
279
+
241
280
  it "transmits the request with Net::HTTP" do
242
281
  @http.should_receive(:request).with('req', 'payload')
243
282
  @request.should_receive(:process_result)
@@ -301,6 +340,15 @@ describe RestClient::Request do
301
340
  req.should_receive(:basic_auth).with('joe', 'mypass')
302
341
  @request.setup_credentials(req)
303
342
  end
343
+
344
+ it "does not attempt to send credentials if Authorization header is set" do
345
+ @request.headers['Authorization'] = 'Token abc123'
346
+ @request.stub(:user).and_return('joe')
347
+ @request.stub(:password).and_return('mypass')
348
+ req = double("request")
349
+ req.should_not_receive(:basic_auth)
350
+ @request.setup_credentials(req)
351
+ end
304
352
  end
305
353
 
306
354
  it "catches EOFError and shows the more informative ServerBrokeConnection" do
@@ -313,14 +361,26 @@ describe RestClient::Request do
313
361
  lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(OpenSSL::SSL::SSLError)
314
362
  end
315
363
 
316
- it "catches Timeout::Error and raise the more informative RequestTimeout" do
364
+ it "catches Timeout::Error and raise the more informative ReadTimeout" do
317
365
  @http.stub(:request).and_raise(Timeout::Error)
318
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
366
+ lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::Exceptions::ReadTimeout)
319
367
  end
320
368
 
321
- it "catches Timeout::Error and raise the more informative RequestTimeout" do
369
+ it "catches Errno::ETIMEDOUT and raise the more informative ReadTimeout" do
322
370
  @http.stub(:request).and_raise(Errno::ETIMEDOUT)
323
- lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
371
+ lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::Exceptions::ReadTimeout)
372
+ end
373
+
374
+ it "catches Net::ReadTimeout and raises RestClient's ReadTimeout",
375
+ :if => defined?(Net::ReadTimeout) do
376
+ @http.stub(:request).and_raise(Net::ReadTimeout)
377
+ lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::Exceptions::ReadTimeout)
378
+ end
379
+
380
+ it "catches Net::OpenTimeout and raises RestClient's OpenTimeout",
381
+ :if => defined?(Net::OpenTimeout) do
382
+ @http.stub(:request).and_raise(Net::OpenTimeout)
383
+ lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::Exceptions::OpenTimeout)
324
384
  end
325
385
 
326
386
  it "class method execute wraps constructor" do
@@ -332,36 +392,105 @@ describe RestClient::Request do
332
392
 
333
393
  describe "exception" do
334
394
  it "raises Unauthorized when the response is 401" do
335
- res = double('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
395
+ res = response_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
336
396
  lambda { @request.process_result(res) }.should raise_error(RestClient::Unauthorized)
337
397
  end
338
398
 
339
399
  it "raises ResourceNotFound when the response is 404" do
340
- res = double('response', :code => '404', :[] => ['content-encoding' => ''], :body => '' )
400
+ res = response_double(:code => '404', :[] => ['content-encoding' => ''], :body => '' )
341
401
  lambda { @request.process_result(res) }.should raise_error(RestClient::ResourceNotFound)
342
402
  end
343
403
 
344
404
  it "raises RequestFailed otherwise" do
345
- res = double('response', :code => '500', :[] => ['content-encoding' => ''], :body => '' )
405
+ res = response_double(:code => '500', :[] => ['content-encoding' => ''], :body => '' )
346
406
  lambda { @request.process_result(res) }.should raise_error(RestClient::InternalServerError)
347
407
  end
348
408
  end
349
409
 
350
410
  describe "block usage" do
351
411
  it "returns what asked to" do
352
- res = double('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
412
+ res = response_double(:code => '401', :[] => ['content-encoding' => ''], :body => '' )
353
413
  @request.process_result(res){|response, request| "foo"}.should eq "foo"
354
414
  end
355
415
  end
356
416
 
357
417
  describe "proxy" do
418
+ before do
419
+ # unstub Net::HTTP creation since we need to test it
420
+ Net::HTTP.unstub(:new)
421
+
422
+ @proxy_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
423
+ end
424
+
358
425
  it "creates a proxy class if a proxy url is given" do
359
426
  RestClient.stub(:proxy).and_return("http://example.com/")
360
- @request.net_http_class.proxy_class?.should be_true
427
+ RestClient.stub(:proxy_set?).and_return(true)
428
+ @proxy_req.net_http_object('host', 80).proxy?.should be true
429
+ end
430
+
431
+ it "creates a proxy class with the correct address if a IPv6 proxy url is given" do
432
+ RestClient.stub(:proxy).and_return("http://[::1]/")
433
+ RestClient.stub(:proxy_set?).and_return(true)
434
+ @proxy_req.net_http_object('host', 80).proxy?.should be true
435
+ @proxy_req.net_http_object('host', 80).proxy_address.should == '::1'
361
436
  end
362
437
 
363
438
  it "creates a non-proxy class if a proxy url is not given" do
364
- @request.net_http_class.proxy_class?.should be_false
439
+ @proxy_req.net_http_object('host', 80).proxy?.should be_falsey
440
+ end
441
+
442
+ it "disables proxy on a per-request basis" do
443
+ RestClient.stub(:proxy).and_return('http://example.com')
444
+ RestClient.stub(:proxy_set?).and_return(true)
445
+ @proxy_req.net_http_object('host', 80).proxy?.should be true
446
+
447
+ disabled_req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
448
+ disabled_req.net_http_object('host', 80).proxy?.should be_falsey
449
+ end
450
+
451
+ it "sets proxy on a per-request basis" do
452
+ @proxy_req.net_http_object('some', 80).proxy?.should be_falsey
453
+
454
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://example.com')
455
+ req.net_http_object('host', 80).proxy?.should be true
456
+ end
457
+
458
+ it "overrides proxy from environment", if: RUBY_VERSION >= '2.0' do
459
+ allow(ENV).to receive(:[]).with("http_proxy").and_return("http://127.0.0.1")
460
+ allow(ENV).to receive(:[]).with("no_proxy").and_return(nil)
461
+ allow(ENV).to receive(:[]).with("NO_PROXY").and_return(nil)
462
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
463
+ obj = req.net_http_object('host', 80)
464
+ obj.proxy?.should be true
465
+ obj.proxy_address.should eq '127.0.0.1'
466
+
467
+ # test original method .proxy?
468
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
469
+ obj = req.net_http_object('host', 80)
470
+ obj.proxy?.should be_falsey
471
+
472
+ # stub RestClient.proxy_set? to peek into implementation
473
+ RestClient.stub(:proxy_set?).and_return(true)
474
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
475
+ obj = req.net_http_object('host', 80)
476
+ obj.proxy?.should be_falsey
477
+
478
+ # test stubbed Net::HTTP.new
479
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => nil)
480
+ expect(Net::HTTP).to receive(:new).with('host', 80, nil, nil, nil, nil)
481
+ req.net_http_object('host', 80)
482
+ end
483
+
484
+ it "overrides global proxy with per-request proxy" do
485
+ RestClient.stub(:proxy).and_return('http://example.com')
486
+ RestClient.stub(:proxy_set?).and_return(true)
487
+ obj = @proxy_req.net_http_object('host', 80)
488
+ obj.proxy?.should be true
489
+ obj.proxy_address.should eq 'example.com'
490
+
491
+ req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :proxy => 'http://127.0.0.1/')
492
+ req.net_http_object('host', 80).proxy?.should be true
493
+ req.net_http_object('host', 80).proxy_address.should == '127.0.0.1'
365
494
  end
366
495
  end
367
496
 
@@ -369,26 +498,26 @@ describe RestClient::Request do
369
498
  describe "logging" do
370
499
  it "logs a get request" do
371
500
  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}
501
+ RestClient::Request.new(:method => :get, :url => 'http://url', :headers => {:user_agent => 'rest-client'}).log_request
502
+ log[0].should eq %Q{RestClient.get "http://url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
374
503
  end
375
504
 
376
505
  it "logs a post request with a small payload" do
377
506
  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}
507
+ RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo', :headers => {:user_agent => 'rest-client'}).log_request
508
+ log[0].should eq %Q{RestClient.post "http://url", "foo", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"3", "User-Agent"=>"rest-client"\n}
380
509
  end
381
510
 
382
511
  it "logs a post request with a large payload" do
383
512
  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}
513
+ RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000), :headers => {:user_agent => 'rest-client'}).log_request
514
+ log[0].should eq %Q{RestClient.post "http://url", 1000 byte(s) length, "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "Content-Length"=>"1000", "User-Agent"=>"rest-client"\n}
386
515
  end
387
516
 
388
517
  it "logs input headers as a hash" do
389
518
  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}
519
+ RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain', :user_agent => 'rest-client' }).log_request
520
+ log[0].should eq %Q{RestClient.get "http://url", "Accept"=>"text/plain", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
392
521
  end
393
522
 
394
523
  it "logs a response including the status code, content type, and result body size in bytes" do
@@ -417,13 +546,13 @@ describe RestClient::Request do
417
546
 
418
547
  it 'does not log request password' do
419
548
  log = RestClient.log = []
420
- RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client', :accept => '*/*'}).log_request
549
+ RestClient::Request.new(:method => :get, :url => 'http://user:password@url', :headers => {:user_agent => 'rest-client'}).log_request
421
550
  log[0].should eq %Q{RestClient.get "http://user:REDACTED@url", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
422
551
  end
423
552
 
424
553
  it 'logs invalid URIs, even though they will fail elsewhere' do
425
554
  log = RestClient.log = []
426
- RestClient::Request.new(:method => :get, :url => 'http://a@b:c', :headers => {:user_agent => 'rest-client', :accept => '*/*'}).log_request
555
+ RestClient::Request.new(:method => :get, :url => 'http://a@b:c', :headers => {:user_agent => 'rest-client'}).log_request
427
556
  log[0].should eq %Q{RestClient.get "[invalid uri]", "Accept"=>"*/*", "Accept-Encoding"=>"gzip, deflate", "User-Agent"=>"rest-client"\n}
428
557
  end
429
558
  end
@@ -449,8 +578,8 @@ describe RestClient::Request do
449
578
  @request.transmit(@uri, 'req', nil)
450
579
  end
451
580
 
452
- it "set read_timeout" do
453
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
581
+ it 'sets read_timeout' do
582
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => 123)
454
583
  @http.stub(:request)
455
584
  @request.stub(:process_result)
456
585
  @request.stub(:response_log)
@@ -460,7 +589,7 @@ describe RestClient::Request do
460
589
  @request.transmit(@uri, 'req', nil)
461
590
  end
462
591
 
463
- it "set open_timeout" do
592
+ it "sets open_timeout" do
464
593
  @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :open_timeout => 123)
465
594
  @http.stub(:request)
466
595
  @request.stub(:process_result)
@@ -471,8 +600,33 @@ describe RestClient::Request do
471
600
  @request.transmit(@uri, 'req', nil)
472
601
  end
473
602
 
603
+ it 'sets both timeouts with :timeout' do
604
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
605
+ @http.stub(:request)
606
+ @request.stub(:process_result)
607
+ @request.stub(:response_log)
608
+
609
+ @net.should_receive(:open_timeout=).with(123)
610
+ @net.should_receive(:read_timeout=).with(123)
611
+
612
+ @request.transmit(@uri, 'req', nil)
613
+ end
614
+
615
+ it 'supersedes :timeout with open/read_timeout' do
616
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123, :open_timeout => 34, :read_timeout => 56)
617
+ @http.stub(:request)
618
+ @request.stub(:process_result)
619
+ @request.stub(:response_log)
620
+
621
+ @net.should_receive(:open_timeout=).with(34)
622
+ @net.should_receive(:read_timeout=).with(56)
623
+
624
+ @request.transmit(@uri, 'req', nil)
625
+ end
626
+
627
+
474
628
  it "disable timeout by setting it to nil" do
475
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => nil, :open_timeout => nil)
629
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => nil, :open_timeout => nil)
476
630
  @http.stub(:request)
477
631
  @request.stub(:process_result)
478
632
  @request.stub(:response_log)
@@ -483,8 +637,21 @@ describe RestClient::Request do
483
637
  @request.transmit(@uri, 'req', nil)
484
638
  end
485
639
 
640
+ it 'deprecated: warns when disabling timeout by setting it to -1' do
641
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1)
642
+ @http.stub(:request)
643
+ @request.stub(:process_result)
644
+ @request.stub(:response_log)
645
+
646
+ @net.should_receive(:read_timeout=).with(nil)
647
+
648
+ fake_stderr {
649
+ @request.transmit(@uri, 'req', nil)
650
+ }.should match(/^Deprecated: .*timeout.* nil instead of -1$/)
651
+ end
652
+
486
653
  it "deprecated: disable timeout by setting it to -1" do
487
- @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => -1, :open_timeout => -1)
654
+ @request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :read_timeout => -1, :open_timeout => -1)
488
655
  @http.stub(:request)
489
656
  @request.stub(:process_result)
490
657
  @request.stub(:response_log)
@@ -907,11 +1074,35 @@ describe RestClient::Request do
907
1074
  tempfile.should_receive(:binmode)
908
1075
  tempfile.stub(:open)
909
1076
  tempfile.stub(:close)
910
- Tempfile.should_receive(:new).with("rest-client").and_return(tempfile)
1077
+ Tempfile.should_receive(:new).with("rest-client.").and_return(tempfile)
911
1078
 
912
1079
  net_http_res = Net::HTTPOK.new(nil, "200", "body")
913
1080
  net_http_res.stub(:read_body).and_return("body")
914
1081
  @request.fetch_body(net_http_res)
915
1082
  end
916
1083
  end
1084
+
1085
+ describe 'payloads' do
1086
+ it 'should accept string payloads' do
1087
+ payload = 'Foo'
1088
+ @request = RestClient::Request.new(method: :get, url: 'example.com', :payload => payload)
1089
+ @request.should_receive(:process_result)
1090
+ @http.should_receive(:request).with('req', payload)
1091
+ @request.transmit(@uri, 'req', payload)
1092
+ end
1093
+
1094
+ it 'should accept streaming IO payloads' do
1095
+ payload = StringIO.new('streamed')
1096
+
1097
+ @request = RestClient::Request.new(method: :get, url: 'example.com', :payload => payload)
1098
+ @request.should_receive(:process_result)
1099
+
1100
+ @get = double('net::http::get')
1101
+ @get.should_receive(:body_stream=).with(instance_of(RestClient::Payload::Streamed))
1102
+
1103
+ @request.net_http_request_class(:GET).stub(:new).and_return(@get)
1104
+ @http.should_receive(:request).with(@get, nil)
1105
+ @request.execute
1106
+ end
1107
+ end
917
1108
  end