rest-client 1.1.0 → 1.6.3

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,24 +1,54 @@
1
- = REST Client -- simple DSL for accessing REST resources
1
+ = REST Client -- simple DSL for accessing HTTP and REST resources
2
2
 
3
- A simple REST client for Ruby, inspired by the Sinatra's microframework style
3
+ A simple HTTP and REST client for Ruby, inspired by the Sinatra's microframework style
4
4
  of specifying actions: get, put, post, delete.
5
5
 
6
+ * Main page: http://github.com/archiloque/rest-client
7
+ * Mailing list: rest.client@librelist.com (send a mail to subscribe).
8
+
6
9
  == Usage: Raw URL
7
10
 
8
11
  require 'rest_client'
9
12
 
10
13
  RestClient.get 'http://example.com/resource'
11
- RestClient.get 'https://user:password@example.com/private/resource'
14
+
15
+ RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}
16
+
17
+ RestClient.get 'https://user:password@example.com/private/resource', {:accept => :json}
12
18
 
13
19
  RestClient.post 'http://example.com/resource', :param1 => 'one', :nested => { :param2 => 'two' }
14
20
 
21
+ RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json
22
+
15
23
  RestClient.delete 'http://example.com/resource'
16
24
 
25
+ response = RestClient.get 'http://example.com/resource'
26
+ response.code
27
+ ➔ 200
28
+ response.cookies
29
+ ➔ {"Foo"=>"BAR", "QUUX"=>"QUUUUX"}
30
+ response.headers
31
+ ➔ {:content_type=>"text/html; charset=utf-8", :cache_control=>"private" ...
32
+ response.to_str
33
+ ➔ \n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html ....
34
+
35
+ RestClient.post( url,
36
+ {
37
+ :transfer => {
38
+ :path => '/foo/bar',
39
+ :owner => 'that_guy',
40
+ :group => 'those_guys'
41
+ },
42
+ :upload => {
43
+ :file => File.new(path, 'rb')
44
+ }
45
+ })
46
+
17
47
  == Multipart
18
48
 
19
49
  Yeah, that's right! This does multipart sends for you!
20
50
 
21
- RestClient.post '/data', :myfile => File.new("/path/to/image.jpg")
51
+ RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')
22
52
 
23
53
  This does two things for you:
24
54
 
@@ -46,9 +76,75 @@ See RestClient::Resource module docs for details.
46
76
 
47
77
  See RestClient::Resource docs for details.
48
78
 
79
+ == Exceptions (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
80
+
81
+ * for results code between 200 and 207 a RestClient::Response will be returned
82
+ * for results code 301, 302 or 307 the redirection will be followed if the request is a get or a head
83
+ * for result code 303 the redirection will be followed and the request transformed into a get
84
+ * for other cases a RestClient::Exception holding the Response will be raised, a specific exception class will be thrown for know error codes
85
+
86
+ RestClient.get 'http://example.com/resource'
87
+ ➔ RestClient::ResourceNotFound: RestClient::ResourceNotFound
88
+
89
+ begin
90
+ RestClient.get 'http://example.com/resource'
91
+ rescue => e
92
+ e.response
93
+ end
94
+ ➔ 404 Resource Not Found | text/html 282 bytes
95
+
96
+ == Result handling
97
+
98
+ A block can be passed to the RestClient method, this block will then be called with the Response.
99
+ Response.return! can be called to invoke the default response's behavior.
100
+
101
+ # Don't raise exceptions but return the response
102
+ RestClient.get('http://example.com/resource'){|response, request, result| response }
103
+ ➔ 404 Resource Not Found | text/html 282 bytes
104
+
105
+ # Manage a specific error code
106
+ RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
107
+ case response.code
108
+ when 200
109
+ p "It worked !"
110
+ response
111
+ when 423
112
+ raise SomeCustomExceptionIfYouWant
113
+ else
114
+ response.return!(request, result, &block)
115
+ end
116
+ }
117
+
118
+ # Follow redirections for all request types and not only for get and head
119
+ # RFC : "If the 301, 302 or 307 status code is received in response to a request other than GET or HEAD,
120
+ # the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user,
121
+ # since this might change the conditions under which the request was issued."
122
+ RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
123
+ if [301, 302, 307].include? response.code
124
+ response.follow_redirection(request, result, &block)
125
+ else
126
+ response.return!(request, result, &block)
127
+ end
128
+ }
129
+
130
+ == Non-normalized URIs.
131
+
132
+ If you want to use non-normalized URIs, you can normalize them with the addressable gem (http://addressable.rubyforge.org/api/).
133
+
134
+ require 'addressable/uri'
135
+ RestClient.get(Addressable::URI.parse("http://www.詹姆斯.com/").normalize.to_str)
136
+
49
137
  == Lower-level access
50
138
 
51
- For cases not covered by the general API, you can use the RestClient::Resource class which provide a lower-level API, see the class' rdoc for more information.
139
+ For cases not covered by the general API, you can use the RestClient::Request class which provide a lower-level API.
140
+
141
+ You can:
142
+
143
+ * specify ssl parameters
144
+ * override cookies
145
+ * manually handle the response (so you can operate on the response stream than reading it fully in memory)
146
+
147
+ see the class' rdoc for more information.
52
148
 
53
149
  == Shell
54
150
 
@@ -82,18 +178,99 @@ Then invoke:
82
178
 
83
179
  $ restclient private_site
84
180
 
85
- == Meta
181
+ Use as a one-off, curl-style:
86
182
 
87
- Written by Adam Wiggins, major modifications by Blake Mizerany, maintained by Archiloque
183
+ $ restclient get http://example.com/resource > output_body
88
184
 
89
- Patches contributed by: Chris Anderson, Greg Borenstein, Ardekantur, Pedro Belo, Rafael Souza, Rick Olson, Aman Gupta, François Beausoleil and Nick Plante.
185
+ $ restclient put http://example.com/resource < input_body
90
186
 
91
- Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
187
+ == Logging
188
+
189
+ To enable logging you can
190
+
191
+ * set RestClient.log with a ruby Logger
192
+ * or set an environment variable to avoid modifying the code (in this case you can use a file name, "stdout" or "stderr"):
193
+
194
+ $ RESTCLIENT_LOG=stdout path/to/my/program
195
+
196
+ Either produces logs like this:
197
+
198
+ RestClient.get "http://some/resource"
199
+ # => 200 OK | text/html 250 bytes
200
+ RestClient.put "http://some/resource", "payload"
201
+ # => 401 Unauthorized | application/xml 340 bytes
202
+
203
+ Note that these logs are valid Ruby, so you can paste them into the restclient
204
+ shell or a script to replay your sequence of rest calls.
205
+
206
+ == Proxy
207
+
208
+ All calls to RestClient, including Resources, will use the proxy specified by
209
+ RestClient.proxy:
210
+
211
+ RestClient.proxy = "http://proxy.example.com/"
212
+ RestClient.get "http://some/resource"
213
+ # => response from some/resource as proxied through proxy.example.com
92
214
 
93
- Main page: http://github.com/archiloque/rest-client
215
+ Often the proxy url is set in an environment variable, so you can do this to
216
+ use whatever proxy the system is configured to use:
94
217
 
95
- Rdoc: http://rdoc.info/projects/archiloque/rest-client
218
+ RestClient.proxy = ENV['http_proxy']
96
219
 
97
- Mailing list: rest.client@librelist.com (send a mail to subscribe).
220
+ == Cookies
98
221
 
99
- IRC: #rest-client at freenode
222
+ Request and Response objects know about HTTP cookies, and will automatically
223
+ extract and set headers for them as needed:
224
+
225
+ response = RestClient.get 'http://example.com/action_which_sets_session_id'
226
+ response.cookies
227
+ # => {"_applicatioN_session_id" => "1234"}
228
+
229
+ response2 = RestClient.post(
230
+ 'http://localhost:3000/',
231
+ {:param1 => "foo"},
232
+ {:cookies => {:session_id => "1234"}}
233
+ )
234
+ # ...response body
235
+
236
+ == SSL Client Certificates
237
+
238
+ RestClient::Resource.new(
239
+ 'https://example.com',
240
+ :ssl_client_cert => OpenSSL::X509::Certificate.new(File.read("cert.pem")),
241
+ :ssl_client_key => OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
242
+ :ssl_ca_file => "ca_certificate.pem",
243
+ :verify_ssl => OpenSSL::SSL::VERIFY_PEER
244
+ ).get
245
+
246
+ Self-signed certificates can be generated with the openssl command-line tool.
247
+
248
+ == Hook
249
+
250
+ RestClient.add_before_execution_proc add a Proc to be called before each execution, it's handy if you need a direct access to the http request.
251
+
252
+ Example:
253
+
254
+ # Add oath support using the oauth gem
255
+ require 'oauth'
256
+ access_token = ...
257
+
258
+ RestClient.add_before_execution_proc do |req, params|
259
+ access_token.sign! req
260
+ end
261
+
262
+ RestClient.get 'http://example.com'
263
+
264
+ == More
265
+
266
+ Need caching, more advanced logging or any ability provided by a rack middleware ?
267
+
268
+ Have a look at rest-client-components http://github.com/crohr/rest-client-components
269
+
270
+ == Meta
271
+
272
+ Written by Adam Wiggins, major modifications by Blake Mizerany, maintained by Julien Kirch
273
+
274
+ Patches contributed by many, including Chris Anderson, Greg Borenstein, Ardekantur, Pedro Belo, Rafael Souza, Rick Olson, Aman Gupta, François Beausoleil and Nick Plante.
275
+
276
+ Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
data/Rakefile CHANGED
@@ -3,41 +3,50 @@ require 'rake'
3
3
  require 'jeweler'
4
4
 
5
5
  Jeweler::Tasks.new do |s|
6
- s.name = "rest-client"
7
- s.description = "A simple REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
8
- s.summary = "Simple REST client for Ruby, inspired by microframework syntax for specifying actions."
9
- s.author = "Adam Wiggins"
10
- s.email = "adam@heroku.com"
11
- s.homepage = "http://rest-client.heroku.com/"
12
- s.rubyforge_project = "rest-client"
13
- s.has_rdoc = true
14
- s.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
15
- s.executables = %w(restclient)
6
+ s.name = "rest-client"
7
+ s.description = "A simple HTTP and REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete."
8
+ s.summary = "Simple HTTP and REST client for Ruby, inspired by microframework syntax for specifying actions."
9
+ s.authors = ["Adam Wiggins", "Julien Kirch"]
10
+ s.email = "rest.client@librelist.com"
11
+ s.homepage = "http://github.com/archiloque/rest-client"
12
+ s.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
13
+ s.test_files = FileList["{spec}/**/*"]
14
+ s.add_runtime_dependency("mime-types", ">= 1.16")
15
+ s.add_development_dependency("webmock", ">= 0.9.1")
16
+ s.add_development_dependency("rspec")
17
+ s.extra_rdoc_files = [ 'README.rdoc', 'history.md']
16
18
  end
17
19
 
18
- Jeweler::RubyforgeTasks.new
19
-
20
20
  ############################
21
21
 
22
22
  require 'spec/rake/spectask'
23
23
 
24
24
  desc "Run all specs"
25
- Spec::Rake::SpecTask.new('spec') do |t|
26
- t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
27
- t.spec_files = FileList['spec/*_spec.rb']
25
+ task :spec => ["spec:unit", "spec:integration"]
26
+
27
+ desc "Run unit specs"
28
+ Spec::Rake::SpecTask.new('spec:unit') do |t|
29
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
30
+ t.spec_files = FileList['spec/*_spec.rb']
31
+ end
32
+
33
+ desc "Run integration specs"
34
+ Spec::Rake::SpecTask.new('spec:integration') do |t|
35
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
36
+ t.spec_files = FileList['spec/integration/*_spec.rb']
28
37
  end
29
38
 
30
39
  desc "Print specdocs"
31
40
  Spec::Rake::SpecTask.new(:doc) do |t|
32
- t.spec_opts = ["--format", "specdoc", "--dry-run"]
33
- t.spec_files = FileList['spec/*_spec.rb']
41
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
42
+ t.spec_files = FileList['spec/*_spec.rb']
34
43
  end
35
44
 
36
45
  desc "Run all examples with RCov"
37
46
  Spec::Rake::SpecTask.new('rcov') do |t|
38
- t.spec_files = FileList['spec/*_spec.rb']
39
- t.rcov = true
40
- t.rcov_opts = ['--exclude', 'examples']
47
+ t.spec_files = FileList['spec/*_spec.rb']
48
+ t.rcov = true
49
+ t.rcov_opts = ['--exclude', 'examples']
41
50
  end
42
51
 
43
52
  task :default => :spec
@@ -47,11 +56,11 @@ task :default => :spec
47
56
  require 'rake/rdoctask'
48
57
 
49
58
  Rake::RDocTask.new do |t|
50
- t.rdoc_dir = 'rdoc'
51
- t.title = "rest-client, fetch RESTful resources effortlessly"
52
- t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
53
- t.options << '--charset' << 'utf-8'
54
- t.rdoc_files.include('README.rdoc')
55
- t.rdoc_files.include('lib/*.rb')
59
+ t.rdoc_dir = 'rdoc'
60
+ t.title = "rest-client, fetch RESTful resources effortlessly"
61
+ t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
62
+ t.options << '--charset' << 'utf-8'
63
+ t.rdoc_files.include('README.rdoc')
64
+ t.rdoc_files.include('lib/*.rb')
56
65
  end
57
66
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.1.0
1
+ 1.6.3
@@ -6,17 +6,19 @@ require 'restclient'
6
6
  require "yaml"
7
7
 
8
8
  def usage(why = nil)
9
- puts "failed for reason: #{why}" if why
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."
13
- exit(1)
9
+ puts "failed for reason: #{why}" if why
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."
13
+ exit(1)
14
14
  end
15
15
 
16
- if %w(get put post delete).include? ARGV.first
17
- @verb = ARGV.shift
16
+ POSSIBLE_VERBS = ['get', 'put', 'post', 'delete']
17
+
18
+ if POSSIBLE_VERBS.include? ARGV.first
19
+ @verb = ARGV.shift
18
20
  else
19
- @verb = nil
21
+ @verb = nil
20
22
  end
21
23
 
22
24
  @url = ARGV.shift || 'http://localhost:4567'
@@ -24,61 +26,64 @@ end
24
26
  config = YAML.load(File.read(ENV['HOME'] + "/.restclient")) rescue {}
25
27
 
26
28
  @url, @username, @password = if c = config[@url]
27
- [c['url'], c['username'], c['password']]
29
+ [c['url'], c['username'], c['password']]
28
30
  else
29
- [@url, *ARGV]
31
+ [@url, * ARGV]
30
32
  end
31
33
 
32
34
  usage("invalid url '#{@url}") unless @url =~ /^https?/
33
35
  usage("too few args") unless ARGV.size < 3
34
36
 
35
37
  def r
36
- @r ||= RestClient::Resource.new(@url, @username, @password)
38
+ @r ||= RestClient::Resource.new(@url, @username, @password)
37
39
  end
38
40
 
39
41
  r # force rc to load
40
42
 
41
43
  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
44
+ begin
45
+ if %w( put post ).include? @verb
46
+ puts r.send(@verb, STDIN.read)
47
+ else
48
+ puts r.send(@verb)
49
+ end
50
+ exit 0
51
+ rescue RestClient::Exception => e
52
+ puts e.response.body if e.respond_to? :response
53
+ raise
54
+ end
53
55
  end
54
56
 
55
- %w(get post put delete).each do |m|
56
- eval <<-end_eval
57
- def #{m}(path, *args, &b)
58
- r[path].#{m}(*args, &b)
57
+ POSSIBLE_VERBS.each do |m|
58
+ eval <<-end_eval
59
+ def #{m} (path, *args, &b)
60
+ r[path]. #{m} (*args, &b)
59
61
  end
60
- end_eval
62
+ end_eval
61
63
  end
62
64
 
63
- def method_missing(s, *args, &b)
64
- super unless r.respond_to?(s)
65
- begin
66
- r.send(s, *args, &b)
67
- rescue RestClient::RequestFailed => e
68
- print STDERR, e.response.body
69
- raise e
70
- end
65
+ def method_missing(s, * args, & b)
66
+ if POSSIBLE_VERBS.include? s
67
+ begin
68
+ r.send(s, *args, & b)
69
+ rescue RestClient::RequestFailed => e
70
+ print STDERR, e.response.body
71
+ raise e
72
+ end
73
+ else
74
+ super
75
+ end
71
76
  end
72
77
 
73
78
  require 'irb'
74
79
  require 'irb/completion'
75
80
 
76
81
  if File.exists? ".irbrc"
77
- ENV['IRBRC'] = ".irbrc"
82
+ ENV['IRBRC'] = ".irbrc"
78
83
  end
79
84
 
80
- if File.exists?(rcfile = "~/.restclientrc")
81
- load(rcfile)
85
+ if File.exists?(File.expand_path(rcfile = "~/.restclientrc"))
86
+ load(rcfile)
82
87
  end
83
88
 
84
89
  ARGV.clear