rest-client 0.6.2 → 0.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rest-client might be problematic. Click here for more details.
- data/Rakefile +1 -1
- data/lib/rest_client.rb +55 -3
- data/spec/rest_client_spec.rb +98 -0
- metadata +2 -2
data/Rakefile
CHANGED
data/lib/rest_client.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'uri'
|
2
2
|
require 'net/https'
|
3
|
+
require 'zlib'
|
4
|
+
require 'stringio'
|
3
5
|
|
4
6
|
require File.dirname(__FILE__) + '/resource'
|
5
7
|
require File.dirname(__FILE__) + '/request_errors'
|
@@ -59,6 +61,18 @@ module RestClient
|
|
59
61
|
:headers => headers)
|
60
62
|
end
|
61
63
|
|
64
|
+
# Print log of RestClient calls. Value can be stdout, stderr, or a filename.
|
65
|
+
# You can also configure logging by the environment variable RESTCLIENT_LOG.
|
66
|
+
def self.log=(log)
|
67
|
+
@@log = log
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.log # :nodoc:
|
71
|
+
return ENV['RESTCLIENT_LOG'] if ENV['RESTCLIENT_LOG']
|
72
|
+
return @@log if defined? @@log
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
|
62
76
|
# Internal class used to build and execute the request.
|
63
77
|
class Request
|
64
78
|
attr_reader :method, :url, :payload, :headers, :user, :password
|
@@ -136,8 +150,12 @@ module RestClient
|
|
136
150
|
net = Net::HTTP.new(uri.host, uri.port)
|
137
151
|
net.use_ssl = uri.is_a?(URI::HTTPS)
|
138
152
|
|
153
|
+
display_log request_log
|
154
|
+
|
139
155
|
net.start do |http|
|
140
|
-
|
156
|
+
res = http.request(req, payload || "")
|
157
|
+
display_log response_log(res)
|
158
|
+
process_result res
|
141
159
|
end
|
142
160
|
rescue EOFError
|
143
161
|
raise RestClient::ServerBrokeConnection
|
@@ -151,7 +169,7 @@ module RestClient
|
|
151
169
|
|
152
170
|
def process_result(res)
|
153
171
|
if %w(200 201 202).include? res.code
|
154
|
-
res.body
|
172
|
+
decode res['content-encoding'], res.body
|
155
173
|
elsif %w(301 302 303).include? res.code
|
156
174
|
url = res.header['Location']
|
157
175
|
|
@@ -171,8 +189,42 @@ module RestClient
|
|
171
189
|
end
|
172
190
|
end
|
173
191
|
|
192
|
+
def decode(content_encoding, body)
|
193
|
+
if content_encoding == 'gzip'
|
194
|
+
Zlib::GzipReader.new(StringIO.new(body)).read
|
195
|
+
elsif content_encoding == 'deflate'
|
196
|
+
Zlib::Inflate.new.inflate(body)
|
197
|
+
else
|
198
|
+
body
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def request_log
|
203
|
+
out = []
|
204
|
+
out << "RestClient.#{method} #{url.inspect}"
|
205
|
+
out << (payload.size > 100 ? "(#{payload.size} byte payload)".inspect : payload.inspect) if payload
|
206
|
+
out << headers.inspect.gsub(/^\{/, '').gsub(/\}$/, '') unless headers.empty?
|
207
|
+
out.join(', ')
|
208
|
+
end
|
209
|
+
|
210
|
+
def response_log(res)
|
211
|
+
"# => #{res.code} #{res.class.to_s.gsub(/^Net::HTTP/, '')} | #{(res['Content-type'] || '').gsub(/;.*$/, '')} #{res.body.size} bytes"
|
212
|
+
end
|
213
|
+
|
214
|
+
def display_log(msg)
|
215
|
+
return unless log_to = RestClient.log
|
216
|
+
|
217
|
+
if log_to == 'stdout'
|
218
|
+
STDOUT.puts msg
|
219
|
+
elsif log_to == 'stderr'
|
220
|
+
STDERR.puts msg
|
221
|
+
else
|
222
|
+
File.open(log_to, 'a') { |f| f.puts msg }
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
174
226
|
def default_headers
|
175
|
-
{ :accept => 'application/xml' }
|
227
|
+
{ :accept => 'application/xml', :accept_encoding => 'gzip, deflate' }
|
176
228
|
end
|
177
229
|
end
|
178
230
|
end
|
data/spec/rest_client_spec.rb
CHANGED
@@ -23,6 +23,29 @@ describe RestClient do
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
context "logging" do
|
27
|
+
after do
|
28
|
+
RestClient.log = nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it "gets the log source from the RESTCLIENT_LOG environment variable" do
|
32
|
+
ENV.stub!(:[]).with('RESTCLIENT_LOG').and_return('from env')
|
33
|
+
RestClient.log = 'from class method'
|
34
|
+
RestClient.log.should == 'from env'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "sets a destination for log output, used if no environment variable is set" do
|
38
|
+
ENV.stub!(:[]).with('RESTCLIENT_LOG').and_return(nil)
|
39
|
+
RestClient.log = 'from class method'
|
40
|
+
RestClient.log.should == 'from class method'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns nil (no logging) if neither are set (default)" do
|
44
|
+
ENV.stub!(:[]).with('RESTCLIENT_LOG').and_return(nil)
|
45
|
+
RestClient.log.should == nil
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
26
49
|
context RestClient::Request do
|
27
50
|
before do
|
28
51
|
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
|
@@ -43,10 +66,23 @@ describe RestClient do
|
|
43
66
|
@request.default_headers[:accept].should == 'application/xml'
|
44
67
|
end
|
45
68
|
|
69
|
+
it "decodes an uncompressed result body by passing it straight through" do
|
70
|
+
@request.decode(nil, 'xyz').should == 'xyz'
|
71
|
+
end
|
72
|
+
|
73
|
+
it "decodes a gzip body" do
|
74
|
+
@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"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "decodes a deflated body" do
|
78
|
+
@request.decode('deflate', "x\234+\316\317MUHIM\313I,IMQ(I\255(\001\000A\223\006\363").should == "some deflated text"
|
79
|
+
end
|
80
|
+
|
46
81
|
it "processes a successful result" do
|
47
82
|
res = mock("result")
|
48
83
|
res.stub!(:code).and_return("200")
|
49
84
|
res.stub!(:body).and_return('body')
|
85
|
+
res.stub!(:[]).with('content-encoding').and_return(nil)
|
50
86
|
@request.process_result(res).should == 'body'
|
51
87
|
end
|
52
88
|
|
@@ -106,6 +142,7 @@ describe RestClient do
|
|
106
142
|
it "transmits the request with Net::HTTP" do
|
107
143
|
@http.should_receive(:request).with('req', 'payload')
|
108
144
|
@request.should_receive(:process_result)
|
145
|
+
@request.should_receive(:response_log)
|
109
146
|
@request.transmit(@uri, 'req', 'payload')
|
110
147
|
end
|
111
148
|
|
@@ -114,12 +151,14 @@ describe RestClient do
|
|
114
151
|
@net.should_receive(:use_ssl=).with(true)
|
115
152
|
@http.stub!(:request)
|
116
153
|
@request.stub!(:process_result)
|
154
|
+
@request.stub!(:response_log)
|
117
155
|
@request.transmit(@uri, 'req', 'payload')
|
118
156
|
end
|
119
157
|
|
120
158
|
it "doesn't send nil payloads" do
|
121
159
|
@http.should_receive(:request).with('req', '')
|
122
160
|
@request.should_receive(:process_result)
|
161
|
+
@request.stub!(:response_log)
|
123
162
|
@request.transmit(@uri, 'req', nil)
|
124
163
|
end
|
125
164
|
|
@@ -146,6 +185,7 @@ describe RestClient do
|
|
146
185
|
it "sets up the credentials prior to the request" do
|
147
186
|
@http.stub!(:request)
|
148
187
|
@request.stub!(:process_result)
|
188
|
+
@request.stub!(:response_log)
|
149
189
|
|
150
190
|
@request.stub!(:user).and_return('joe')
|
151
191
|
@request.stub!(:password).and_return('mypass')
|
@@ -216,5 +256,63 @@ describe RestClient do
|
|
216
256
|
res = mock('response', :code => '500')
|
217
257
|
lambda { @request.process_result(res) }.should raise_error(RestClient::RequestFailed)
|
218
258
|
end
|
259
|
+
|
260
|
+
it "logs a get request" do
|
261
|
+
RestClient::Request.new(:method => :get, :url => 'http://url').request_log.should ==
|
262
|
+
'RestClient.get "http://url"'
|
263
|
+
end
|
264
|
+
|
265
|
+
it "logs a post request with a small payload" do
|
266
|
+
RestClient::Request.new(:method => :post, :url => 'http://url', :payload => 'foo').request_log.should ==
|
267
|
+
'RestClient.post "http://url", "foo"'
|
268
|
+
end
|
269
|
+
|
270
|
+
it "logs a post request with a large payload" do
|
271
|
+
RestClient::Request.new(:method => :post, :url => 'http://url', :payload => ('x' * 1000)).request_log.should ==
|
272
|
+
'RestClient.post "http://url", "(1000 byte payload)"'
|
273
|
+
end
|
274
|
+
|
275
|
+
it "logs input headers as a hash" do
|
276
|
+
RestClient::Request.new(:method => :get, :url => 'http://url', :headers => { :accept => 'text/plain' }).request_log.should ==
|
277
|
+
'RestClient.get "http://url", :accept=>"text/plain"'
|
278
|
+
end
|
279
|
+
|
280
|
+
it "logs a response including the status code, content type, and result body size in bytes" do
|
281
|
+
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
|
282
|
+
res.stub!(:[]).with('Content-type').and_return('text/html')
|
283
|
+
@request.response_log(res).should == "# => 200 OK | text/html 4 bytes"
|
284
|
+
end
|
285
|
+
|
286
|
+
it "logs a response with a nil Content-type" do
|
287
|
+
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
|
288
|
+
res.stub!(:[]).with('Content-type').and_return(nil)
|
289
|
+
@request.response_log(res).should == "# => 200 OK | 4 bytes"
|
290
|
+
end
|
291
|
+
|
292
|
+
it "strips the charset from the response content type" do
|
293
|
+
res = mock('result', :code => '200', :class => Net::HTTPOK, :body => 'abcd')
|
294
|
+
res.stub!(:[]).with('Content-type').and_return('text/html; charset=utf-8')
|
295
|
+
@request.response_log(res).should == "# => 200 OK | text/html 4 bytes"
|
296
|
+
end
|
297
|
+
|
298
|
+
it "displays the log to stdout" do
|
299
|
+
RestClient.stub!(:log).and_return('stdout')
|
300
|
+
STDOUT.should_receive(:puts).with('xyz')
|
301
|
+
@request.display_log('xyz')
|
302
|
+
end
|
303
|
+
|
304
|
+
it "displays the log to stderr" do
|
305
|
+
RestClient.stub!(:log).and_return('stderr')
|
306
|
+
STDERR.should_receive(:puts).with('xyz')
|
307
|
+
@request.display_log('xyz')
|
308
|
+
end
|
309
|
+
|
310
|
+
it "append the log to the requested filename" do
|
311
|
+
RestClient.stub!(:log).and_return('/tmp/restclient.log')
|
312
|
+
f = mock('file handle')
|
313
|
+
File.should_receive(:open).with('/tmp/restclient.log', 'a').and_yield(f)
|
314
|
+
f.should_receive(:puts).with('xyz')
|
315
|
+
@request.display_log('xyz')
|
316
|
+
end
|
219
317
|
end
|
220
318
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: "0.7"
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Wiggins
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-08-
|
12
|
+
date: 2008-08-18 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|