rest-client 1.6.14 → 2.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +6 -6
  3. data/.rspec +2 -1
  4. data/.rubocop-disables.yml +384 -0
  5. data/.rubocop.yml +3 -0
  6. data/.travis.yml +46 -1
  7. data/AUTHORS +28 -5
  8. data/Gemfile +5 -1
  9. data/LICENSE +21 -0
  10. data/README.md +784 -0
  11. data/Rakefile +95 -12
  12. data/bin/restclient +11 -12
  13. data/history.md +180 -16
  14. data/lib/restclient.rb +25 -11
  15. data/lib/restclient/abstract_response.rb +171 -51
  16. data/lib/restclient/exceptions.rb +102 -56
  17. data/lib/restclient/params_array.rb +72 -0
  18. data/lib/restclient/payload.rb +43 -74
  19. data/lib/restclient/platform.rb +22 -2
  20. data/lib/restclient/raw_response.rb +7 -3
  21. data/lib/restclient/request.rb +672 -179
  22. data/lib/restclient/resource.rb +6 -7
  23. data/lib/restclient/response.rb +64 -10
  24. data/lib/restclient/utils.rb +235 -0
  25. data/lib/restclient/version.rb +2 -1
  26. data/lib/restclient/windows.rb +8 -0
  27. data/lib/restclient/windows/root_certs.rb +105 -0
  28. data/rest-client.gemspec +16 -11
  29. data/rest-client.windows.gemspec +19 -0
  30. data/spec/helpers.rb +22 -0
  31. data/spec/integration/_lib.rb +1 -0
  32. data/spec/integration/capath_verisign/415660c1.0 +14 -0
  33. data/spec/integration/capath_verisign/7651b327.0 +14 -0
  34. data/spec/integration/capath_verisign/README +8 -0
  35. data/spec/integration/capath_verisign/verisign.crt +14 -0
  36. data/spec/integration/httpbin_spec.rb +87 -0
  37. data/spec/integration/integration_spec.rb +125 -0
  38. data/spec/integration/request_spec.rb +72 -20
  39. data/spec/spec_helper.rb +29 -0
  40. data/spec/unit/_lib.rb +1 -0
  41. data/spec/unit/abstract_response_spec.rb +145 -0
  42. data/spec/unit/exceptions_spec.rb +108 -0
  43. data/spec/{master_shake.jpg → unit/master_shake.jpg} +0 -0
  44. data/spec/unit/params_array_spec.rb +36 -0
  45. data/spec/{payload_spec.rb → unit/payload_spec.rb} +73 -54
  46. data/spec/{raw_response_spec.rb → unit/raw_response_spec.rb} +5 -4
  47. data/spec/unit/request2_spec.rb +54 -0
  48. data/spec/unit/request_spec.rb +1250 -0
  49. data/spec/unit/resource_spec.rb +134 -0
  50. data/spec/unit/response_spec.rb +241 -0
  51. data/spec/unit/restclient_spec.rb +79 -0
  52. data/spec/unit/utils_spec.rb +147 -0
  53. data/spec/unit/windows/root_certs_spec.rb +22 -0
  54. metadata +143 -53
  55. data/README.rdoc +0 -300
  56. data/lib/restclient/net_http_ext.rb +0 -55
  57. data/spec/abstract_response_spec.rb +0 -85
  58. data/spec/base.rb +0 -13
  59. data/spec/exceptions_spec.rb +0 -98
  60. data/spec/integration_spec.rb +0 -38
  61. data/spec/request2_spec.rb +0 -35
  62. data/spec/request_spec.rb +0 -528
  63. data/spec/resource_spec.rb +0 -136
  64. data/spec/response_spec.rb +0 -169
  65. data/spec/restclient_spec.rb +0 -73
@@ -1,300 +0,0 @@
1
- = REST Client -- simple DSL for accessing HTTP and REST resources
2
-
3
- Build status: {<img src="https://travis-ci.org/rest-client/rest-client.svg?branch=1.6-legacy" alt="Build Status" />}[https://travis-ci.org/rest-client/rest-client]
4
-
5
- A simple HTTP and REST client for Ruby, inspired by the Sinatra's microframework style
6
- of specifying actions: get, put, post, delete.
7
-
8
- * Main page: https://github.com/rest-client/rest-client
9
- * Mailing list: rest.client@librelist.com (send a mail to subscribe).
10
-
11
- == Usage: Raw URL
12
-
13
- require 'rest_client'
14
-
15
- RestClient.get 'http://example.com/resource'
16
-
17
- RestClient.get 'http://example.com/resource', {:params => {:id => 50, 'foo' => 'bar'}}
18
-
19
- RestClient.get 'https://user:password@example.com/private/resource', {:accept => :json}
20
-
21
- RestClient.post 'http://example.com/resource', :param1 => 'one', :nested => { :param2 => 'two' }
22
-
23
- RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json
24
-
25
- RestClient.delete 'http://example.com/resource'
26
-
27
- response = RestClient.get 'http://example.com/resource'
28
- response.code
29
- ➔ 200
30
- response.cookies
31
- ➔ {"Foo"=>"BAR", "QUUX"=>"QUUUUX"}
32
- response.headers
33
- ➔ {:content_type=>"text/html; charset=utf-8", :cache_control=>"private" ...
34
- response.to_str
35
- ➔ \n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html ....
36
-
37
- RestClient.post( url,
38
- {
39
- :transfer => {
40
- :path => '/foo/bar',
41
- :owner => 'that_guy',
42
- :group => 'those_guys'
43
- },
44
- :upload => {
45
- :file => File.new(path, 'rb')
46
- }
47
- })
48
-
49
- == Multipart
50
-
51
- Yeah, that's right! This does multipart sends for you!
52
-
53
- RestClient.post '/data', :myfile => File.new("/path/to/image.jpg", 'rb')
54
-
55
- This does two things for you:
56
-
57
- * Auto-detects that you have a File value sends it as multipart
58
- * Auto-detects the mime of the file and sets it in the HEAD of the payload for each entry
59
-
60
- If you are sending params that do not contain a File object but the payload needs to be multipart then:
61
-
62
- RestClient.post '/data', :foo => 'bar', :multipart => true
63
-
64
- == Usage: ActiveResource-Style
65
-
66
- resource = RestClient::Resource.new 'http://example.com/resource'
67
- resource.get
68
-
69
- private_resource = RestClient::Resource.new 'https://example.com/private/resource', 'user', 'pass'
70
- private_resource.put File.read('pic.jpg'), :content_type => 'image/jpg'
71
-
72
- See RestClient::Resource module docs for details.
73
-
74
- == Usage: Resource Nesting
75
-
76
- site = RestClient::Resource.new('http://example.com')
77
- site['posts/1/comments'].post 'Good article.', :content_type => 'text/plain'
78
-
79
- See RestClient::Resource docs for details.
80
-
81
- == Exceptions (see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html)
82
-
83
- * for result codes between 200 and 207, a RestClient::Response will be returned
84
- * for result codes 301, 302 or 307, the redirection will be followed if the request is a GET or a HEAD
85
- * for result code 303, the redirection will be followed and the request transformed into a GET
86
- * for other cases, a RestClient::Exception holding the Response will be raised; a specific exception class will be thrown for known error codes
87
-
88
- RestClient.get 'http://example.com/resource'
89
- ➔ RestClient::ResourceNotFound: RestClient::ResourceNotFound
90
-
91
- begin
92
- RestClient.get 'http://example.com/resource'
93
- rescue => e
94
- e.response
95
- end
96
- ➔ 404 Resource Not Found | text/html 282 bytes
97
-
98
- == Result handling
99
-
100
- A block can be passed to the RestClient method. This block will then be called with the Response.
101
- Response.return! can be called to invoke the default response's behavior.
102
-
103
- # Don't raise exceptions but return the response
104
- RestClient.get('http://example.com/resource'){|response, request, result| response }
105
- ➔ 404 Resource Not Found | text/html 282 bytes
106
-
107
- # Manage a specific error code
108
- RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
109
- case response.code
110
- when 200
111
- p "It worked !"
112
- response
113
- when 423
114
- raise SomeCustomExceptionIfYouWant
115
- else
116
- response.return!(request, result, &block)
117
- end
118
- }
119
-
120
- # Follow redirections for all request types and not only for get and head
121
- # RFC : "If the 301, 302 or 307 status code is received in response to a request other than GET or HEAD,
122
- # the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user,
123
- # since this might change the conditions under which the request was issued."
124
- RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
125
- if [301, 302, 307].include? response.code
126
- response.follow_redirection(request, result, &block)
127
- else
128
- response.return!(request, result, &block)
129
- end
130
- }
131
-
132
- == Non-normalized URIs
133
-
134
- If you need to normalize URIs, e.g. to work with International Resource Identifiers (IRIs),
135
- use the addressable gem (http://addressable.rubyforge.org/api/) in your code:
136
-
137
- require 'addressable/uri'
138
- RestClient.get(Addressable::URI.parse("http://www.詹姆斯.com/").normalize.to_str)
139
-
140
- == Lower-level access
141
-
142
- For cases not covered by the general API, you can use the RestClient::Request class, which provides a lower-level API.
143
-
144
- You can:
145
-
146
- * specify ssl parameters
147
- * override cookies
148
- * manually handle the response (e.g. to operate on it as a stream rather than reading it all into memory)
149
-
150
- See RestClient::Request's documentation for more information.
151
-
152
- == Shell
153
-
154
- The restclient shell command gives an IRB session with RestClient already loaded:
155
-
156
- $ restclient
157
- >> RestClient.get 'http://example.com'
158
-
159
- Specify a URL argument for get/post/put/delete on that resource:
160
-
161
- $ restclient http://example.com
162
- >> put '/resource', 'data'
163
-
164
- Add a user and password for authenticated resources:
165
-
166
- $ restclient https://example.com user pass
167
- >> delete '/private/resource'
168
-
169
- Create ~/.restclient for named sessions:
170
-
171
- sinatra:
172
- url: http://localhost:4567
173
- rack:
174
- url: http://localhost:9292
175
- private_site:
176
- url: http://example.com
177
- username: user
178
- password: pass
179
-
180
- Then invoke:
181
-
182
- $ restclient private_site
183
-
184
- Use as a one-off, curl-style:
185
-
186
- $ restclient get http://example.com/resource > output_body
187
-
188
- $ restclient put http://example.com/resource < input_body
189
-
190
- == Logging
191
-
192
- To enable logging you can:
193
-
194
- * set RestClient.log with a Ruby Logger, or
195
- * set an environment variable to avoid modifying the code (in this case you can use a file name, "stdout" or "stderr"):
196
-
197
- $ RESTCLIENT_LOG=stdout path/to/my/program
198
-
199
- Either produces logs like this:
200
-
201
- RestClient.get "http://some/resource"
202
- # => 200 OK | text/html 250 bytes
203
- RestClient.put "http://some/resource", "payload"
204
- # => 401 Unauthorized | application/xml 340 bytes
205
-
206
- Note that these logs are valid Ruby, so you can paste them into the restclient
207
- shell or a script to replay your sequence of rest calls.
208
-
209
- == Proxy
210
-
211
- All calls to RestClient, including Resources, will use the proxy specified by
212
- RestClient.proxy:
213
-
214
- RestClient.proxy = "http://proxy.example.com/"
215
- RestClient.get "http://some/resource"
216
- # => response from some/resource as proxied through proxy.example.com
217
-
218
- Often the proxy URL is set in an environment variable, so you can do this to
219
- use whatever proxy the system is configured to use:
220
-
221
- RestClient.proxy = ENV['http_proxy']
222
-
223
- == Query parameters
224
-
225
- Request objects know about query parameters and will automatically add them to
226
- the URL for GET, HEAD and DELETE requests, escaping the keys and values as needed:
227
-
228
- RestClient.get 'http://example.com/resource', :params => {:foo => 'bar', :baz => 'qux'}
229
- # will GET http://example.com/resource?foo=bar&baz=qux
230
-
231
- == Cookies
232
-
233
- Request and Response objects know about HTTP cookies, and will automatically
234
- extract and set headers for them as needed:
235
-
236
- response = RestClient.get 'http://example.com/action_which_sets_session_id'
237
- response.cookies
238
- # => {"_applicatioN_session_id" => "1234"}
239
-
240
- response2 = RestClient.post(
241
- 'http://localhost:3000/',
242
- {:param1 => "foo"},
243
- {:cookies => {:session_id => "1234"}}
244
- )
245
- # ...response body
246
-
247
- == SSL Client Certificates
248
-
249
- RestClient::Resource.new(
250
- 'https://example.com',
251
- :ssl_client_cert => OpenSSL::X509::Certificate.new(File.read("cert.pem")),
252
- :ssl_client_key => OpenSSL::PKey::RSA.new(File.read("key.pem"), "passphrase, if any"),
253
- :ssl_ca_file => "ca_certificate.pem",
254
- :verify_ssl => OpenSSL::SSL::VERIFY_PEER
255
- ).get
256
-
257
- Self-signed certificates can be generated with the openssl command-line tool.
258
-
259
- == Hook
260
-
261
- RestClient.add_before_execution_proc add a Proc to be called before each execution.
262
- It's handy if you need direct access to the HTTP request.
263
-
264
- Example:
265
-
266
- # Add oauth support using the oauth gem
267
- require 'oauth'
268
- access_token = ...
269
-
270
- RestClient.add_before_execution_proc do |req, params|
271
- access_token.sign! req
272
- end
273
-
274
- RestClient.get 'http://example.com'
275
-
276
- == More
277
-
278
- Need caching, more advanced logging or any ability provided by Rack middleware?
279
-
280
- Have a look at rest-client-components: http://github.com/crohr/rest-client-components
281
-
282
- == Credits
283
-
284
- REST Client Team:: Matthew Manning, Lawrence Leonard Gilbert, Andy Brody
285
-
286
- Creator:: Adam Wiggins
287
-
288
- Maintainer Emeritus:: Julien Kirch
289
-
290
- Major contributions:: Blake Mizerany, Julien Kirch
291
-
292
- Patches contributed by many, including Chris Anderson, Greg Borenstein, Ardekantur, Pedro Belo, Rafael Souza, Rick Olson, Aman Gupta, François Beausoleil and Nick Plante.
293
-
294
- == Legal
295
-
296
- Released under the MIT License: http://www.opensource.org/licenses/mit-license.php
297
-
298
- "Master Shake" photo (http://www.flickr.com/photos/solgrundy/924205581/) by
299
- "SolGrundy"; used under terms of the Creative Commons Attribution-ShareAlike 2.0
300
- Generic license (http://creativecommons.org/licenses/by-sa/2.0/)
@@ -1,55 +0,0 @@
1
- module Net
2
- class HTTP
3
-
4
- # Adding the patch method if it doesn't exist (rest-client issue: https://github.com/archiloque/rest-client/issues/79)
5
- if !defined?(Net::HTTP::Patch)
6
- # Code taken from this commit: https://github.com/ruby/ruby/commit/ab70e53ac3b5102d4ecbe8f38d4f76afad29d37d#lib/net/http.rb
7
- class Protocol
8
- # Sends a PATCH request to the +path+ and gets a response,
9
- # as an HTTPResponse object.
10
- def patch(path, data, initheader = nil, dest = nil, &block) # :yield: +body_segment+
11
- send_entity(path, data, initheader, dest, Patch, &block)
12
- end
13
-
14
- # Executes a request which uses a representation
15
- # and returns its body.
16
- def send_entity(path, data, initheader, dest, type, &block)
17
- res = nil
18
- request(type.new(path, initheader), data) {|r|
19
- r.read_body dest, &block
20
- res = r
21
- }
22
- unless @newimpl
23
- res.value
24
- return res, res.body
25
- end
26
- res
27
- end
28
- end
29
-
30
- class Patch < HTTPRequest
31
- METHOD = 'PATCH'
32
- REQUEST_HAS_BODY = true
33
- RESPONSE_HAS_BODY = true
34
- end
35
- end
36
-
37
- #
38
- # Replace the request method in Net::HTTP to sniff the body type
39
- # and set the stream if appropriate
40
- #
41
- # Taken from:
42
- # http://www.missiondata.com/blog/ruby/29/streaming-data-to-s3-with-ruby/
43
-
44
- alias __request__ request
45
-
46
- def request(req, body=nil, &block)
47
- if body != nil && body.respond_to?(:read)
48
- req.body_stream = body
49
- return __request__(req, nil, &block)
50
- else
51
- return __request__(req, body, &block)
52
- end
53
- end
54
- end
55
- end
@@ -1,85 +0,0 @@
1
- require File.join( File.dirname(File.expand_path(__FILE__)), 'base')
2
-
3
- describe RestClient::AbstractResponse do
4
-
5
- class MyAbstractResponse
6
-
7
- include RestClient::AbstractResponse
8
-
9
- attr_accessor :size
10
-
11
- def initialize net_http_res, args
12
- @net_http_res = net_http_res
13
- @args = args
14
- end
15
-
16
- end
17
-
18
- before do
19
- @net_http_res = double('net http response')
20
- @response = MyAbstractResponse.new(@net_http_res, {})
21
- end
22
-
23
- it "fetches the numeric response code" do
24
- @net_http_res.should_receive(:code).and_return('200')
25
- @response.code.should eq 200
26
- end
27
-
28
- it "has a nice description" do
29
- @net_http_res.should_receive(:to_hash).and_return({'Content-Type' => ['application/pdf']})
30
- @net_http_res.should_receive(:code).and_return('200')
31
- @response.description.should eq "200 OK | application/pdf bytes\n"
32
- end
33
-
34
- it "beautifies the headers by turning the keys to symbols" do
35
- h = RestClient::AbstractResponse.beautify_headers('content-type' => [ 'x' ])
36
- h.keys.first.should eq :content_type
37
- end
38
-
39
- it "beautifies the headers by turning the values to strings instead of one-element arrays" do
40
- h = RestClient::AbstractResponse.beautify_headers('x' => [ 'text/html' ] )
41
- h.values.first.should eq 'text/html'
42
- end
43
-
44
- it "fetches the headers" do
45
- @net_http_res.should_receive(:to_hash).and_return('content-type' => [ 'text/html' ])
46
- @response.headers.should eq({ :content_type => 'text/html' })
47
- end
48
-
49
- it "extracts cookies from response headers" do
50
- @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
51
- @response.cookies.should eq({ 'session_id' => '1' })
52
- end
53
-
54
- it "extract strange cookies" do
55
- @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=ZJ/HQVH6YE+rVkTpn0zvTQ==; path=/'])
56
- @response.cookies.should eq({ 'session_id' => 'ZJ%2FHQVH6YE+rVkTpn0zvTQ%3D%3D' })
57
- end
58
-
59
- it "doesn't escape cookies" do
60
- @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca; path=/'])
61
- @response.cookies.should eq({ 'session_id' => 'BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca' })
62
- end
63
-
64
- it "can access the net http result directly" do
65
- @response.net_http_res.should eq @net_http_res
66
- end
67
-
68
- describe "#return!" do
69
- it "should return the response itself on 200-codes" do
70
- @net_http_res.should_receive(:code).and_return('200')
71
- @response.return!.should be_equal(@response)
72
- end
73
-
74
- it "should raise RequestFailed on unknown codes" do
75
- @net_http_res.should_receive(:code).and_return('1000')
76
- lambda { @response.return! }.should raise_error RestClient::RequestFailed
77
- end
78
-
79
- it "should raise an error on a redirection after non-GET/HEAD requests" do
80
- @net_http_res.should_receive(:code).and_return('301')
81
- @response.args.merge(:method => :put)
82
- lambda { @response.return! }.should raise_error RestClient::RequestFailed
83
- end
84
- end
85
- end
@@ -1,13 +0,0 @@
1
- def is_ruby_19?
2
- RUBY_VERSION > '1.9'
3
- end
4
-
5
- require 'rubygems'
6
-
7
- begin
8
- require "ruby-debug"
9
- rescue LoadError
10
- # NOP, ignore
11
- end
12
-
13
- require File.dirname(__FILE__) + '/../lib/restclient'