rest-client 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rest-client might be problematic. Click here for more details.
- data/README.rdoc +119 -7
- data/Rakefile +2 -2
- data/VERSION +1 -1
- data/history.md +28 -0
- data/lib/restclient.rb +63 -20
- data/lib/restclient/exceptions.rb +77 -46
- data/lib/restclient/mixin/response.rb +23 -7
- data/lib/restclient/payload.rb +2 -2
- data/lib/restclient/request.rb +60 -71
- data/lib/restclient/resource.rb +11 -10
- data/spec/exceptions_spec.rb +3 -5
- data/spec/integration_spec.rb +38 -0
- data/spec/mixin/response_spec.rb +1 -1
- data/spec/payload_spec.rb +6 -6
- data/spec/request_spec.rb +357 -332
- data/spec/resource_spec.rb +24 -0
- data/spec/response_spec.rb +51 -0
- data/spec/restclient_spec.rb +21 -11
- metadata +8 -4
data/spec/request_spec.rb
CHANGED
@@ -15,27 +15,29 @@ describe RestClient::Request do
|
|
15
15
|
@net.stub!(:start).and_yield(@http)
|
16
16
|
@net.stub!(:use_ssl=)
|
17
17
|
@net.stub!(:verify_mode=)
|
18
|
-
RestClient.log =
|
18
|
+
RestClient.log = nil
|
19
19
|
end
|
20
20
|
|
21
21
|
it "accept */* mimetype, preferring xml" do
|
22
22
|
@request.default_headers[:accept].should == '*/*; q=0.5, application/xml'
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
describe "compression" do
|
26
|
+
it "decodes an uncompressed result body by passing it straight through" do
|
27
|
+
RestClient::Request.decode(nil, 'xyz').should == 'xyz'
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
it "decodes a gzip body" do
|
31
|
+
RestClient::Request.decode('gzip', "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000").should == "i'm gziped\n"
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
34
|
+
it "ingores gzip for empty bodies" do
|
35
|
+
RestClient::Request.decode('gzip', '').should be_empty
|
36
|
+
end
|
36
37
|
|
37
|
-
|
38
|
-
|
38
|
+
it "decodes a deflated body" do
|
39
|
+
RestClient::Request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should == "some deflated text"
|
40
|
+
end
|
39
41
|
end
|
40
42
|
|
41
43
|
it "processes a successful result" do
|
@@ -66,76 +68,83 @@ describe RestClient::Request do
|
|
66
68
|
@request.parse_url('example.com/resource')
|
67
69
|
end
|
68
70
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
71
|
+
describe "user - password" do
|
72
|
+
it "extracts the username and password when parsing http://user:password@example.com/" do
|
73
|
+
URI.stub!(:parse).and_return(mock('uri', :user => 'joe', :password => 'pass1'))
|
74
|
+
@request.parse_url_with_auth('http://joe:pass1@example.com/resource')
|
75
|
+
@request.user.should == 'joe'
|
76
|
+
@request.password.should == 'pass1'
|
77
|
+
end
|
75
78
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
79
|
+
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
|
80
|
+
URI.stub!(:parse).and_return(mock('uri', :user => nil, :password => nil))
|
81
|
+
@request = RestClient::Request.new(:method => 'get', :url => 'example.com', :user => 'beth', :password => 'pass2')
|
82
|
+
@request.parse_url_with_auth('http://example.com/resource')
|
83
|
+
@request.user.should == 'beth'
|
84
|
+
@request.password.should == 'pass2'
|
85
|
+
end
|
82
86
|
end
|
83
87
|
|
84
88
|
it "correctly formats cookies provided to the constructor" do
|
85
89
|
URI.stub!(:parse).and_return(mock('uri', :user => nil, :password => nil))
|
86
|
-
@request = RestClient::Request.new(:method => 'get', :url => 'example.com', :cookies => {:session_id => '1' })
|
90
|
+
@request = RestClient::Request.new(:method => 'get', :url => 'example.com', :cookies => {:session_id => '1', :user_id => "someone" })
|
87
91
|
@request.should_receive(:default_headers).and_return({'foo' => 'bar'})
|
88
|
-
headers = @request.make_headers({}).should == { 'Foo' => 'bar', 'Cookie' => 'session_id=1'}
|
92
|
+
headers = @request.make_headers({}).should == { 'Foo' => 'bar', 'Cookie' => 'session_id=1,user_id=someone'}
|
89
93
|
end
|
90
94
|
|
91
95
|
it "determines the Net::HTTP class to instantiate by the method name" do
|
92
96
|
@request.net_http_request_class(:put).should == Net::HTTP::Put
|
93
97
|
end
|
94
98
|
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
99
|
+
describe "user headers" do
|
100
|
+
it "merges user headers with the default headers" do
|
101
|
+
@request.should_receive(:default_headers).and_return({ '1' => '2' })
|
102
|
+
headers = @request.make_headers('3' => '4')
|
103
|
+
headers.should have_key('1')
|
104
|
+
headers['1'].should == '2'
|
105
|
+
headers.should have_key('3')
|
106
|
+
headers['3'].should == '4'
|
107
|
+
end
|
103
108
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
+
it "prefers the user header when the same header exists in the defaults" do
|
110
|
+
@request.should_receive(:default_headers).and_return({ '1' => '2' })
|
111
|
+
headers = @request.make_headers('1' => '3')
|
112
|
+
headers.should have_key('1')
|
113
|
+
headers['1'].should == '3'
|
114
|
+
end
|
109
115
|
end
|
110
116
|
|
111
|
-
|
112
|
-
@request.should_receive(:default_headers).and_return({})
|
113
|
-
headers = @request.make_headers(:content_type => 'abc')
|
114
|
-
headers.should have_key('Content-type')
|
115
|
-
headers['Content-type'].should == 'abc'
|
116
|
-
end
|
117
|
+
describe "header symbols" do
|
117
118
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
119
|
+
it "converts header symbols from :content_type to 'Content-type'" do
|
120
|
+
@request.should_receive(:default_headers).and_return({})
|
121
|
+
headers = @request.make_headers(:content_type => 'abc')
|
122
|
+
headers.should have_key('Content-type')
|
123
|
+
headers['Content-type'].should == 'abc'
|
124
|
+
end
|
125
|
+
|
126
|
+
it "converts content-type from extension to real content-type" do
|
127
|
+
@request.should_receive(:default_headers).and_return({})
|
128
|
+
headers = @request.make_headers(:content_type => 'json')
|
129
|
+
headers.should have_key('Content-type')
|
130
|
+
headers['Content-type'].should == 'application/json'
|
131
|
+
end
|
124
132
|
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
133
|
+
it "converts accept from extension(s) to real content-type(s)" do
|
134
|
+
@request.should_receive(:default_headers).and_return({})
|
135
|
+
headers = @request.make_headers(:accept => 'json, mp3')
|
136
|
+
headers.should have_key('Accept')
|
137
|
+
headers['Accept'].should == 'application/json, audio/mpeg'
|
130
138
|
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
139
|
+
@request.should_receive(:default_headers).and_return({})
|
140
|
+
headers = @request.make_headers(:accept => :json)
|
141
|
+
headers.should have_key('Accept')
|
142
|
+
headers['Accept'].should == 'application/json'
|
143
|
+
end
|
136
144
|
|
137
|
-
|
138
|
-
|
145
|
+
it "converts header values to strings" do
|
146
|
+
@request.make_headers('A' => 1)['A'].should == '1'
|
147
|
+
end
|
139
148
|
end
|
140
149
|
|
141
150
|
it "executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
|
@@ -150,39 +159,31 @@ describe RestClient::Request do
|
|
150
159
|
it "transmits the request with Net::HTTP" do
|
151
160
|
@http.should_receive(:request).with('req', 'payload')
|
152
161
|
@request.should_receive(:process_result)
|
153
|
-
@request.should_receive(:response_log)
|
154
162
|
@request.transmit(@uri, 'req', 'payload')
|
155
163
|
end
|
156
164
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
end
|
165
|
-
|
166
|
-
it "sends nil payloads" do
|
167
|
-
@http.should_receive(:request).with('req', nil)
|
168
|
-
@request.should_receive(:process_result)
|
169
|
-
@request.stub!(:response_log)
|
170
|
-
@request.transmit(@uri, 'req', nil)
|
171
|
-
end
|
165
|
+
describe "payload" do
|
166
|
+
it "sends nil payloads" do
|
167
|
+
@http.should_receive(:request).with('req', nil)
|
168
|
+
@request.should_receive(:process_result)
|
169
|
+
@request.stub!(:response_log)
|
170
|
+
@request.transmit(@uri, 'req', nil)
|
171
|
+
end
|
172
172
|
|
173
|
-
|
174
|
-
|
175
|
-
|
173
|
+
it "passes non-hash payloads straight through" do
|
174
|
+
@request.process_payload("x").should == "x"
|
175
|
+
end
|
176
176
|
|
177
|
-
|
178
|
-
|
179
|
-
|
177
|
+
it "converts a hash payload to urlencoded data" do
|
178
|
+
@request.process_payload(:a => 'b c+d').should == "a=b%20c%2Bd"
|
179
|
+
end
|
180
180
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
181
|
+
it "accepts nested hashes in payload" do
|
182
|
+
payload = @request.process_payload(:user => { :name => 'joe', :location => { :country => 'USA', :state => 'CA' }})
|
183
|
+
payload.should include('user[name]=joe')
|
184
|
+
payload.should include('user[location][country]=USA')
|
185
|
+
payload.should include('user[location][state]=CA')
|
186
|
+
end
|
186
187
|
end
|
187
188
|
|
188
189
|
it "set urlencoded content_type header on hash payloads" do
|
@@ -190,31 +191,33 @@ describe RestClient::Request do
|
|
190
191
|
@request.headers[:content_type].should == 'application/x-www-form-urlencoded'
|
191
192
|
end
|
192
193
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
194
|
+
describe "credentials" do
|
195
|
+
it "sets up the credentials prior to the request" do
|
196
|
+
@http.stub!(:request)
|
197
|
+
@request.stub!(:process_result)
|
198
|
+
@request.stub!(:response_log)
|
197
199
|
|
198
|
-
|
199
|
-
|
200
|
-
|
200
|
+
@request.stub!(:user).and_return('joe')
|
201
|
+
@request.stub!(:password).and_return('mypass')
|
202
|
+
@request.should_receive(:setup_credentials).with('req')
|
201
203
|
|
202
|
-
|
203
|
-
|
204
|
+
@request.transmit(@uri, 'req', nil)
|
205
|
+
end
|
204
206
|
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
207
|
+
it "does not attempt to send any credentials if user is nil" do
|
208
|
+
@request.stub!(:user).and_return(nil)
|
209
|
+
req = mock("request")
|
210
|
+
req.should_not_receive(:basic_auth)
|
211
|
+
@request.setup_credentials(req)
|
212
|
+
end
|
211
213
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
214
|
+
it "setup credentials when there's a user" do
|
215
|
+
@request.stub!(:user).and_return('joe')
|
216
|
+
@request.stub!(:password).and_return('mypass')
|
217
|
+
req = mock("request")
|
218
|
+
req.should_receive(:basic_auth).with('joe', 'mypass')
|
219
|
+
@request.setup_credentials(req)
|
220
|
+
end
|
218
221
|
end
|
219
222
|
|
220
223
|
it "catches EOFError and shows the more informative ServerBrokeConnection" do
|
@@ -234,275 +237,297 @@ describe RestClient::Request do
|
|
234
237
|
RestClient::Request.execute(1 => 2)
|
235
238
|
end
|
236
239
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
240
|
+
describe "redirection" do
|
241
|
+
it "raises a Redirect with the new location when the response is in the 30x range" do
|
242
|
+
res = mock('response', :code => '301', :header => { 'Location' => 'http://new/resource'}, :[] => ['content-encoding' => ''], :body => '' )
|
243
|
+
lambda { @request.process_result(res) }.should raise_error(RestClient::Redirect) { |e| e.url.should == 'http://new/resource'}
|
244
|
+
end
|
241
245
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
+
it "handles redirects with relative paths" do
|
247
|
+
res = mock('response', :code => '301', :header => { 'Location' => 'index' }, :[] => ['content-encoding' => ''], :body => '' )
|
248
|
+
lambda { @request.process_result(res) }.should raise_error(RestClient::Redirect) { |e| e.url.should == 'http://some/index' }
|
249
|
+
end
|
246
250
|
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
251
|
+
it "handles redirects with absolute paths" do
|
252
|
+
@request.instance_variable_set('@url', 'http://some/place/else')
|
253
|
+
res = mock('response', :code => '301', :header => { 'Location' => '/index' }, :[] => ['content-encoding' => ''], :body => '' )
|
254
|
+
lambda { @request.process_result(res) }.should raise_error(RestClient::Redirect) { |e| e.url.should == 'http://some/index' }
|
255
|
+
end
|
252
256
|
|
253
|
-
|
254
|
-
|
257
|
+
it "uses GET and clears payload and removes possible harmful headers when following 30x redirects" do
|
258
|
+
url = "http://example.com/redirected"
|
255
259
|
|
256
|
-
|
260
|
+
@request.should_receive(:execute_inner).once.ordered.and_raise(RestClient::Redirect.new(url))
|
257
261
|
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
262
|
+
@request.should_receive(:execute_inner).once.ordered do
|
263
|
+
@request.processed_headers.should_not have_key("Content-Length")
|
264
|
+
@request.url.should == url
|
265
|
+
@request.method.should == :get
|
266
|
+
@request.payload.should be_nil
|
267
|
+
end
|
263
268
|
|
264
|
-
|
269
|
+
@request.execute
|
270
|
+
end
|
265
271
|
end
|
266
272
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
273
|
+
describe "exception" do
|
274
|
+
it "raises Unauthorized when the response is 401" do
|
275
|
+
res = mock('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
|
276
|
+
lambda { @request.process_result(res) }.should raise_error(RestClient::Unauthorized)
|
277
|
+
end
|
271
278
|
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
279
|
+
it "raises ResourceNotFound when the response is 404" do
|
280
|
+
res = mock('response', :code => '404', :[] => ['content-encoding' => ''], :body => '' )
|
281
|
+
lambda { @request.process_result(res) }.should raise_error(RestClient::ResourceNotFound)
|
282
|
+
end
|
276
283
|
|
277
|
-
|
278
|
-
|
279
|
-
|
284
|
+
it "raises RequestFailed otherwise" do
|
285
|
+
res = mock('response', :code => '500', :[] => ['content-encoding' => ''], :body => '' )
|
286
|
+
lambda { @request.process_result(res) }.should raise_error(RestClient::InternalServerError)
|
287
|
+
end
|
280
288
|
end
|
281
289
|
|
282
|
-
|
283
|
-
|
284
|
-
|
290
|
+
describe "block usage" do
|
291
|
+
it "returns what asked to" do
|
292
|
+
res = mock('response', :code => '401', :[] => ['content-encoding' => ''], :body => '' )
|
293
|
+
@request.process_result(res){|response| "foo"}.should == "foo"
|
294
|
+
end
|
285
295
|
end
|
286
296
|
|
287
|
-
|
288
|
-
|
289
|
-
|
297
|
+
describe "proxy" do
|
298
|
+
it "creates a proxy class if a proxy url is given" do
|
299
|
+
RestClient.stub!(:proxy).and_return("http://example.com/")
|
300
|
+
@request.net_http_class.should include(Net::HTTP::ProxyDelta)
|
301
|
+
end
|
290
302
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
RestClient::Request.new(:method => :get, :url => 'http://url').request_log
|
303
|
+
it "creates a non-proxy class if a proxy url is not given" do
|
304
|
+
@request.net_http_class.should_not include(Net::HTTP::ProxyDelta)
|
305
|
+
end
|
295
306
|
end
|
296
307
|
|
297
|
-
it "logs a post request with a small payload" do
|
298
|
-
['RestClient.post "http://url", headers: {"Accept-encoding"=>"gzip, deflate", "Content-Length"=>"3", "Accept"=>"*/*; q=0.5, application/xml"}, paylod: "foo"',
|
299
|
-
'RestClient.post "http://url", headers: {"Accept"=>"*/*; q=0.5, application/xml", "Accept-encoding"=>"gzip, deflate", "Content-Length"=>"3"}, paylod: "foo"'].should include
|
300
|
-
RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo').request_log
|
301
|
-
end
|
302
308
|
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
309
|
+
describe "logging" do
|
310
|
+
it "logs a get request" do
|
311
|
+
log = RestClient.log = []
|
312
|
+
RestClient::Request.new(:method => :get, :url => 'http://url').log_request
|
313
|
+
['RestClient.get "http://url", "Accept-encoding"=>"gzip, deflate", "Accept"=>"*/*; q=0.5, application/xml"' + "\n",
|
314
|
+
'RestClient.get "http://url", "Accept"=>"*/*; q=0.5, application/xml", "Accept-encoding"=>"gzip, deflate"' + "\n"].should include(log[0])
|
315
|
+
end
|
308
316
|
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
317
|
+
it "logs a post request with a small payload" do
|
318
|
+
log = RestClient.log = []
|
319
|
+
RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo').log_request
|
320
|
+
['RestClient.post "http://url", "foo", "Accept-encoding"=>"gzip, deflate", "Content-Length"=>"3", "Accept"=>"*/*; q=0.5, application/xml"' + "\n",
|
321
|
+
'RestClient.post "http://url", "foo", "Accept"=>"*/*; q=0.5, application/xml", "Accept-encoding"=>"gzip, deflate", "Content-Length"=>"3"' + "\n"].should include(log[0])
|
322
|
+
end
|
314
323
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
324
|
+
it "logs a post request with a large payload" do
|
325
|
+
log = RestClient.log = []
|
326
|
+
RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000)).log_request
|
327
|
+
['RestClient.post "http://url", 1000 byte length, "Accept-encoding"=>"gzip, deflate", "Content-Length"=>"1000", "Accept"=>"*/*; q=0.5, application/xml"' + "\n",
|
328
|
+
'RestClient.post "http://url", 1000 byte length, "Accept"=>"*/*; q=0.5, application/xml", "Accept-encoding"=>"gzip, deflate", "Content-Length"=>"1000"' + "\n"].should include(log[0])
|
329
|
+
end
|
320
330
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
331
|
+
it "logs input headers as a hash" do
|
332
|
+
log = RestClient.log = []
|
333
|
+
RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain' }).log_request
|
334
|
+
['RestClient.get "http://url", "Accept-encoding"=>"gzip, deflate", "Accept"=>"text/plain"' + "\n",
|
335
|
+
'RestClient.get "http://url", "Accept"=>"text/plain", "Accept-encoding"=>"gzip, deflate"' + "\n"].should include(log[0])
|
336
|
+
end
|
326
337
|
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
338
|
+
it "logs a response including the status code, content type, and result body size in bytes" do
|
339
|
+
log = RestClient.log = []
|
340
|
+
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
|
341
|
+
res.stub!(:[]).with('Content-type').and_return('text/html')
|
342
|
+
@request.log_response res
|
343
|
+
log[0].should == "# => 200 OK | text/html 4 bytes\n"
|
344
|
+
end
|
345
|
+
|
346
|
+
it "logs a response with a nil Content-type" do
|
347
|
+
log = RestClient.log = []
|
348
|
+
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
|
349
|
+
res.stub!(:[]).with('Content-type').and_return(nil)
|
350
|
+
@request.log_response res
|
351
|
+
log[0].should == "# => 200 OK | 4 bytes\n"
|
352
|
+
end
|
353
|
+
|
354
|
+
it "logs a response with a nil body" do
|
355
|
+
log = RestClient.log = []
|
356
|
+
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => nil)
|
357
|
+
res.stub!(:[]).with('Content-type').and_return('text/html; charset=utf-8')
|
358
|
+
@request.log_response res
|
359
|
+
log[0].should == "# => 200 OK | text/html 0 bytes\n"
|
360
|
+
end
|
331
361
|
end
|
332
362
|
|
333
363
|
it "strips the charset from the response content type" do
|
364
|
+
log = RestClient.log = []
|
334
365
|
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
|
335
366
|
res.stub!(:[]).with('Content-type').and_return('text/html; charset=utf-8')
|
336
|
-
@request.
|
367
|
+
@request.log_response res
|
368
|
+
log[0].should == "# => 200 OK | text/html 4 bytes\n"
|
337
369
|
end
|
338
370
|
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
371
|
+
describe "timeout" do
|
372
|
+
it "set read_timeout" do
|
373
|
+
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
|
374
|
+
@http.stub!(:request)
|
375
|
+
@request.stub!(:process_result)
|
376
|
+
@request.stub!(:response_log)
|
344
377
|
|
345
|
-
|
346
|
-
RestClient.stub!(:log).and_return('stderr')
|
347
|
-
STDERR.should_receive(:puts).with('xyz')
|
348
|
-
@request.display_log('xyz')
|
349
|
-
end
|
378
|
+
@net.should_receive(:read_timeout=).with(123)
|
350
379
|
|
351
|
-
|
352
|
-
|
353
|
-
f = mock('file handle')
|
354
|
-
File.should_receive(:open).with('/tmp/restclient.log', 'a').and_yield(f)
|
355
|
-
f.should_receive(:puts).with('xyz')
|
356
|
-
@request.display_log('xyz')
|
357
|
-
end
|
380
|
+
@request.transmit(@uri, 'req', nil)
|
381
|
+
end
|
358
382
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
383
|
+
it "set open_timeout" do
|
384
|
+
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :open_timeout => 123)
|
385
|
+
@http.stub!(:request)
|
386
|
+
@request.stub!(:process_result)
|
387
|
+
@request.stub!(:response_log)
|
364
388
|
|
365
|
-
|
389
|
+
@net.should_receive(:open_timeout=).with(123)
|
366
390
|
|
367
|
-
|
391
|
+
@request.transmit(@uri, 'req', nil)
|
392
|
+
end
|
368
393
|
end
|
369
394
|
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
end
|
395
|
+
describe "ssl" do
|
396
|
+
it "uses SSL when the URI refers to a https address" do
|
397
|
+
@uri.stub!(:is_a?).with(URI::HTTPS).and_return(true)
|
398
|
+
@net.should_receive(:use_ssl=).with(true)
|
399
|
+
@http.stub!(:request)
|
400
|
+
@request.stub!(:process_result)
|
401
|
+
@request.stub!(:response_log)
|
402
|
+
@request.transmit(@uri, 'req', 'payload')
|
403
|
+
end
|
380
404
|
|
381
|
-
|
382
|
-
|
383
|
-
|
405
|
+
it "should default to not verifying ssl certificates" do
|
406
|
+
@request.verify_ssl.should == false
|
407
|
+
end
|
384
408
|
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
409
|
+
it "should set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is false" do
|
410
|
+
@net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
411
|
+
@http.stub!(:request)
|
412
|
+
@request.stub!(:process_result)
|
413
|
+
@request.stub!(:response_log)
|
414
|
+
@request.transmit(@uri, 'req', 'payload')
|
415
|
+
end
|
392
416
|
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
417
|
+
it "should not set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is true" do
|
418
|
+
@request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload', :verify_ssl => true)
|
419
|
+
@net.should_not_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
420
|
+
@http.stub!(:request)
|
421
|
+
@request.stub!(:process_result)
|
422
|
+
@request.stub!(:response_log)
|
423
|
+
@request.transmit(@uri, 'req', 'payload')
|
424
|
+
end
|
401
425
|
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
426
|
+
it "should set net.verify_mode to the passed value if verify_ssl is an OpenSSL constant" do
|
427
|
+
mode = OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
428
|
+
@request = RestClient::Request.new( :method => :put,
|
429
|
+
:url => 'https://some/resource',
|
430
|
+
:payload => 'payload',
|
431
|
+
:verify_ssl => mode )
|
432
|
+
@net.should_receive(:verify_mode=).with(mode)
|
433
|
+
@http.stub!(:request)
|
434
|
+
@request.stub!(:process_result)
|
435
|
+
@request.stub!(:response_log)
|
436
|
+
@request.transmit(@uri, 'req', 'payload')
|
437
|
+
end
|
414
438
|
|
415
|
-
|
416
|
-
|
417
|
-
|
439
|
+
it "should default to not having an ssl_client_cert" do
|
440
|
+
@request.ssl_client_cert.should be(nil)
|
441
|
+
end
|
418
442
|
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
443
|
+
it "should set the ssl_client_cert if provided" do
|
444
|
+
@request = RestClient::Request.new(
|
445
|
+
:method => :put,
|
446
|
+
:url => 'https://some/resource',
|
447
|
+
:payload => 'payload',
|
448
|
+
:ssl_client_cert => "whatsupdoc!"
|
449
|
+
)
|
450
|
+
@net.should_receive(:cert=).with("whatsupdoc!")
|
451
|
+
@http.stub!(:request)
|
452
|
+
@request.stub!(:process_result)
|
453
|
+
@request.stub!(:response_log)
|
454
|
+
@request.transmit(@uri, 'req', 'payload')
|
455
|
+
end
|
432
456
|
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
457
|
+
it "should not set the ssl_client_cert if it is not provided" do
|
458
|
+
@request = RestClient::Request.new(
|
459
|
+
:method => :put,
|
460
|
+
:url => 'https://some/resource',
|
461
|
+
:payload => 'payload'
|
462
|
+
)
|
463
|
+
@net.should_not_receive(:cert=).with("whatsupdoc!")
|
464
|
+
@http.stub!(:request)
|
465
|
+
@request.stub!(:process_result)
|
466
|
+
@request.stub!(:response_log)
|
467
|
+
@request.transmit(@uri, 'req', 'payload')
|
468
|
+
end
|
445
469
|
|
446
|
-
|
447
|
-
|
448
|
-
|
470
|
+
it "should default to not having an ssl_client_key" do
|
471
|
+
@request.ssl_client_key.should be(nil)
|
472
|
+
end
|
449
473
|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
474
|
+
it "should set the ssl_client_key if provided" do
|
475
|
+
@request = RestClient::Request.new(
|
476
|
+
:method => :put,
|
477
|
+
:url => 'https://some/resource',
|
478
|
+
:payload => 'payload',
|
479
|
+
:ssl_client_key => "whatsupdoc!"
|
480
|
+
)
|
481
|
+
@net.should_receive(:key=).with("whatsupdoc!")
|
482
|
+
@http.stub!(:request)
|
483
|
+
@request.stub!(:process_result)
|
484
|
+
@request.stub!(:response_log)
|
485
|
+
@request.transmit(@uri, 'req', 'payload')
|
486
|
+
end
|
463
487
|
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
488
|
+
it "should not set the ssl_client_key if it is not provided" do
|
489
|
+
@request = RestClient::Request.new(
|
490
|
+
:method => :put,
|
491
|
+
:url => 'https://some/resource',
|
492
|
+
:payload => 'payload'
|
493
|
+
)
|
494
|
+
@net.should_not_receive(:key=).with("whatsupdoc!")
|
495
|
+
@http.stub!(:request)
|
496
|
+
@request.stub!(:process_result)
|
497
|
+
@request.stub!(:response_log)
|
498
|
+
@request.transmit(@uri, 'req', 'payload')
|
499
|
+
end
|
476
500
|
|
477
|
-
|
478
|
-
|
479
|
-
|
501
|
+
it "should default to not having an ssl_ca_file" do
|
502
|
+
@request.ssl_ca_file.should be(nil)
|
503
|
+
end
|
480
504
|
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
505
|
+
it "should set the ssl_ca_file if provided" do
|
506
|
+
@request = RestClient::Request.new(
|
507
|
+
:method => :put,
|
508
|
+
:url => 'https://some/resource',
|
509
|
+
:payload => 'payload',
|
510
|
+
:ssl_ca_file => "Certificate Authority File"
|
511
|
+
)
|
512
|
+
@net.should_receive(:ca_file=).with("Certificate Authority File")
|
513
|
+
@http.stub!(:request)
|
514
|
+
@request.stub!(:process_result)
|
515
|
+
@request.stub!(:response_log)
|
516
|
+
@request.transmit(@uri, 'req', 'payload')
|
517
|
+
end
|
494
518
|
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
519
|
+
it "should not set the ssl_ca_file if it is not provided" do
|
520
|
+
@request = RestClient::Request.new(
|
521
|
+
:method => :put,
|
522
|
+
:url => 'https://some/resource',
|
523
|
+
:payload => 'payload'
|
524
|
+
)
|
525
|
+
@net.should_not_receive(:ca_file=).with("Certificate Authority File")
|
526
|
+
@http.stub!(:request)
|
527
|
+
@request.stub!(:process_result)
|
528
|
+
@request.stub!(:response_log)
|
529
|
+
@request.transmit(@uri, 'req', 'payload')
|
530
|
+
end
|
506
531
|
end
|
507
532
|
|
508
533
|
it "should still return a response object for 204 No Content responses" do
|
@@ -512,7 +537,7 @@ describe RestClient::Request do
|
|
512
537
|
:payload => 'payload'
|
513
538
|
)
|
514
539
|
net_http_res = Net::HTTPNoContent.new("", "204", "No Content")
|
515
|
-
net_http_res.stub(:read_body).and_return(nil)
|
540
|
+
net_http_res.stub!(:read_body).and_return(nil)
|
516
541
|
@http.should_receive(:request).and_return(@request.fetch_body(net_http_res))
|
517
542
|
response = @request.transmit(@uri, 'req', 'payload')
|
518
543
|
response.should_not be_nil
|