rest-client 1.1.0 → 1.2.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.

@@ -1,146 +1,146 @@
1
1
  module RestClient
2
- # A class that can be instantiated for access to a RESTful resource,
3
- # including authentication.
4
- #
5
- # Example:
6
- #
7
- # resource = RestClient::Resource.new('http://some/resource')
8
- # jpg = resource.get(:accept => 'image/jpg')
9
- #
10
- # With HTTP basic authentication:
11
- #
12
- # resource = RestClient::Resource.new('http://protected/resource', :user => 'user', :password => 'password')
13
- # resource.delete
14
- #
15
- # With a timeout (seconds):
16
- #
17
- # RestClient::Resource.new('http://slow', :timeout => 10)
18
- #
19
- # With an open timeout (seconds):
20
- #
21
- # RestClient::Resource.new('http://behindfirewall', :open_timeout => 10)
22
- #
23
- # You can also use resources to share common headers. For headers keys,
24
- # symbols are converted to strings. Example:
25
- #
26
- # resource = RestClient::Resource.new('http://some/resource', :headers => { :client_version => 1 })
27
- #
28
- # This header will be transported as X-Client-Version (notice the X prefix,
29
- # capitalization and hyphens)
30
- #
31
- # Use the [] syntax to allocate subresources:
32
- #
33
- # site = RestClient::Resource.new('http://example.com', :user => 'adam', :password => 'mypasswd')
34
- # site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
35
- #
36
- class Resource
37
- attr_reader :url, :options
2
+ # A class that can be instantiated for access to a RESTful resource,
3
+ # including authentication.
4
+ #
5
+ # Example:
6
+ #
7
+ # resource = RestClient::Resource.new('http://some/resource')
8
+ # jpg = resource.get(:accept => 'image/jpg')
9
+ #
10
+ # With HTTP basic authentication:
11
+ #
12
+ # resource = RestClient::Resource.new('http://protected/resource', :user => 'user', :password => 'password')
13
+ # resource.delete
14
+ #
15
+ # With a timeout (seconds):
16
+ #
17
+ # RestClient::Resource.new('http://slow', :timeout => 10)
18
+ #
19
+ # With an open timeout (seconds):
20
+ #
21
+ # RestClient::Resource.new('http://behindfirewall', :open_timeout => 10)
22
+ #
23
+ # You can also use resources to share common headers. For headers keys,
24
+ # symbols are converted to strings. Example:
25
+ #
26
+ # resource = RestClient::Resource.new('http://some/resource', :headers => { :client_version => 1 })
27
+ #
28
+ # This header will be transported as X-Client-Version (notice the X prefix,
29
+ # capitalization and hyphens)
30
+ #
31
+ # Use the [] syntax to allocate subresources:
32
+ #
33
+ # site = RestClient::Resource.new('http://example.com', :user => 'adam', :password => 'mypasswd')
34
+ # site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
35
+ #
36
+ class Resource
37
+ attr_reader :url, :options
38
38
 
39
- def initialize(url, options={}, backwards_compatibility=nil)
40
- @url = url
41
- if options.class == Hash
42
- @options = options
43
- else # compatibility with previous versions
44
- @options = { :user => options, :password => backwards_compatibility }
45
- end
46
- end
39
+ def initialize(url, options={}, backwards_compatibility=nil)
40
+ @url = url
41
+ if options.class == Hash
42
+ @options = options
43
+ else # compatibility with previous versions
44
+ @options = { :user => options, :password => backwards_compatibility }
45
+ end
46
+ end
47
47
 
48
- def get(additional_headers={}, &b)
49
- headers = (options[:headers] || {}).merge(additional_headers)
50
- Request.execute(options.merge(
51
- :method => :get,
52
- :url => url,
53
- :headers => headers), &b)
54
- end
48
+ def get(additional_headers={}, &b)
49
+ headers = (options[:headers] || {}).merge(additional_headers)
50
+ Request.execute(options.merge(
51
+ :method => :get,
52
+ :url => url,
53
+ :headers => headers), &b)
54
+ end
55
55
 
56
- def post(payload, additional_headers={}, &b)
57
- headers = (options[:headers] || {}).merge(additional_headers)
58
- Request.execute(options.merge(
59
- :method => :post,
60
- :url => url,
61
- :payload => payload,
62
- :headers => headers), &b)
63
- end
56
+ def post(payload, additional_headers={}, &b)
57
+ headers = (options[:headers] || {}).merge(additional_headers)
58
+ Request.execute(options.merge(
59
+ :method => :post,
60
+ :url => url,
61
+ :payload => payload,
62
+ :headers => headers), &b)
63
+ end
64
64
 
65
- def put(payload, additional_headers={}, &b)
66
- headers = (options[:headers] || {}).merge(additional_headers)
67
- Request.execute(options.merge(
68
- :method => :put,
69
- :url => url,
70
- :payload => payload,
71
- :headers => headers), &b)
72
- end
65
+ def put(payload, additional_headers={}, &b)
66
+ headers = (options[:headers] || {}).merge(additional_headers)
67
+ Request.execute(options.merge(
68
+ :method => :put,
69
+ :url => url,
70
+ :payload => payload,
71
+ :headers => headers), &b)
72
+ end
73
73
 
74
- def delete(additional_headers={}, &b)
75
- headers = (options[:headers] || {}).merge(additional_headers)
76
- Request.execute(options.merge(
77
- :method => :delete,
78
- :url => url,
79
- :headers => headers), &b)
80
- end
74
+ def delete(additional_headers={}, &b)
75
+ headers = (options[:headers] || {}).merge(additional_headers)
76
+ Request.execute(options.merge(
77
+ :method => :delete,
78
+ :url => url,
79
+ :headers => headers), &b)
80
+ end
81
81
 
82
- def to_s
83
- url
84
- end
82
+ def to_s
83
+ url
84
+ end
85
85
 
86
- def user
87
- options[:user]
88
- end
86
+ def user
87
+ options[:user]
88
+ end
89
89
 
90
- def password
91
- options[:password]
92
- end
90
+ def password
91
+ options[:password]
92
+ end
93
93
 
94
- def headers
95
- options[:headers] || {}
96
- end
94
+ def headers
95
+ options[:headers] || {}
96
+ end
97
97
 
98
- def timeout
99
- options[:timeout]
100
- end
101
-
102
- def open_timeout
103
- options[:open_timeout]
104
- end
98
+ def timeout
99
+ options[:timeout]
100
+ end
105
101
 
106
- # Construct a subresource, preserving authentication.
107
- #
108
- # Example:
109
- #
110
- # site = RestClient::Resource.new('http://example.com', 'adam', 'mypasswd')
111
- # site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
112
- #
113
- # This is especially useful if you wish to define your site in one place and
114
- # call it in multiple locations:
115
- #
116
- # def orders
117
- # RestClient::Resource.new('http://example.com/orders', 'admin', 'mypasswd')
118
- # end
119
- #
120
- # orders.get # GET http://example.com/orders
121
- # orders['1'].get # GET http://example.com/orders/1
122
- # orders['1/items'].delete # DELETE http://example.com/orders/1/items
123
- #
124
- # Nest resources as far as you want:
125
- #
126
- # site = RestClient::Resource.new('http://example.com')
127
- # posts = site['posts']
128
- # first_post = posts['1']
129
- # comments = first_post['comments']
130
- # comments.post 'Hello', :content_type => 'text/plain'
131
- #
132
- def [](suburl)
133
- self.class.new(concat_urls(url, suburl), options)
134
- end
102
+ def open_timeout
103
+ options[:open_timeout]
104
+ end
135
105
 
136
- def concat_urls(url, suburl) # :nodoc:
137
- url = url.to_s
138
- suburl = suburl.to_s
139
- if url.slice(-1, 1) == '/' or suburl.slice(0, 1) == '/'
140
- url + suburl
141
- else
142
- "#{url}/#{suburl}"
143
- end
144
- end
145
- end
106
+ # Construct a subresource, preserving authentication.
107
+ #
108
+ # Example:
109
+ #
110
+ # site = RestClient::Resource.new('http://example.com', 'adam', 'mypasswd')
111
+ # site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
112
+ #
113
+ # This is especially useful if you wish to define your site in one place and
114
+ # call it in multiple locations:
115
+ #
116
+ # def orders
117
+ # RestClient::Resource.new('http://example.com/orders', 'admin', 'mypasswd')
118
+ # end
119
+ #
120
+ # orders.get # GET http://example.com/orders
121
+ # orders['1'].get # GET http://example.com/orders/1
122
+ # orders['1/items'].delete # DELETE http://example.com/orders/1/items
123
+ #
124
+ # Nest resources as far as you want:
125
+ #
126
+ # site = RestClient::Resource.new('http://example.com')
127
+ # posts = site['posts']
128
+ # first_post = posts['1']
129
+ # comments = first_post['comments']
130
+ # comments.post 'Hello', :content_type => 'text/plain'
131
+ #
132
+ def [](suburl)
133
+ self.class.new(concat_urls(url, suburl), options)
134
+ end
135
+
136
+ def concat_urls(url, suburl) # :nodoc:
137
+ url = url.to_s
138
+ suburl = suburl.to_s
139
+ if url.slice(-1, 1) == '/' or suburl.slice(0, 1) == '/'
140
+ url + suburl
141
+ else
142
+ "#{url}/#{suburl}"
143
+ end
144
+ end
145
+ end
146
146
  end
@@ -1,20 +1,20 @@
1
1
  require File.dirname(__FILE__) + '/mixin/response'
2
2
 
3
3
  module RestClient
4
- # The response from RestClient looks like a string, but is actually one of
5
- # these. 99% of the time you're making a rest call all you care about is
6
- # the body, but on the occassion you want to fetch the headers you can:
7
- #
8
- # RestClient.get('http://example.com').headers[:content_type]
9
- #
10
- class Response < String
4
+ # The response from RestClient looks like a string, but is actually one of
5
+ # these. 99% of the time you're making a rest call all you care about is
6
+ # the body, but on the occassion you want to fetch the headers you can:
7
+ #
8
+ # RestClient.get('http://example.com').headers[:content_type]
9
+ #
10
+ class Response < String
11
11
 
12
- include RestClient::Mixin::Response
12
+ include RestClient::Mixin::Response
13
13
 
14
- def initialize(string, net_http_res)
15
- @net_http_res = net_http_res
16
- super(string || "")
17
- end
14
+ def initialize(string, net_http_res)
15
+ @net_http_res = net_http_res
16
+ super(string || "")
17
+ end
18
18
 
19
- end
19
+ end
20
20
  end
@@ -1,65 +1,65 @@
1
1
  require File.dirname(__FILE__) + '/base'
2
2
 
3
3
  describe RestClient::Exception do
4
- it "sets the exception message to ErrorMessage" do
5
- RestClient::ResourceNotFound.new.message.should == 'Resource not found'
6
- end
4
+ it "sets the exception message to ErrorMessage" do
5
+ RestClient::ResourceNotFound.new.message.should == 'Resource not found'
6
+ end
7
7
 
8
- it "contains exceptions in RestClient" do
9
- RestClient::Unauthorized.new.should be_a_kind_of(RestClient::Exception)
10
- RestClient::ServerBrokeConnection.new.should be_a_kind_of(RestClient::Exception)
11
- end
8
+ it "contains exceptions in RestClient" do
9
+ RestClient::Unauthorized.new.should be_a_kind_of(RestClient::Exception)
10
+ RestClient::ServerBrokeConnection.new.should be_a_kind_of(RestClient::Exception)
11
+ end
12
12
  end
13
13
 
14
14
  describe RestClient::RequestFailed do
15
- before do
16
- @response = mock('HTTP Response', :code => '502')
17
- end
15
+ before do
16
+ @response = mock('HTTP Response', :code => '502')
17
+ end
18
18
 
19
- it "stores the http response on the exception" do
20
- begin
21
- raise RestClient::RequestFailed, :response
22
- rescue RestClient::RequestFailed => e
23
- e.response.should == :response
24
- end
25
- end
19
+ it "stores the http response on the exception" do
20
+ begin
21
+ raise RestClient::RequestFailed, :response
22
+ rescue RestClient::RequestFailed => e
23
+ e.response.should == :response
24
+ end
25
+ end
26
26
 
27
- it "http_code convenience method for fetching the code as an integer" do
28
- RestClient::RequestFailed.new(@response).http_code.should == 502
29
- end
27
+ it "http_code convenience method for fetching the code as an integer" do
28
+ RestClient::RequestFailed.new(@response).http_code.should == 502
29
+ end
30
30
 
31
- it "http_body convenience method for fetching the body (decoding when necessary)" do
32
- @response.stub!(:[]).with('content-encoding').and_return('gzip')
33
- @response.stub!(:body).and_return('compressed body')
34
- RestClient::Request.should_receive(:decode).with('gzip', 'compressed body').and_return('plain body')
35
- RestClient::RequestFailed.new(@response).http_body.should == 'plain body'
36
- end
31
+ it "http_body convenience method for fetching the body (decoding when necessary)" do
32
+ @response.stub!(:[]).with('content-encoding').and_return('gzip')
33
+ @response.stub!(:body).and_return('compressed body')
34
+ RestClient::Request.should_receive(:decode).with('gzip', 'compressed body').and_return('plain body')
35
+ RestClient::RequestFailed.new(@response).http_body.should == 'plain body'
36
+ end
37
37
 
38
- it "shows the status code in the message" do
39
- RestClient::RequestFailed.new(@response).to_s.should match(/502/)
40
- end
38
+ it "shows the status code in the message" do
39
+ RestClient::RequestFailed.new(@response).to_s.should match(/502/)
40
+ end
41
41
  end
42
42
 
43
43
  describe RestClient::ResourceNotFound do
44
- it "also has the http response attached" do
45
- begin
46
- raise RestClient::ResourceNotFound, :response
47
- rescue RestClient::ResourceNotFound => e
48
- e.response.should == :response
49
- end
50
- end
44
+ it "also has the http response attached" do
45
+ begin
46
+ raise RestClient::ResourceNotFound, :response
47
+ rescue RestClient::ResourceNotFound => e
48
+ e.response.should == :response
49
+ end
50
+ end
51
51
  end
52
52
 
53
53
  describe "backwards compatibility" do
54
- it "alias RestClient::Request::Redirect to RestClient::Redirect" do
55
- RestClient::Request::Redirect.should == RestClient::Redirect
56
- end
54
+ it "alias RestClient::Request::Redirect to RestClient::Redirect" do
55
+ RestClient::Request::Redirect.should == RestClient::Redirect
56
+ end
57
57
 
58
- it "alias RestClient::Request::Unauthorized to RestClient::Unauthorized" do
59
- RestClient::Request::Unauthorized.should == RestClient::Unauthorized
60
- end
58
+ it "alias RestClient::Request::Unauthorized to RestClient::Unauthorized" do
59
+ RestClient::Request::Unauthorized.should == RestClient::Unauthorized
60
+ end
61
61
 
62
- it "alias RestClient::Request::RequestFailed to RestClient::RequestFailed" do
63
- RestClient::Request::RequestFailed.should == RestClient::RequestFailed
64
- end
62
+ it "alias RestClient::Request::RequestFailed to RestClient::RequestFailed" do
63
+ RestClient::Request::RequestFailed.should == RestClient::RequestFailed
64
+ end
65
65
  end
@@ -1,46 +1,46 @@
1
1
  require File.dirname(__FILE__) + '/../base'
2
2
 
3
3
  class MockResponse
4
- include RestClient::Mixin::Response
4
+ include RestClient::Mixin::Response
5
5
 
6
- def initialize(body, res)
7
- @net_http_res = res
8
- @body = @body
9
- end
6
+ def initialize(body, res)
7
+ @net_http_res = res
8
+ @body = @body
9
+ end
10
10
  end
11
11
 
12
12
  describe RestClient::Mixin::Response do
13
- before do
14
- @net_http_res = mock('net http response')
15
- @response = MockResponse.new('abc', @net_http_res)
16
- end
17
-
18
- it "fetches the numeric response code" do
19
- @net_http_res.should_receive(:code).and_return('200')
20
- @response.code.should == 200
21
- end
22
-
23
- it "beautifies the headers by turning the keys to symbols" do
24
- h = RestClient::Response.beautify_headers('content-type' => [ 'x' ])
25
- h.keys.first.should == :content_type
26
- end
27
-
28
- it "beautifies the headers by turning the values to strings instead of one-element arrays" do
29
- h = RestClient::Response.beautify_headers('x' => [ 'text/html' ] )
30
- h.values.first.should == 'text/html'
31
- end
32
-
33
- it "fetches the headers" do
34
- @net_http_res.should_receive(:to_hash).and_return('content-type' => [ 'text/html' ])
35
- @response.headers.should == { :content_type => 'text/html' }
36
- end
37
-
38
- it "extracts cookies from response headers" do
39
- @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
40
- @response.cookies.should == { 'session_id' => '1' }
41
- end
42
-
43
- it "can access the net http result directly" do
44
- @response.net_http_res.should == @net_http_res
45
- end
13
+ before do
14
+ @net_http_res = mock('net http response')
15
+ @response = MockResponse.new('abc', @net_http_res)
16
+ end
17
+
18
+ it "fetches the numeric response code" do
19
+ @net_http_res.should_receive(:code).and_return('200')
20
+ @response.code.should == 200
21
+ end
22
+
23
+ it "beautifies the headers by turning the keys to symbols" do
24
+ h = RestClient::Response.beautify_headers('content-type' => [ 'x' ])
25
+ h.keys.first.should == :content_type
26
+ end
27
+
28
+ it "beautifies the headers by turning the values to strings instead of one-element arrays" do
29
+ h = RestClient::Response.beautify_headers('x' => [ 'text/html' ] )
30
+ h.values.first.should == 'text/html'
31
+ end
32
+
33
+ it "fetches the headers" do
34
+ @net_http_res.should_receive(:to_hash).and_return('content-type' => [ 'text/html' ])
35
+ @response.headers.should == { :content_type => 'text/html' }
36
+ end
37
+
38
+ it "extracts cookies from response headers" do
39
+ @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
40
+ @response.cookies.should == { 'session_id' => '1' }
41
+ end
42
+
43
+ it "can access the net http result directly" do
44
+ @response.net_http_res.should == @net_http_res
45
+ end
46
46
  end