rest-client 0.7 → 0.8
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/Rakefile +1 -1
- data/bin/restclient +25 -3
- data/lib/resource.rb +38 -15
- data/lib/rest_client.rb +27 -8
- data/spec/resource_spec.rb +35 -16
- data/spec/rest_client_spec.rb +15 -2
- metadata +5 -5
data/Rakefile
CHANGED
data/bin/restclient
CHANGED
@@ -7,10 +7,18 @@ require "yaml"
|
|
7
7
|
|
8
8
|
def usage(why = nil)
|
9
9
|
puts "failed for reason: #{why}" if why
|
10
|
-
puts "usage: restclient url|name [username] [password]"
|
10
|
+
puts "usage: restclient [get|put|post|delete] url|name [username] [password]"
|
11
|
+
puts " The verb is optional, if you leave it off you'll get an interactive shell."
|
12
|
+
puts " put and post both take the input body on stdin."
|
11
13
|
exit(1)
|
12
14
|
end
|
13
15
|
|
16
|
+
if %w(get put post delete).include? ARGV.first
|
17
|
+
@verb = ARGV.shift
|
18
|
+
else
|
19
|
+
@verb = nil
|
20
|
+
end
|
21
|
+
|
14
22
|
@url = ARGV.shift || 'http://localhost:4567'
|
15
23
|
|
16
24
|
config = YAML.load(File.read(ENV['HOME'] + "/.restclient")) rescue {}
|
@@ -22,7 +30,7 @@ else
|
|
22
30
|
end
|
23
31
|
|
24
32
|
usage("invalid url '#{@url}") unless @url =~ /^https?/
|
25
|
-
usage("
|
33
|
+
usage("too few args") unless ARGV.size < 3
|
26
34
|
|
27
35
|
def r
|
28
36
|
@r ||= RestClient::Resource.new(@url, @username, @password)
|
@@ -30,6 +38,20 @@ end
|
|
30
38
|
|
31
39
|
r # force rc to load
|
32
40
|
|
41
|
+
if @verb
|
42
|
+
begin
|
43
|
+
if %w(put post).include? @verb
|
44
|
+
puts r.send(@verb, STDIN.read)
|
45
|
+
else
|
46
|
+
puts r.send(@verb)
|
47
|
+
end
|
48
|
+
exit 0
|
49
|
+
rescue RestClient::Exception => e
|
50
|
+
puts e.response.body if e.respond_to? :response
|
51
|
+
raise
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
33
55
|
%w(get post put delete).each do |m|
|
34
56
|
eval <<-end_eval
|
35
57
|
def #{m}(path, *args, &b)
|
@@ -43,7 +65,7 @@ def method_missing(s, *args, &b)
|
|
43
65
|
begin
|
44
66
|
r.send(s, *args, &b)
|
45
67
|
rescue RestClient::RequestFailed => e
|
46
|
-
|
68
|
+
print STDERR, e.response.body
|
47
69
|
raise e
|
48
70
|
end
|
49
71
|
end
|
data/lib/resource.rb
CHANGED
@@ -9,55 +9,78 @@ module RestClient
|
|
9
9
|
#
|
10
10
|
# With HTTP basic authentication:
|
11
11
|
#
|
12
|
-
# resource = RestClient::Resource.new('http://protected/resource', 'user', '
|
12
|
+
# resource = RestClient::Resource.new('http://protected/resource', :user => 'user', :password => 'password')
|
13
13
|
# resource.delete
|
14
14
|
#
|
15
|
+
# You can also use resources to share common headers. For headers keys,
|
16
|
+
# symbols are converted to strings. Example:
|
17
|
+
#
|
18
|
+
# resource = RestClient::Resource.new('http://some/resource', :headers => { :client_version => 1 })
|
19
|
+
#
|
20
|
+
# This header will be transported as X-Client-Version (notice the X prefix,
|
21
|
+
# capitalization and hyphens)
|
22
|
+
#
|
15
23
|
# Use the [] syntax to allocate subresources:
|
16
24
|
#
|
17
|
-
# site = RestClient::Resource.new('http://example.com', 'adam', 'mypasswd')
|
25
|
+
# site = RestClient::Resource.new('http://example.com', :user => 'adam', :password => 'mypasswd')
|
18
26
|
# site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
|
19
27
|
#
|
20
28
|
class Resource
|
21
|
-
attr_reader :url, :
|
29
|
+
attr_reader :url, :options
|
22
30
|
|
23
|
-
def initialize(url,
|
31
|
+
def initialize(url, options={}, backwards_compatibility=nil)
|
24
32
|
@url = url
|
25
|
-
|
26
|
-
|
33
|
+
if options.class == Hash
|
34
|
+
@options = options
|
35
|
+
else # compatibility with previous versions
|
36
|
+
@options = { :user => options, :password => backwards_compatibility }
|
37
|
+
end
|
27
38
|
end
|
28
39
|
|
29
|
-
def get(
|
40
|
+
def get(additional_headers={})
|
30
41
|
Request.execute(:method => :get,
|
31
42
|
:url => url,
|
32
43
|
:user => user,
|
33
44
|
:password => password,
|
34
|
-
:headers => headers)
|
45
|
+
:headers => headers.merge(additional_headers))
|
35
46
|
end
|
36
47
|
|
37
|
-
def post(payload,
|
48
|
+
def post(payload, additional_headers={})
|
38
49
|
Request.execute(:method => :post,
|
39
50
|
:url => url,
|
40
51
|
:payload => payload,
|
41
52
|
:user => user,
|
42
53
|
:password => password,
|
43
|
-
:headers => headers)
|
54
|
+
:headers => headers.merge(additional_headers))
|
44
55
|
end
|
45
56
|
|
46
|
-
def put(payload,
|
57
|
+
def put(payload, additional_headers={})
|
47
58
|
Request.execute(:method => :put,
|
48
59
|
:url => url,
|
49
60
|
:payload => payload,
|
50
61
|
:user => user,
|
51
62
|
:password => password,
|
52
|
-
:headers => headers)
|
63
|
+
:headers => headers.merge(additional_headers))
|
53
64
|
end
|
54
65
|
|
55
|
-
def delete(
|
66
|
+
def delete(additional_headers={})
|
56
67
|
Request.execute(:method => :delete,
|
57
68
|
:url => url,
|
58
69
|
:user => user,
|
59
70
|
:password => password,
|
60
|
-
:headers => headers)
|
71
|
+
:headers => headers.merge(additional_headers))
|
72
|
+
end
|
73
|
+
|
74
|
+
def user
|
75
|
+
options[:user]
|
76
|
+
end
|
77
|
+
|
78
|
+
def password
|
79
|
+
options[:password]
|
80
|
+
end
|
81
|
+
|
82
|
+
def headers
|
83
|
+
options[:headers] || {}
|
61
84
|
end
|
62
85
|
|
63
86
|
# Construct a subresource, preserving authentication.
|
@@ -87,7 +110,7 @@ module RestClient
|
|
87
110
|
# comments.post 'Hello', :content_type => 'text/plain'
|
88
111
|
#
|
89
112
|
def [](suburl)
|
90
|
-
self.class.new(concat_urls(url, suburl),
|
113
|
+
self.class.new(concat_urls(url, suburl), options)
|
91
114
|
end
|
92
115
|
|
93
116
|
def concat_urls(url, suburl) # :nodoc:
|
data/lib/rest_client.rb
CHANGED
@@ -29,6 +29,14 @@ require File.dirname(__FILE__) + '/request_errors'
|
|
29
29
|
# # DELETE
|
30
30
|
# RestClient.delete 'http://example.com/resource'
|
31
31
|
#
|
32
|
+
# To use with a proxy, just set RestClient.proxy to the proper http proxy:
|
33
|
+
#
|
34
|
+
# RestClient.proxy = "http://proxy.example.com/"
|
35
|
+
#
|
36
|
+
# Or inherit the proxy from the environment:
|
37
|
+
#
|
38
|
+
# RestClient.proxy = ENV['http_proxy']
|
39
|
+
#
|
32
40
|
# For live tests of RestClient, try using http://rest-test.heroku.com, which echoes back information about the rest call:
|
33
41
|
#
|
34
42
|
# >> RestClient.put 'http://rest-test.heroku.com/resource', :foo => 'baz'
|
@@ -61,6 +69,10 @@ module RestClient
|
|
61
69
|
:headers => headers)
|
62
70
|
end
|
63
71
|
|
72
|
+
class <<self
|
73
|
+
attr_accessor :proxy
|
74
|
+
end
|
75
|
+
|
64
76
|
# Print log of RestClient calls. Value can be stdout, stderr, or a filename.
|
65
77
|
# You can also configure logging by the environment variable RESTCLIENT_LOG.
|
66
78
|
def self.log=(log)
|
@@ -99,19 +111,26 @@ module RestClient
|
|
99
111
|
|
100
112
|
def execute_inner
|
101
113
|
uri = parse_url_with_auth(url)
|
102
|
-
transmit uri,
|
114
|
+
transmit uri, net_http_request_class(method).new(uri.request_uri, make_headers(headers)), payload
|
103
115
|
end
|
104
116
|
|
105
117
|
def make_headers(user_headers)
|
106
|
-
final
|
107
|
-
|
108
|
-
|
109
|
-
|
118
|
+
default_headers.merge(user_headers).inject({}) do |final, (key, value)|
|
119
|
+
final[key.to_s.gsub(/_/, '-').capitalize] = value.to_s
|
120
|
+
final
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
def net_http_class
|
125
|
+
if RestClient.proxy
|
126
|
+
proxy_uri = URI.parse(RestClient.proxy)
|
127
|
+
Net::HTTP::Proxy(proxy_uri.host, proxy_uri.port, proxy_uri.user, proxy_uri.password)
|
128
|
+
else
|
129
|
+
Net::HTTP
|
110
130
|
end
|
111
|
-
final
|
112
131
|
end
|
113
132
|
|
114
|
-
def
|
133
|
+
def net_http_request_class(method)
|
115
134
|
Net::HTTP.const_get(method.to_s.capitalize)
|
116
135
|
end
|
117
136
|
|
@@ -147,7 +166,7 @@ module RestClient
|
|
147
166
|
def transmit(uri, req, payload)
|
148
167
|
setup_credentials(req)
|
149
168
|
|
150
|
-
net =
|
169
|
+
net = net_http_class.new(uri.host, uri.port)
|
151
170
|
net.use_ssl = uri.is_a?(URI::HTTPS)
|
152
171
|
|
153
172
|
display_log request_log
|
data/spec/resource_spec.rb
CHANGED
@@ -2,33 +2,46 @@ require File.dirname(__FILE__) + '/base'
|
|
2
2
|
|
3
3
|
describe RestClient::Resource do
|
4
4
|
before do
|
5
|
-
@resource = RestClient::Resource.new('http://some/resource', 'jane', 'mypass')
|
5
|
+
@resource = RestClient::Resource.new('http://some/resource', :user => 'jane', :password => 'mypass', :headers => { 'X-Something' => '1'})
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
context "Resource delegation" do
|
9
|
+
it "GET" do
|
10
|
+
RestClient::Request.should_receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => { 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
11
|
+
@resource.get
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
it "POST" do
|
15
|
+
RestClient::Request.should_receive(:execute).with(:method => :post, :url => 'http://some/resource', :payload => 'abc', :headers => { :content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
16
|
+
@resource.post 'abc', :content_type => 'image/jpg'
|
17
|
+
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
it "PUT" do
|
20
|
+
RestClient::Request.should_receive(:execute).with(:method => :put, :url => 'http://some/resource', :payload => 'abc', :headers => { :content_type => 'image/jpg', 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
21
|
+
@resource.put 'abc', :content_type => 'image/jpg'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "DELETE" do
|
25
|
+
RestClient::Request.should_receive(:execute).with(:method => :delete, :url => 'http://some/resource', :headers => { 'X-Something' => '1'}, :user => 'jane', :password => 'mypass')
|
26
|
+
@resource.delete
|
27
|
+
end
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
it "overrides resource headers" do
|
30
|
+
RestClient::Request.should_receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => { 'X-Something' => '2'}, :user => 'jane', :password => 'mypass')
|
31
|
+
@resource.get 'X-Something' => '2'
|
32
|
+
end
|
26
33
|
end
|
27
34
|
|
28
35
|
it "can instantiate with no user/password" do
|
29
36
|
@resource = RestClient::Resource.new('http://some/resource')
|
30
37
|
end
|
31
38
|
|
39
|
+
it "is backwards compatible with previous constructor" do
|
40
|
+
@resource = RestClient::Resource.new('http://some/resource', 'user', 'pass')
|
41
|
+
@resource.user.should == 'user'
|
42
|
+
@resource.password.should == 'pass'
|
43
|
+
end
|
44
|
+
|
32
45
|
it "concatinates urls, inserting a slash when it needs one" do
|
33
46
|
@resource.concat_urls('http://example.com', 'resource').should == 'http://example.com/resource'
|
34
47
|
end
|
@@ -49,4 +62,10 @@ describe RestClient::Resource do
|
|
49
62
|
parent = RestClient::Resource.new('http://example.com')
|
50
63
|
parent['posts'].url.should == 'http://example.com/posts'
|
51
64
|
end
|
65
|
+
|
66
|
+
it "transports options to subresources" do
|
67
|
+
parent = RestClient::Resource.new('http://example.com', :user => 'user', :password => 'password')
|
68
|
+
parent['posts'].user.should == 'user'
|
69
|
+
parent['posts'].password.should == 'password'
|
70
|
+
end
|
52
71
|
end
|
data/spec/rest_client_spec.rb
CHANGED
@@ -112,7 +112,7 @@ describe RestClient do
|
|
112
112
|
end
|
113
113
|
|
114
114
|
it "determines the Net::HTTP class to instantiate by the method name" do
|
115
|
-
@request.
|
115
|
+
@request.net_http_request_class(:put).should == Net::HTTP::Put
|
116
116
|
end
|
117
117
|
|
118
118
|
it "merges user headers with the default headers" do
|
@@ -130,10 +130,14 @@ describe RestClient do
|
|
130
130
|
@request.make_headers(:content_type => 'abc').should == { 'Content-type' => 'abc' }
|
131
131
|
end
|
132
132
|
|
133
|
+
it "converts header values to strings" do
|
134
|
+
@request.make_headers('A' => 1)['A'].should == '1'
|
135
|
+
end
|
136
|
+
|
133
137
|
it "executes by constructing the Net::HTTP object, headers, and payload and calling transmit" do
|
134
138
|
@request.should_receive(:parse_url_with_auth).with('http://some/resource').and_return(@uri)
|
135
139
|
klass = mock("net:http class")
|
136
|
-
@request.should_receive(:
|
140
|
+
@request.should_receive(:net_http_request_class).with(:put).and_return(klass)
|
137
141
|
klass.should_receive(:new).and_return('result')
|
138
142
|
@request.should_receive(:transmit).with(@uri, 'result', 'payload')
|
139
143
|
@request.execute_inner
|
@@ -257,6 +261,15 @@ describe RestClient do
|
|
257
261
|
lambda { @request.process_result(res) }.should raise_error(RestClient::RequestFailed)
|
258
262
|
end
|
259
263
|
|
264
|
+
it "creates a proxy class if a proxy url is given" do
|
265
|
+
RestClient.stub!(:proxy).and_return("http://example.com/")
|
266
|
+
@request.net_http_class.should include(Net::HTTP::ProxyDelta)
|
267
|
+
end
|
268
|
+
|
269
|
+
it "creates a non-proxy class if a proxy url is not given" do
|
270
|
+
@request.net_http_class.should_not include(Net::HTTP::ProxyDelta)
|
271
|
+
end
|
272
|
+
|
260
273
|
it "logs a get request" do
|
261
274
|
RestClient::Request.new(:method => :get, :url => 'http://url').request_log.should ==
|
262
275
|
'RestClient.get "http://url"'
|
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.8"
|
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-
|
12
|
+
date: 2008-10-13 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -23,13 +23,13 @@ extra_rdoc_files: []
|
|
23
23
|
|
24
24
|
files:
|
25
25
|
- Rakefile
|
26
|
-
- lib/request_errors.rb
|
27
26
|
- lib/resource.rb
|
28
27
|
- lib/rest_client.rb
|
29
|
-
-
|
30
|
-
- spec/request_errors_spec.rb
|
28
|
+
- lib/request_errors.rb
|
31
29
|
- spec/resource_spec.rb
|
30
|
+
- spec/request_errors_spec.rb
|
32
31
|
- spec/rest_client_spec.rb
|
32
|
+
- spec/base.rb
|
33
33
|
has_rdoc: true
|
34
34
|
homepage: http://rest-client.heroku.com/
|
35
35
|
post_install_message:
|