rest-client 0.7 → 0.8

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 CHANGED
@@ -31,7 +31,7 @@ require 'rake/gempackagetask'
31
31
  require 'rake/rdoctask'
32
32
  require 'fileutils'
33
33
 
34
- version = "0.7"
34
+ version = "0.8"
35
35
  name = "rest-client"
36
36
 
37
37
  spec = Gem::Specification.new do |s|
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("to few args") unless ARGV.size < 3
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
- puts e.response.body
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', 'pass')
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, :user, :password
29
+ attr_reader :url, :options
22
30
 
23
- def initialize(url, user=nil, password=nil)
31
+ def initialize(url, options={}, backwards_compatibility=nil)
24
32
  @url = url
25
- @user = user
26
- @password = password
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(headers={})
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, headers={})
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, headers={})
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(headers={})
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), user, password)
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, net_http_class(method).new(uri.request_uri, make_headers(headers)), payload
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
- merged = default_headers.merge(user_headers)
108
- merged.keys.each do |key|
109
- final[key.to_s.gsub(/_/, '-').capitalize] = merged[key]
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 net_http_class(method)
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 = Net::HTTP.new(uri.host, uri.port)
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
@@ -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
- it "GET" do
9
- RestClient::Request.should_receive(:execute).with(:method => :get, :url => 'http://some/resource', :headers => {}, :user => 'jane', :password => 'mypass')
10
- @resource.get
11
- end
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
- it "POST" do
14
- RestClient::Request.should_receive(:execute).with(:method => :post, :url => 'http://some/resource', :payload => 'abc', :headers => { :content_type => 'image/jpg' }, :user => 'jane', :password => 'mypass')
15
- @resource.post 'abc', :content_type => 'image/jpg'
16
- end
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
- it "PUT" do
19
- RestClient::Request.should_receive(:execute).with(:method => :put, :url => 'http://some/resource', :payload => 'abc', :headers => { :content_type => 'image/jpg' }, :user => 'jane', :password => 'mypass')
20
- @resource.put 'abc', :content_type => 'image/jpg'
21
- end
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
- it "DELETE" do
24
- RestClient::Request.should_receive(:execute).with(:method => :delete, :url => 'http://some/resource', :headers => {}, :user => 'jane', :password => 'mypass')
25
- @resource.delete
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
@@ -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.net_http_class(:put).should == Net::HTTP::Put
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(:net_http_class).with(:put).and_return(klass)
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.7"
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-08-18 00:00:00 -07:00
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
- - spec/base.rb
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: