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 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: