rest-client-next-dshelf 1.6.1

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,277 @@
1
+ = REST Client -- simple DSL for accessing HTTP and REST resources
2
+
3
+ A simple HTTP and REST client for Ruby, inspired by the Sinatra's microframework style
4
+ of specifying actions: get, put, post, delete.
5
+
6
+ * Main page: http://github.com/archiloque/rest-client
7
+ * Mailing list: rest.client@librelist.com (send a mail to subscribe).
8
+ * IRC: #rest-client at freenode
9
+
10
+ == Usage: Raw URL
11
+
12
+ require 'rest_client'
13
+
14
+ RestClient.get 'http://example.com/resource'
15
+
16
+ RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}
17
+
18
+ RestClient.get 'https://user:password@example.com/private/resource', {:accept => :json}
19
+
20
+ RestClient.post 'http://example.com/resource', :param1 => 'one', :nested => { :param2 => 'two' }
21
+
22
+ RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json
23
+
24
+ RestClient.delete 'http://example.com/resource'
25
+
26
+ response = RestClient.get 'http://example.com/resource'
27
+ response.code
28
+ ➔ 200
29
+ response.cookies
30
+ ➔ {"Foo"=>"BAR", "QUUX"=>"QUUUUX"}
31
+ response.headers
32
+ ➔ {:content_type=>"text/html; charset=utf-8", :cache_control=>"private" ...
33
+ response.to_str
34
+ ➔ \n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html ....
35
+
36
+ RestClient.post( url,
37
+ {
38
+ :transfer => {
39
+ :path => '/foo/bar',
40
+ :owner => 'that_guy',
41
+ :group => 'those_guys'
42
+ },
43
+ :upload => {
44
+ :file => File.new(path, 'rb')
45
+ }
46
+ })
47
+
48
+ == Multipart
49
+
50
+ Yeah, that's right! This does multipart sends for you!
51
+
52
+ RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')
53
+
54
+ This does two things for you:
55
+
56
+ * Auto-detects that you have a File value sends it as multipart
57
+ * Auto-detects the mime of the file and sets it in the HEAD of the payload for each entry
58
+
59
+ If you are sending params that do not contain a File object but the payload needs to be multipart then:
60
+
61
+ RestClient.post '/data', :foo => 'bar', :multipart => true
62
+
63
+ == Usage: ActiveResource-Style
64
+
65
+ resource = RestClient::Resource.new 'http://example.com/resource'
66
+ resource.get
67
+
68
+ private_resource = RestClient::Resource.new 'https://example.com/private/resource', 'user', 'pass'
69
+ private_resource.put File.read('pic.jpg'), :content_type => 'image/jpg'
70
+
71
+ See RestClient::Resource module docs for details.
72
+
73
+ == Usage: Resource Nesting
74
+
75
+ site = RestClient::Resource.new('http://example.com')
76
+ site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
77
+
78
+ See RestClient::Resource docs for details.
79
+
80
+ == Exceptions (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
81
+
82
+ * for results code between 200 and 207 a RestClient::Response will be returned
83
+ * for results code 301, 302 or 307 the redirection will be followed if the request is a get or a head
84
+ * for result code 303 the redirection will be followed and the request transformed into a get
85
+ * for other cases a RestClient::Exception holding the Response will be raised, a specific exception class will be thrown for know error codes
86
+
87
+ RestClient.get 'http://example.com/resource'
88
+ ➔ RestClient::ResourceNotFound: RestClient::ResourceNotFound
89
+
90
+ begin
91
+ RestClient.get 'http://example.com/resource'
92
+ rescue => e
93
+ e.response
94
+ end
95
+ ➔ 404 Resource Not Found | text/html 282 bytes
96
+
97
+ == Result handling
98
+
99
+ A block can be passed to the RestClient method, this block will then be called with the Response.
100
+ Response.return! can be called to invoke the default response's behavior.
101
+
102
+ # Don't raise exceptions but return the response
103
+ RestClient.get('http://example.com/resource'){|response, request, result| response }
104
+ ➔ 404 Resource Not Found | text/html 282 bytes
105
+
106
+ # Manage a specific error code
107
+ RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
108
+ case response.code
109
+ when 200
110
+ p "It worked !"
111
+ response
112
+ when 423
113
+ raise SomeCustomExceptionIfYouWant
114
+ else
115
+ response.return!(request, result, &block)
116
+ end
117
+ }
118
+
119
+ # Follow redirections for all request types and not only for get and head
120
+ # RFC : "If the 301, 302 or 307 status code is received in response to a request other than GET or HEAD,
121
+ # the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user,
122
+ # since this might change the conditions under which the request was issued."
123
+ RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
124
+ if [301, 302, 307].include? response.code
125
+ response.follow_redirection(request, result, &block)
126
+ else
127
+ response.return!(request, result, &block)
128
+ end
129
+ }
130
+
131
+ == Non-normalized URIs.
132
+
133
+ If you want to use non-normalized URIs, you can normalize them with the addressable gem (http://addressable.rubyforge.org/api/).
134
+
135
+ require 'addressable/uri'
136
+ RestClient.get(Addressable::URI.parse("http://www.詹姆斯.com/").normalize.to_str)
137
+
138
+ == Lower-level access
139
+
140
+ For cases not covered by the general API, you can use the RestClient::Request class which provide a lower-level API.
141
+
142
+ You can:
143
+
144
+ * specify ssl parameters
145
+ * override cookies
146
+ * manually handle the response (so you can operate on the response stream than reading it fully in memory)
147
+
148
+ see the class' rdoc for more information.
149
+
150
+ == Shell
151
+
152
+ The restclient shell command gives an IRB session with RestClient already loaded:
153
+
154
+ $ restclient
155
+ >> RestClient.get 'http://example.com'
156
+
157
+ Specify a URL argument for get/post/put/delete on that resource:
158
+
159
+ $ restclient http://example.com
160
+ >> put '/resource', 'data'
161
+
162
+ Add a user and password for authenticated resources:
163
+
164
+ $ restclient https://example.com user pass
165
+ >> delete '/private/resource'
166
+
167
+ Create ~/.restclient for named sessions:
168
+
169
+ sinatra:
170
+ url: http://localhost:4567
171
+ rack:
172
+ url: http://localhost:9292
173
+ private_site:
174
+ url: http://example.com
175
+ username: user
176
+ password: pass
177
+
178
+ Then invoke:
179
+
180
+ $ restclient private_site
181
+
182
+ Use as a one-off, curl-style:
183
+
184
+ $ restclient get http://example.com/resource > output_body
185
+
186
+ $ restclient put http://example.com/resource < input_body
187
+
188
+ == Logging
189
+
190
+ To enable logging you can
191
+
192
+ * set RestClient.log with a ruby Logger
193
+ * or set an environment variable to avoid modifying the code (in this case you can use a file name, "stdout" or "stderr"):
194
+
195
+ $ RESTCLIENT_LOG=stdout path/to/my/program
196
+
197
+ Either produces logs like this:
198
+
199
+ RestClient.get "http://some/resource"
200
+ # => 200 OK | text/html 250 bytes
201
+ RestClient.put "http://some/resource", "payload"
202
+ # => 401 Unauthorized | application/xml 340 bytes
203
+
204
+ Note that these logs are valid Ruby, so you can paste them into the restclient
205
+ shell or a script to replay your sequence of rest calls.
206
+
207
+ == Proxy
208
+
209
+ All calls to RestClient, including Resources, will use the proxy specified by
210
+ RestClient.proxy:
211
+
212
+ RestClient.proxy = "http://proxy.example.com/"
213
+ RestClient.get "http://some/resource"
214
+ # => response from some/resource as proxied through proxy.example.com
215
+
216
+ Often the proxy url is set in an environment variable, so you can do this to
217
+ use whatever proxy the system is configured to use:
218
+
219
+ RestClient.proxy = ENV['http_proxy']
220
+
221
+ == Cookies
222
+
223
+ Request and Response objects know about HTTP cookies, and will automatically
224
+ extract and set headers for them as needed:
225
+
226
+ response = RestClient.get 'http://example.com/action_which_sets_session_id'
227
+ response.cookies
228
+ # => {"_applicatioN_session_id" => "1234"}
229
+
230
+ response2 = RestClient.post(
231
+ 'http://localhost:3000/',
232
+ {:param1 => "foo"},
233
+ {:cookies => {:session_id => "1234"}}
234
+ )
235
+ # ...response body
236
+
237
+ == SSL Client Certificates
238
+
239
+ RestClient::Resource.new(
240
+ 'https://example.com',
241
+ :ssl_client_cert => OpenSSL::X509::Certificate.new(File.read("cert.pem")),
242
+ :ssl_client_key => OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
243
+ :ssl_ca_file => "ca_certificate.pem",
244
+ :verify_ssl => OpenSSL::SSL::VERIFY_PEER
245
+ ).get
246
+
247
+ Self-signed certificates can be generated with the openssl command-line tool.
248
+
249
+ == Hook
250
+
251
+ 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.
252
+
253
+ Example:
254
+
255
+ # Add oath support using the oauth gem
256
+ require 'oauth'
257
+ access_token = ...
258
+
259
+ RestClient.add_before_execution_proc do |req, params|
260
+ access_token.sign! req
261
+ end
262
+
263
+ RestClient.get 'http://example.com'
264
+
265
+ == More
266
+
267
+ Need caching, more advanced logging or any ability provided by a rack middleware ?
268
+
269
+ Have a look at rest-client-components http://github.com/crohr/rest-client-components
270
+
271
+ == Meta
272
+
273
+ Written by Adam Wiggins, major modifications by Blake Mizerany, maintained by Julien Kirch
274
+
275
+ Patches contributed by many, including Chris Anderson, Greg Borenstein, Ardekantur, Pedro Belo, Rafael Souza, Rick Olson, Aman Gupta, François Beausoleil and Nick Plante.
276
+
277
+ Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
data/Rakefile ADDED
@@ -0,0 +1,70 @@
1
+ require 'rake'
2
+
3
+ require 'jeweler'
4
+
5
+ Jeweler::Tasks.new do |s|
6
+ s.name = "rest-client-next-dshelf"
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.rubyforge_project = "rest-client"
13
+ s.has_rdoc = true
14
+ s.files = FileList["[A-Z]*", "{bin,lib,spec}/**/*"]
15
+ s.executables = %w(restclient)
16
+ s.add_runtime_dependency("mime-types", ">= 1.16")
17
+ s.add_development_dependency("webmock", ">= 0.9.1")
18
+ s.add_development_dependency("rspec")
19
+ s.extra_rdoc_files = [ 'README.rdoc', 'history.md']
20
+ end
21
+
22
+ Jeweler::RubyforgeTasks.new
23
+
24
+ ############################
25
+
26
+ require 'spec/rake/spectask'
27
+
28
+ desc "Run all specs"
29
+ task :spec => ["spec:unit", "spec:integration"]
30
+
31
+ desc "Run unit specs"
32
+ Spec::Rake::SpecTask.new('spec:unit') do |t|
33
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
34
+ t.spec_files = FileList['spec/*_spec.rb']
35
+ end
36
+
37
+ desc "Run integration specs"
38
+ Spec::Rake::SpecTask.new('spec:integration') do |t|
39
+ t.spec_opts = ['--colour --format progress --loadby mtime --reverse']
40
+ t.spec_files = FileList['spec/integration/*_spec.rb']
41
+ end
42
+
43
+ desc "Print specdocs"
44
+ Spec::Rake::SpecTask.new(:doc) do |t|
45
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
46
+ t.spec_files = FileList['spec/*_spec.rb']
47
+ end
48
+
49
+ desc "Run all examples with RCov"
50
+ Spec::Rake::SpecTask.new('rcov') do |t|
51
+ t.spec_files = FileList['spec/*_spec.rb']
52
+ t.rcov = true
53
+ t.rcov_opts = ['--exclude', 'examples']
54
+ end
55
+
56
+ task :default => :spec
57
+
58
+ ############################
59
+
60
+ require 'rake/rdoctask'
61
+
62
+ Rake::RDocTask.new do |t|
63
+ t.rdoc_dir = 'rdoc'
64
+ t.title = "rest-client, fetch RESTful resources effortlessly"
65
+ t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
66
+ t.options << '--charset' << 'utf-8'
67
+ t.rdoc_files.include('README.rdoc')
68
+ t.rdoc_files.include('lib/*.rb')
69
+ end
70
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.6.1
data/bin/restclient ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.dirname(__FILE__) + "/../lib"
4
+ require 'restclient'
5
+
6
+ require "yaml"
7
+
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)
14
+ end
15
+
16
+ POSSIBLE_VERBS = ['get', 'put', 'post', 'delete']
17
+
18
+ if POSSIBLE_VERBS.include? ARGV.first
19
+ @verb = ARGV.shift
20
+ else
21
+ @verb = nil
22
+ end
23
+
24
+ @url = ARGV.shift || 'http://localhost:4567'
25
+
26
+ config = YAML.load(File.read(ENV['HOME'] + "/.restclient")) rescue {}
27
+
28
+ @url, @username, @password = if c = config[@url]
29
+ [c['url'], c['username'], c['password']]
30
+ else
31
+ [@url, * ARGV]
32
+ end
33
+
34
+ usage("invalid url '#{@url}") unless @url =~ /^https?/
35
+ usage("too few args") unless ARGV.size < 3
36
+
37
+ def r
38
+ @r ||= RestClient::Resource.new(@url, @username, @password)
39
+ end
40
+
41
+ r # force rc to load
42
+
43
+ if @verb
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
55
+ end
56
+
57
+ POSSIBLE_VERBS.each do |m|
58
+ eval <<-end_eval
59
+ def #{m} (path, *args, &b)
60
+ r[path]. #{m} (*args, &b)
61
+ end
62
+ end_eval
63
+ end
64
+
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
76
+ end
77
+
78
+ require 'irb'
79
+ require 'irb/completion'
80
+
81
+ if File.exists? ".irbrc"
82
+ ENV['IRBRC'] = ".irbrc"
83
+ end
84
+
85
+ if File.exists?(File.expand_path(rcfile = "~/.restclientrc"))
86
+ load(rcfile)
87
+ end
88
+
89
+ ARGV.clear
90
+
91
+ IRB.start
92
+ exit!
data/history.md ADDED
@@ -0,0 +1,104 @@
1
+ # 1.6.2
2
+
3
+ - add support for HEAD in resources (patch provided by tpresa)
4
+ - fix shell for 1.9.2
5
+ - workaround when some gem monkeypatch net/http (patch provided by Ian Warshak)
6
+ - DELETE requests should process parameters just like GET and HEAD
7
+ - adding :block_response parameter for manual processing
8
+ - Limit number of redirections (patch provided by Chris Dinn)
9
+
10
+ # 1.6.1
11
+
12
+ - add response body in Exception#inspect
13
+ - add support for RestClient.options
14
+ - fix tests for 1.9.2 (patch provided by Niko Dittmann)
15
+ - block passing in Resource#[] (patch provided by Niko Dittmann)
16
+ - cookies set in a response should be kept in a redirect
17
+ - HEAD requests should process parameters just like GET (patch provided by Rob Eanes)
18
+ - Exception message should never be nil (patch provided by Michael Klett)
19
+
20
+ # 1.6.0
21
+
22
+ - forgot to include rest-client.rb in the gem
23
+ - user, password and user-defined headers should survive a redirect
24
+ - added all missing status codes
25
+ - added parameter passing for get request using the :param key in header
26
+ - the warning about the logger when using a string was a bad idea
27
+ - multipart parameters names should not be escaped
28
+ - remove the cookie escaping introduced by migrating to CGI cookie parsing in 1.5.1
29
+ - add a streamed payload type (patch provided by Caleb Land)
30
+ - Exception#http_body works even when no response
31
+
32
+ # 1.5.1
33
+
34
+ - only converts headers keys which are Symbols
35
+ - use CGI for cookie parsing instead of custom code
36
+ - unescape user and password before using them (patch provided by Lars Gierth)
37
+ - expand ~ in ~/.restclientrc (patch provided by Mike Fletcher)
38
+ - ssl verification raise an exception when the ca certificate is incorrect (patch provided by Braintree)
39
+
40
+ # 1.5.0
41
+
42
+ - the response is now a String with the Response module a.k.a. the change in 1.4.0 was a mistake (Response.body is returning self for compatability)
43
+ - added AbstractResponse.to_i to improve semantic
44
+ - multipart Payloads ignores the name attribute if it's not set (patch provided by Tekin Suleyman)
45
+ - correctly takes into account user headers whose keys are strings (path provided by Cyril Rohr)
46
+ - use binary mode for payload temp file
47
+ - concatenate cookies with ';'
48
+ - fixed deeper parameter handling
49
+ - do not quote the boundary in the Content-Type header (patch provided by W. Andrew Loe III)
50
+
51
+ # 1.4.2
52
+
53
+ - fixed RestClient.add_before_execution_proc (patch provided by Nicholas Wieland)
54
+ - fixed error when an exception is raised without a response (patch provided by Caleb Land)
55
+
56
+ # 1.4.1
57
+
58
+ - fixed parameters managment when using hash
59
+
60
+ # 1.4.0
61
+
62
+ - Response is no more a String, and the mixin is replaced by an abstract_response, existing calls are redirected to response body with a warning.
63
+ - enable repeated parameters RestClient.post 'http://example.com/resource', :param1 => ['one', 'two', 'three'], => :param2 => 'foo' (patch provided by Rodrigo Panachi)
64
+ - fixed the redirect code concerning relative path and query string combination (patch provided by Kevin Read)
65
+ - redirection code moved to Response so redirection can be customized using the block syntax
66
+ - only get and head redirections are now followed by default, as stated in the specification
67
+ - added RestClient.add_before_execution_proc to hack the http request, like for oauth
68
+
69
+ The response change may be breaking in rare cases.
70
+
71
+ # 1.3.1
72
+
73
+ - added compatibility to enable responses in exception to act like Net::HTTPResponse
74
+
75
+ # 1.3.0
76
+
77
+ - a block can be used to process a request's result, this enable to handle custom error codes or paththrought (design by Cyril Rohr)
78
+ - cleaner log API, add a warning for some cases but should be compatible
79
+ - accept multiple "Set-Cookie" headers, see http://www.ietf.org/rfc/rfc2109.txt (patch provided by Cyril Rohr)
80
+ - remove "Content-Length" and "Content-Type" headers when following a redirection (patch provided by haarts)
81
+ - all http error codes have now a corresponding exception class and all of them contain the Reponse -> this means that the raised exception can be different
82
+ - changed "Content-Disposition: multipart/form-data" to "Content-Disposition: form-data" per RFC 2388 (patch provided by Kyle Crawford)
83
+
84
+ The only breaking change should be the exception classes, but as the new classes inherits from the existing ones, the breaking cases should be rare.
85
+
86
+ # 1.2.0
87
+
88
+ - formatting changed from tabs to spaces
89
+ - logged requests now include generated headers
90
+ - accept and content-type headers can now be specified using extentions: RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json
91
+ - should be 1.1.1 but renamed to 1.2.0 because 1.1.X versions has already been packaged on Debian
92
+
93
+ # 1.1.0
94
+
95
+ - new maintainer: Archiloque, the working repo is now at http://github.com/archiloque/rest-client
96
+ - a mailing list has been created at rest.client@librelist.com and an freenode irc channel #rest-client
97
+ - François Beausoleil' multipart code from http://github.com/francois/rest-client has been merged
98
+ - ability to use hash in hash as payload
99
+ - the mime-type code now rely on the mime-types gem http://mime-types.rubyforge.org/ instead of an internal partial list
100
+ - 204 response returns a Response instead of nil (patch provided by Elliott Draper)
101
+
102
+ All changes exept the last one should be fully compatible with the previous version.
103
+
104
+ NOTE: due to a dependency problem and to the last change, heroku users should update their heroku gem to >= 1.5.3 to be able to use this version.