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