rest-client 2.0.0.rc4 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +22 -17
- data/README.md +214 -40
- data/history.md +14 -0
- data/lib/restclient/request.rb +20 -67
- data/lib/restclient/utils.rb +2 -2
- data/lib/restclient/version.rb +1 -1
- data/rest-client.gemspec +1 -1
- data/spec/integration/httpbin_spec.rb +2 -1
- data/spec/integration/integration_spec.rb +5 -3
- data/spec/unit/request_spec.rb +37 -51
- data/spec/unit/resource_spec.rb +5 -1
- metadata +7 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10312217af6f5a0312bdce748c8fd82f428fce64
|
4
|
+
data.tar.gz: 67846732a7926b335a7082eb1fba0b7178f0c5c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56d9d3140ee5418e9b4e877e9756bbb1a1858314c4487b5d7e41ca5fc72f70532f764dcf480c8c3098f4297025fa66c7d8db0bd890e9ae46459e7478a34a685a
|
7
|
+
data.tar.gz: 812f11c8a6c2c4ac5ec68852e75f64ae2d7416ae4683f5ff6525055dbf8e472baed3cc01a85eb76e5da2cb39233ff2dc2129cbdab7165dec89637987b346359b
|
data/.travis.yml
CHANGED
@@ -1,43 +1,48 @@
|
|
1
1
|
# Available ruby versions: http://rubies.travis-ci.org/
|
2
2
|
|
3
3
|
language: ruby
|
4
|
+
|
4
5
|
os:
|
5
6
|
- linux
|
6
7
|
- osx
|
8
|
+
|
7
9
|
rvm:
|
8
10
|
- "2.0.0"
|
9
11
|
- "2.1" # latest 2.1.x
|
10
|
-
- "2.2"
|
11
|
-
- "2.3.
|
12
|
+
- "2.2.5"
|
13
|
+
- "2.3.3"
|
14
|
+
- "2.4.0"
|
12
15
|
- "ruby-head"
|
13
16
|
- "jruby-9.0.5.0"
|
17
|
+
- "jruby-9.1.5.0"
|
14
18
|
- "jruby-head"
|
19
|
+
|
20
|
+
cache: bundler
|
21
|
+
|
15
22
|
script:
|
16
23
|
bundle exec rake test
|
24
|
+
|
17
25
|
branches:
|
18
26
|
except:
|
19
27
|
- "readme-edits"
|
20
28
|
|
29
|
+
before_install:
|
30
|
+
- gem update --system
|
31
|
+
# bundler installation needed for jruby-head
|
32
|
+
# https://github.com/travis-ci/travis-ci/issues/5861
|
33
|
+
- gem install bundler
|
34
|
+
|
21
35
|
# Travis OS X support is pretty janky. These are some hacks to include tests
|
22
36
|
# only on versions that actually work.
|
23
|
-
# (last tested: 2016-
|
37
|
+
# (last tested: 2016-11)
|
24
38
|
matrix:
|
25
|
-
exclude:
|
26
|
-
|
27
|
-
|
28
|
-
- os: osx
|
29
|
-
rvm: '2.3.1' # No 2.3.x at all
|
30
|
-
include:
|
31
|
-
- os: osx
|
32
|
-
rvm: '2.2.2' # Travis OS X doesn't have 2.2 aliases
|
39
|
+
# exclude: {}
|
40
|
+
# include: {}
|
41
|
+
|
33
42
|
allow_failures:
|
34
43
|
- rvm: 'ruby-head'
|
35
|
-
|
36
|
-
|
37
|
-
- os: osx
|
38
|
-
rvm: 'jruby-head'
|
39
|
-
- os: linux
|
40
|
-
rvm: 'jruby-head'
|
44
|
+
|
45
|
+
# return results as soon as mandatory versions are done
|
41
46
|
fast_finish: true
|
42
47
|
|
43
48
|
sudo: false
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# REST Client -- simple DSL for accessing HTTP and REST resources
|
2
2
|
|
3
|
-
[![Gem Downloads](https://img.shields.io/gem/dt/
|
3
|
+
[![Gem Downloads](https://img.shields.io/gem/dt/rest-client.svg)](https://rubygems.org/gems/rest-client)
|
4
4
|
[![Build Status](https://travis-ci.org/rest-client/rest-client.svg?branch=master)](https://travis-ci.org/rest-client/rest-client)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/rest-client/rest-client.svg)](https://codeclimate.com/github/rest-client/rest-client)
|
6
6
|
[![Inline docs](http://inch-ci.org/github/rest-client/rest-client.svg?branch=master)](http://www.rubydoc.info/github/rest-client/rest-client/master)
|
@@ -45,31 +45,78 @@ There are also several development dependencies. It's recommended to use
|
|
45
45
|
[bundler](http://bundler.io/) to manage these dependencies for hacking on
|
46
46
|
rest-client.
|
47
47
|
|
48
|
+
### Upgrading to rest-client 2.0 from 1.x
|
49
|
+
|
50
|
+
Users are encouraged to upgrade to rest-client 2.0, which cleans up a number of
|
51
|
+
API warts and wrinkles, making rest-client generally more useful. Usage is
|
52
|
+
largely compatible, so many applications will be able to upgrade with no
|
53
|
+
changes.
|
54
|
+
|
55
|
+
Overview of significant changes:
|
56
|
+
|
57
|
+
* requires Ruby >= 2.0
|
58
|
+
* `RestClient::Response` objects are a subclass of `String` rather than a
|
59
|
+
Frankenstein monster. And `#body` or `#to_s` return a true `String` object.
|
60
|
+
* cleanup of exception classes, including new `RestClient::Exceptions::Timeout`
|
61
|
+
* improvements to handling of redirects: responses and history are properly
|
62
|
+
exposed
|
63
|
+
* major changes to cookie support: cookie jars are used for browser-like
|
64
|
+
behavior throughout
|
65
|
+
* encoding: Content-Type charset response headers are used to automatically set
|
66
|
+
the encoding of the response string
|
67
|
+
* HTTP params: handling of GET/POST params is more consistent and sophisticated
|
68
|
+
for deeply nested hash objects, and `ParamsArray` can be used to pass ordered
|
69
|
+
params
|
70
|
+
* improved proxy support with per-request proxy configuration, plus the ability
|
71
|
+
to disable proxies set by environment variables
|
72
|
+
* default request headers: rest-client sets `Accept: */*` and
|
73
|
+
`User-Agent: rest-client/...`
|
74
|
+
|
75
|
+
See [history.md](./history.md) for a more complete description of changes.
|
76
|
+
|
48
77
|
## Usage: Raw URL
|
78
|
+
|
79
|
+
Basic usage:
|
80
|
+
|
81
|
+
```ruby
|
82
|
+
require 'rest-client'
|
83
|
+
|
84
|
+
RestClient.get(url, headers={})
|
85
|
+
|
86
|
+
RestClient.post(url, payload, headers={})
|
87
|
+
```
|
88
|
+
|
89
|
+
In the high level helpers, only POST, PATCH, and PUT take a payload argument.
|
90
|
+
To pass a payload with other HTTP verbs or to pass more advanced options, use
|
91
|
+
`RestClient::Request.execute` instead.
|
92
|
+
|
93
|
+
More detailed examples:
|
94
|
+
|
49
95
|
```ruby
|
50
96
|
require 'rest-client'
|
51
97
|
|
52
98
|
RestClient.get 'http://example.com/resource'
|
53
99
|
|
54
|
-
RestClient.get 'http://example.com/resource', {:
|
100
|
+
RestClient.get 'http://example.com/resource', {params: {id: 50, 'foo' => 'bar'}}
|
55
101
|
|
56
|
-
RestClient.get 'https://user:password@example.com/private/resource', {:
|
102
|
+
RestClient.get 'https://user:password@example.com/private/resource', {accept: :json}
|
57
103
|
|
58
|
-
RestClient.post 'http://example.com/resource', :
|
104
|
+
RestClient.post 'http://example.com/resource', {param1: 'one', nested: {param2: 'two'}}
|
59
105
|
|
60
|
-
RestClient.post "http://example.com/resource", {
|
106
|
+
RestClient.post "http://example.com/resource", {'x' => 1}.to_json, {content_type: :json, accept: :json}
|
61
107
|
|
62
108
|
RestClient.delete 'http://example.com/resource'
|
63
109
|
|
64
|
-
response = RestClient.get 'http://example.com/resource'
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
110
|
+
>> response = RestClient.get 'http://example.com/resource'
|
111
|
+
=> <RestClient::Response 200 "<!doctype h...">
|
112
|
+
>> response.code
|
113
|
+
=> 200
|
114
|
+
>> response.cookies
|
115
|
+
=> {"Foo"=>"BAR", "QUUX"=>"QUUUUX"}
|
116
|
+
>> response.headers
|
117
|
+
=> {:content_type=>"text/html; charset=utf-8", :cache_control=>"private" ... }
|
118
|
+
>> response.body
|
119
|
+
=> "<!doctype html>\n<html>\n<head>\n <title>Example Domain</title>\n\n ..."
|
73
120
|
|
74
121
|
RestClient.post( url,
|
75
122
|
{
|
@@ -162,25 +209,76 @@ See `RestClient::Resource` docs for details.
|
|
162
209
|
- for result codes between `200` and `207`, a `RestClient::Response` will be returned
|
163
210
|
- for result codes `301`, `302` or `307`, the redirection will be followed if the request is a `GET` or a `HEAD`
|
164
211
|
- for result code `303`, the redirection will be followed and the request transformed into a `GET`
|
165
|
-
- for other cases, a `RestClient::
|
212
|
+
- for other cases, a `RestClient::ExceptionWithResponse` holding the Response will be raised; a specific exception class will be thrown for known error codes
|
166
213
|
- call `.response` on the exception to get the server's response
|
167
214
|
|
168
215
|
```ruby
|
169
|
-
RestClient.get 'http://example.com/
|
170
|
-
|
216
|
+
>> RestClient.get 'http://example.com/nonexistent'
|
217
|
+
Exception: RestClient::NotFound: 404 Not Found
|
171
218
|
|
172
|
-
begin
|
173
|
-
|
174
|
-
rescue => e
|
175
|
-
|
176
|
-
end
|
177
|
-
|
219
|
+
>> begin
|
220
|
+
RestClient.get 'http://example.com/nonexistent'
|
221
|
+
rescue RestClient::ExceptionWithResponse => e
|
222
|
+
e.response
|
223
|
+
end
|
224
|
+
=> <RestClient::Response 404 "<!doctype h...">
|
225
|
+
```
|
226
|
+
|
227
|
+
### Other exceptions
|
228
|
+
|
229
|
+
While most exceptions have been collected under `RestClient::RequestFailed` aka
|
230
|
+
`RestClient::ExceptionWithResponse`, there are a few quirky exceptions that
|
231
|
+
have been kept for backwards compatibility.
|
232
|
+
|
233
|
+
RestClient will propagate up exceptions like socket errors without modification:
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
>> RestClient.get 'http://localhost:12345'
|
237
|
+
Exception: Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 12345
|
178
238
|
```
|
179
239
|
|
180
|
-
|
240
|
+
RestClient handles a few specific error cases separately in order to give
|
241
|
+
better error messages. These will hopefully be cleaned up in a future major
|
242
|
+
release.
|
243
|
+
|
244
|
+
`RestClient::ServerBrokeConnection` is translated from `EOFError` to give a
|
245
|
+
better error message.
|
246
|
+
|
247
|
+
`RestClient::SSLCertificateNotVerified` is raised when HTTPS validation fails.
|
248
|
+
Other `OpenSSL::SSL::SSLError` errors are raised as is.
|
249
|
+
|
250
|
+
### Redirection
|
251
|
+
|
252
|
+
By default, rest-client will follow HTTP 30x redirection requests.
|
253
|
+
|
254
|
+
__New in 2.0:__ `RestClient::Response` exposes a `#history` method that returns
|
255
|
+
a list of each response received in a redirection chain.
|
256
|
+
|
257
|
+
```ruby
|
258
|
+
>> r = RestClient.get('http://httpbin.org/redirect/2')
|
259
|
+
=> <RestClient::Response 200 "{\n \"args\":...">
|
260
|
+
|
261
|
+
# see each response in the redirect chain
|
262
|
+
>> r.history
|
263
|
+
=> [<RestClient::Response 302 "<!DOCTYPE H...">, <RestClient::Response 302 "">]
|
264
|
+
|
265
|
+
# see each requested URL
|
266
|
+
>> r.request.url
|
267
|
+
=> "http://httpbin.org/get"
|
268
|
+
>> r.history.map {|x| x.request.url}
|
269
|
+
=> ["http://httpbin.org/redirect/2", "http://httpbin.org/relative-redirect/1"]
|
270
|
+
```
|
271
|
+
|
272
|
+
#### Manually following redirection
|
181
273
|
|
182
274
|
To disable automatic redirection, set `:max_redirects => 0`.
|
183
275
|
|
276
|
+
__New in 2.0:__ Prior versions of rest-client would raise
|
277
|
+
`RestClient::MaxRedirectsReached`, with no easy way to access the server's
|
278
|
+
response. In 2.0, rest-client raises the normal
|
279
|
+
`RestClient::ExceptionWithResponse` as it would with any other non-HTTP-20x
|
280
|
+
response.
|
281
|
+
|
184
282
|
```ruby
|
185
283
|
>> RestClient::Request.execute(method: :get, url: 'http://httpbin.org/redirect/1')
|
186
284
|
=> RestClient::Response 200 "{\n "args":..."
|
@@ -226,7 +324,7 @@ Response objects have several useful methods. (See the class rdoc for more detai
|
|
226
324
|
- `Response#cookies`: A hash of HTTP cookies set by the server
|
227
325
|
- `Response#cookie_jar`: <em>New in 1.8</em> An HTTP::CookieJar of cookies
|
228
326
|
- `Response#request`: The RestClient::Request object used to make the request
|
229
|
-
- `Response#history`: If redirection was followed, a list of prior Response objects
|
327
|
+
- `Response#history`: <em>New in 2.0</em> If redirection was followed, a list of prior Response objects
|
230
328
|
|
231
329
|
```ruby
|
232
330
|
RestClient.get('http://example.com')
|
@@ -240,18 +338,20 @@ end
|
|
240
338
|
➔ <RestClient::Response 404 "<!doctype h...">
|
241
339
|
```
|
242
340
|
|
243
|
-
### Response callbacks
|
341
|
+
### Response callbacks, error handling
|
244
342
|
|
245
343
|
A block can be passed to the RestClient method. This block will then be called with the Response.
|
246
344
|
Response.return! can be called to invoke the default response's behavior.
|
247
345
|
|
248
346
|
```ruby
|
249
347
|
# Don't raise exceptions but return the response
|
250
|
-
RestClient.get('http://example.com/
|
251
|
-
|
348
|
+
>> RestClient.get('http://example.com/nonexistent') {|response, request, result| response }
|
349
|
+
=> <RestClient::Response 404 "<!doctype h...">
|
350
|
+
```
|
252
351
|
|
352
|
+
```ruby
|
253
353
|
# Manage a specific error code
|
254
|
-
RestClient.get('http://
|
354
|
+
RestClient.get('http://example.com/resource') { |response, request, result, &block|
|
255
355
|
case response.code
|
256
356
|
when 200
|
257
357
|
p "It worked !"
|
@@ -262,19 +362,68 @@ RestClient.get('http://my-rest-service.com/resource'){ |response, request, resul
|
|
262
362
|
response.return!(request, result, &block)
|
263
363
|
end
|
264
364
|
}
|
365
|
+
```
|
366
|
+
|
367
|
+
But note that it may be more straightforward to use exceptions to handle
|
368
|
+
different HTTP error response cases:
|
369
|
+
|
370
|
+
```ruby
|
371
|
+
begin
|
372
|
+
resp = RestClient.get('http://example.com/resource')
|
373
|
+
rescue RestClient::Unauthorized, RestClient::Forbidden => err
|
374
|
+
puts 'Access denied'
|
375
|
+
return err.response
|
376
|
+
rescue RestClient::ImATeapot => err
|
377
|
+
puts 'The server is a teapot! # RFC 2324'
|
378
|
+
return err.response
|
379
|
+
else
|
380
|
+
puts 'It worked!'
|
381
|
+
return resp
|
382
|
+
end
|
383
|
+
```
|
265
384
|
|
385
|
+
For GET and HEAD requests, rest-client automatically follows redirection. For
|
386
|
+
other HTTP verbs, call `.follow_redirection` on the response object (works both
|
387
|
+
in block form and in exception form).
|
388
|
+
|
389
|
+
```ruby
|
266
390
|
# Follow redirections for all request types and not only for get and head
|
267
391
|
# RFC : "If the 301, 302 or 307 status code is received in response to a request other than GET or HEAD,
|
268
392
|
# the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user,
|
269
393
|
# since this might change the conditions under which the request was issued."
|
270
|
-
|
271
|
-
|
272
|
-
|
394
|
+
|
395
|
+
# block style
|
396
|
+
RestClient.post('http://example.com/redirect', 'body') { |response, request, result|
|
397
|
+
case response.code
|
398
|
+
when 301, 302, 307
|
399
|
+
response.follow_redirection
|
273
400
|
else
|
274
|
-
response.return!
|
401
|
+
response.return!
|
275
402
|
end
|
276
403
|
}
|
404
|
+
|
405
|
+
# exception style by explicit classes
|
406
|
+
begin
|
407
|
+
RestClient.post('http://example.com/redirect', 'body')
|
408
|
+
rescue RestClient::MovedPermanently,
|
409
|
+
RestClient::Found,
|
410
|
+
RestClient::TemporaryRedirect => err
|
411
|
+
err.response.follow_redirection
|
412
|
+
end
|
413
|
+
|
414
|
+
# exception style by response code
|
415
|
+
begin
|
416
|
+
RestClient.post('http://example.com/redirect', 'body')
|
417
|
+
rescue RestClient::ExceptionWithResponse => err
|
418
|
+
case err.http_code
|
419
|
+
when 301, 302, 307
|
420
|
+
err.response.follow_redirection
|
421
|
+
else
|
422
|
+
raise
|
423
|
+
end
|
424
|
+
end
|
277
425
|
```
|
426
|
+
|
278
427
|
## Non-normalized URIs
|
279
428
|
|
280
429
|
If you need to normalize URIs, e.g. to work with International Resource Identifiers (IRIs),
|
@@ -452,6 +601,14 @@ Basic `x-www-form-urlencoded` POST params:
|
|
452
601
|
"url"=>"https://httpbin.org/post"}
|
453
602
|
```
|
454
603
|
|
604
|
+
JSON payload: rest-client does not speak JSON natively, so serialize your
|
605
|
+
payload to a string before passing it to rest-client.
|
606
|
+
```ruby
|
607
|
+
>> payload = {'name' => 'newrepo', 'description': 'A new repo'}
|
608
|
+
>> RestClient.post('https://api.github.com/user/repos', payload.to_json, content_type: :json)
|
609
|
+
=> <RestClient::Response 201 "{\"id\":75149...">
|
610
|
+
```
|
611
|
+
|
455
612
|
Advanced GET params (arrays):
|
456
613
|
```ruby
|
457
614
|
>> r = RestClient.get('https://http-params.herokuapp.com/get', params: {foo: [1,2,3]})
|
@@ -514,6 +671,24 @@ RestClient.post 'http://example.com/resource', {:foo => 'bar', :baz => 'qux'}, {
|
|
514
671
|
RestClient.delete 'http://example.com/resource', {:Authorization => 'Bearer cT0febFoD5lxAlNAXHo6g'}
|
515
672
|
```
|
516
673
|
|
674
|
+
## Timeouts
|
675
|
+
|
676
|
+
By default the timeout for a request is 60 seconds. Timeouts for your request can
|
677
|
+
be adjusted by setting the `timeout:` to the number of seconds that you would like
|
678
|
+
the request to wait. Setting `timeout:` will override both `read_timeout:` and `open_timeout:`.
|
679
|
+
|
680
|
+
```ruby
|
681
|
+
RestClient::Request.execute(method: :get, url: 'http://example.com/resource',
|
682
|
+
timeout: 120)
|
683
|
+
```
|
684
|
+
|
685
|
+
Additionally, you can set `read_timeout:` and `open_timeout:` separately.
|
686
|
+
|
687
|
+
```ruby
|
688
|
+
RestClient::Request.execute(method: :get, url: 'http://example.com/resource',
|
689
|
+
read_timeout: 120, open_timeout: 240)
|
690
|
+
```
|
691
|
+
|
517
692
|
## Cookies
|
518
693
|
|
519
694
|
Request and Response objects know about HTTP cookies, and will automatically
|
@@ -587,13 +762,12 @@ Need caching, more advanced logging or any ability provided by Rack middleware?
|
|
587
762
|
Have a look at rest-client-components: http://github.com/crohr/rest-client-components
|
588
763
|
|
589
764
|
## Credits
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
| Major contributions | Blake Mizerany, Julien Kirch |
|
765
|
+
| | |
|
766
|
+
|-------------------------|---------------------------------------------------------|
|
767
|
+
| **REST Client Team** | Andy Brody |
|
768
|
+
| **Creator** | Adam Wiggins |
|
769
|
+
| **Maintainers Emeriti** | Lawrence Leonard Gilbert, Matthew Manning, Julien Kirch |
|
770
|
+
| **Major contributions** | Blake Mizerany, Julien Kirch |
|
597
771
|
|
598
772
|
A great many generous folks have contributed features and patches.
|
599
773
|
See AUTHORS for the full list.
|
data/history.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# 2.0.2
|
2
|
+
|
3
|
+
- Suppress the header override warning introduced in 2.0.1 if the value is the
|
4
|
+
same. There's no conflict if the value is unchanged. (#578)
|
5
|
+
|
6
|
+
# 2.0.1
|
7
|
+
|
8
|
+
- Warn if auto-generated headers from the payload, such as Content-Type,
|
9
|
+
override headers set by the user. This is usually not what the user wants to
|
10
|
+
happen, and can be surprising. (#554)
|
11
|
+
- Drop the old check for weak default TLS ciphers, and use the built-in Ruby
|
12
|
+
defaults. Ruby versions from Oct. 2014 onward use sane defaults, so this is
|
13
|
+
no longer needed. (#573)
|
14
|
+
|
1
15
|
# 2.0.0
|
2
16
|
|
3
17
|
This release is largely API compatible, but makes several breaking changes.
|
data/lib/restclient/request.rb
CHANGED
@@ -52,63 +52,6 @@ module RestClient
|
|
52
52
|
new(args).execute(& block)
|
53
53
|
end
|
54
54
|
|
55
|
-
# This is similar to the list now in ruby core, but adds HIGH for better
|
56
|
-
# compatibility (similar to Firefox) and moves AES-GCM cipher suites above
|
57
|
-
# DHE/ECDHE CBC suites (similar to Chromium).
|
58
|
-
# https://github.com/ruby/ruby/commit/699b209cf8cf11809620e12985ad33ae33b119ee
|
59
|
-
#
|
60
|
-
# This list will be used by default if the Ruby global OpenSSL default
|
61
|
-
# ciphers appear to be a weak list.
|
62
|
-
DefaultCiphers = %w{
|
63
|
-
!aNULL
|
64
|
-
!eNULL
|
65
|
-
!EXPORT
|
66
|
-
!SSLV2
|
67
|
-
!LOW
|
68
|
-
|
69
|
-
ECDHE-ECDSA-AES128-GCM-SHA256
|
70
|
-
ECDHE-RSA-AES128-GCM-SHA256
|
71
|
-
ECDHE-ECDSA-AES256-GCM-SHA384
|
72
|
-
ECDHE-RSA-AES256-GCM-SHA384
|
73
|
-
DHE-RSA-AES128-GCM-SHA256
|
74
|
-
DHE-DSS-AES128-GCM-SHA256
|
75
|
-
DHE-RSA-AES256-GCM-SHA384
|
76
|
-
DHE-DSS-AES256-GCM-SHA384
|
77
|
-
AES128-GCM-SHA256
|
78
|
-
AES256-GCM-SHA384
|
79
|
-
ECDHE-ECDSA-AES128-SHA256
|
80
|
-
ECDHE-RSA-AES128-SHA256
|
81
|
-
ECDHE-ECDSA-AES128-SHA
|
82
|
-
ECDHE-RSA-AES128-SHA
|
83
|
-
ECDHE-ECDSA-AES256-SHA384
|
84
|
-
ECDHE-RSA-AES256-SHA384
|
85
|
-
ECDHE-ECDSA-AES256-SHA
|
86
|
-
ECDHE-RSA-AES256-SHA
|
87
|
-
DHE-RSA-AES128-SHA256
|
88
|
-
DHE-RSA-AES256-SHA256
|
89
|
-
DHE-RSA-AES128-SHA
|
90
|
-
DHE-RSA-AES256-SHA
|
91
|
-
DHE-DSS-AES128-SHA256
|
92
|
-
DHE-DSS-AES256-SHA256
|
93
|
-
DHE-DSS-AES128-SHA
|
94
|
-
DHE-DSS-AES256-SHA
|
95
|
-
AES128-SHA256
|
96
|
-
AES256-SHA256
|
97
|
-
AES128-SHA
|
98
|
-
AES256-SHA
|
99
|
-
ECDHE-ECDSA-RC4-SHA
|
100
|
-
ECDHE-RSA-RC4-SHA
|
101
|
-
RC4-SHA
|
102
|
-
|
103
|
-
HIGH
|
104
|
-
+RC4
|
105
|
-
}.join(":")
|
106
|
-
|
107
|
-
# A set of weak default ciphers that we will override by default.
|
108
|
-
WeakDefaultCiphers = Set.new([
|
109
|
-
"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
|
110
|
-
])
|
111
|
-
|
112
55
|
SSLOptionList = %w{client_cert client_key ca_file ca_path cert_store
|
113
56
|
version ciphers verify_callback verify_callback_warnings}
|
114
57
|
|
@@ -186,15 +129,6 @@ module RestClient
|
|
186
129
|
if !ssl_ca_file && !ssl_ca_path && !@ssl_opts.include?(:cert_store)
|
187
130
|
@ssl_opts[:cert_store] = self.class.default_ssl_cert_store
|
188
131
|
end
|
189
|
-
|
190
|
-
unless @ssl_opts.include?(:ciphers)
|
191
|
-
# If we're on a Ruby version that has insecure default ciphers,
|
192
|
-
# override it with our default list.
|
193
|
-
if WeakDefaultCiphers.include?(
|
194
|
-
OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.fetch(:ciphers))
|
195
|
-
@ssl_opts[:ciphers] = DefaultCiphers
|
196
|
-
end
|
197
|
-
end
|
198
132
|
end
|
199
133
|
|
200
134
|
@tf = nil # If you are a raw request, this is your tempfile
|
@@ -428,7 +362,26 @@ module RestClient
|
|
428
362
|
#
|
429
363
|
def make_headers(user_headers)
|
430
364
|
headers = stringify_headers(default_headers).merge(stringify_headers(user_headers))
|
431
|
-
|
365
|
+
|
366
|
+
# override headers from the payload (e.g. Content-Type, Content-Length)
|
367
|
+
if @payload
|
368
|
+
payload_headers = @payload.headers
|
369
|
+
|
370
|
+
# Warn the user if we override any headers that were previously
|
371
|
+
# present. This usually indicates that rest-client was passed
|
372
|
+
# conflicting information, e.g. if it was asked to render a payload as
|
373
|
+
# x-www-form-urlencoded but a Content-Type application/json was
|
374
|
+
# also supplied by the user.
|
375
|
+
payload_headers.each_pair do |key, val|
|
376
|
+
if headers.include?(key) && headers[key] != val
|
377
|
+
warn("warning: Overriding #{key.inspect} header " +
|
378
|
+
"#{headers.fetch(key).inspect} with #{val.inspect} " +
|
379
|
+
"due to payload")
|
380
|
+
end
|
381
|
+
end
|
382
|
+
|
383
|
+
headers.merge!(payload_headers)
|
384
|
+
end
|
432
385
|
|
433
386
|
# merge in cookies
|
434
387
|
cookies = make_cookie_header
|
data/lib/restclient/utils.rb
CHANGED
@@ -8,8 +8,8 @@ module RestClient
|
|
8
8
|
# text. This differs from the older RFC 2616 behavior, which specifies
|
9
9
|
# using ISO-8859-1 for text/* content types without a charset.
|
10
10
|
#
|
11
|
-
# Strings will
|
12
|
-
#
|
11
|
+
# Strings will use the default encoding when this method returns nil. This
|
12
|
+
# default is likely to be UTF-8 for Ruby >= 2.0
|
13
13
|
#
|
14
14
|
# @param headers [Hash<Symbol,String>]
|
15
15
|
#
|
data/lib/restclient/version.rb
CHANGED
data/rest-client.gemspec
CHANGED
@@ -20,7 +20,7 @@ Gem::Specification.new do |s|
|
|
20
20
|
s.add_development_dependency('rspec', '~> 3.0')
|
21
21
|
s.add_development_dependency('pry', '~> 0')
|
22
22
|
s.add_development_dependency('pry-doc', '~> 0')
|
23
|
-
s.add_development_dependency('rdoc', '>= 2.4.2', '<
|
23
|
+
s.add_development_dependency('rdoc', '>= 2.4.2', '< 6.0')
|
24
24
|
s.add_development_dependency('rubocop', '~> 0')
|
25
25
|
|
26
26
|
s.add_dependency('http-cookie', '>= 1.0.2', '< 2.0')
|
@@ -13,7 +13,8 @@ describe RestClient::Request do
|
|
13
13
|
def default_httpbin_url
|
14
14
|
# add a hack to work around java/jruby bug
|
15
15
|
# java.lang.RuntimeException: Could not generate DH keypair with backtrace
|
16
|
-
|
16
|
+
# Also (2017-04-09) Travis Jruby versions have a broken CA keystore
|
17
|
+
if ENV['TRAVIS_RUBY_VERSION'] =~ /\Ajruby-/
|
17
18
|
'http://httpbin.org/'
|
18
19
|
else
|
19
20
|
'https://httpbin.org/'
|
@@ -88,14 +88,15 @@ describe RestClient do
|
|
88
88
|
expect(response.encode('utf-8')).to eq body_utf8
|
89
89
|
end
|
90
90
|
|
91
|
-
it 'defaults to
|
91
|
+
it 'defaults to the default encoding' do
|
92
92
|
stub_request(:get, 'www.example.com').to_return(
|
93
93
|
body: 'abc', status: 200, headers: {
|
94
94
|
'Content-Type' => 'text/plain'
|
95
95
|
})
|
96
96
|
|
97
97
|
response = RestClient.get 'www.example.com'
|
98
|
-
expect(response.encoding).to eq Encoding.default_external
|
98
|
+
# expect(response.encoding).to eq Encoding.default_external
|
99
|
+
expect(response.encoding).to eq Encoding::UTF_8
|
99
100
|
end
|
100
101
|
|
101
102
|
it 'handles invalid encoding' do
|
@@ -105,7 +106,8 @@ describe RestClient do
|
|
105
106
|
})
|
106
107
|
|
107
108
|
response = RestClient.get 'www.example.com'
|
108
|
-
expect(response.encoding).to eq Encoding.default_external
|
109
|
+
# expect(response.encoding).to eq Encoding.default_external
|
110
|
+
expect(response.encoding).to eq Encoding::UTF_8
|
109
111
|
end
|
110
112
|
|
111
113
|
it 'leaves images as binary' do
|
data/spec/unit/request_spec.rb
CHANGED
@@ -260,6 +260,41 @@ describe RestClient::Request, :include_helpers do
|
|
260
260
|
end
|
261
261
|
end
|
262
262
|
|
263
|
+
it 'warns when overriding existing headers via payload' do
|
264
|
+
expect(fake_stderr {
|
265
|
+
RestClient::Request.new(method: :post, url: 'example.com',
|
266
|
+
payload: {'foo' => 1}, headers: {content_type: :json})
|
267
|
+
}).to match(/warning: Overriding "Content-Type" header/i)
|
268
|
+
expect(fake_stderr {
|
269
|
+
RestClient::Request.new(method: :post, url: 'example.com',
|
270
|
+
payload: {'foo' => 1}, headers: {'Content-Type' => 'application/json'})
|
271
|
+
}).to match(/warning: Overriding "Content-Type" header/i)
|
272
|
+
|
273
|
+
expect(fake_stderr {
|
274
|
+
RestClient::Request.new(method: :post, url: 'example.com',
|
275
|
+
payload: '123456', headers: {content_length: '20'})
|
276
|
+
}).to match(/warning: Overriding "Content-Length" header/i)
|
277
|
+
expect(fake_stderr {
|
278
|
+
RestClient::Request.new(method: :post, url: 'example.com',
|
279
|
+
payload: '123456', headers: {'Content-Length' => '20'})
|
280
|
+
}).to match(/warning: Overriding "Content-Length" header/i)
|
281
|
+
end
|
282
|
+
|
283
|
+
it "does not warn when overriding user header with header derived from payload if those header values were identical" do
|
284
|
+
expect(fake_stderr {
|
285
|
+
RestClient::Request.new(method: :post, url: 'example.com',
|
286
|
+
payload: {'foo' => '123456'}, headers: { 'Content-Type' => 'application/x-www-form-urlencoded' })
|
287
|
+
}).not_to match(/warning: Overriding "Content-Type" header/i)
|
288
|
+
end
|
289
|
+
|
290
|
+
it 'does not warn for a normal looking payload' do
|
291
|
+
expect(fake_stderr {
|
292
|
+
RestClient::Request.new(method: :post, url: 'example.com', payload: 'payload')
|
293
|
+
RestClient::Request.new(method: :post, url: 'example.com', payload: 'payload', headers: {content_type: :json})
|
294
|
+
RestClient::Request.new(method: :post, url: 'example.com', payload: {'foo' => 'bar'})
|
295
|
+
}).to eq ''
|
296
|
+
end
|
297
|
+
|
263
298
|
it "uses netrc credentials" do
|
264
299
|
expect(Netrc).to receive(:read).and_return('example.com' => ['a', 'b'])
|
265
300
|
request = RestClient::Request.new(:method => :put, :url => 'http://example.com/', :payload => 'payload')
|
@@ -567,7 +602,8 @@ describe RestClient::Request, :include_helpers do
|
|
567
602
|
allow(ENV).to receive(:[]).with("http_proxy").and_return("http://127.0.0.1")
|
568
603
|
allow(ENV).to receive(:[]).with("no_proxy").and_return(nil)
|
569
604
|
allow(ENV).to receive(:[]).with("NO_PROXY").and_return(nil)
|
570
|
-
allow(
|
605
|
+
allow(Netrc).to receive(:read).and_return({})
|
606
|
+
|
571
607
|
req = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
|
572
608
|
obj = req.net_http_object('host', 80)
|
573
609
|
expect(obj.proxy?).to be true
|
@@ -897,56 +933,6 @@ describe RestClient::Request, :include_helpers do
|
|
897
933
|
@request.send(:transmit, @uri, 'req', 'payload')
|
898
934
|
end
|
899
935
|
|
900
|
-
it "should override ssl_ciphers with better defaults with weak default ciphers" do
|
901
|
-
stub_const(
|
902
|
-
'::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
|
903
|
-
{
|
904
|
-
:ssl_version=>"SSLv23",
|
905
|
-
:verify_mode=>1,
|
906
|
-
:ciphers=>"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
|
907
|
-
:options=>-2147480577,
|
908
|
-
}
|
909
|
-
)
|
910
|
-
|
911
|
-
@request = RestClient::Request.new(
|
912
|
-
:method => :put,
|
913
|
-
:url => 'https://some/resource',
|
914
|
-
:payload => 'payload',
|
915
|
-
)
|
916
|
-
|
917
|
-
expect(@net).to receive(:ciphers=).with(RestClient::Request::DefaultCiphers)
|
918
|
-
|
919
|
-
allow(@http).to receive(:request)
|
920
|
-
allow(@request).to receive(:process_result)
|
921
|
-
allow(@request).to receive(:response_log)
|
922
|
-
@request.send(:transmit, @uri, 'req', 'payload')
|
923
|
-
end
|
924
|
-
|
925
|
-
it "should not override ssl_ciphers with better defaults with different default ciphers" do
|
926
|
-
stub_const(
|
927
|
-
'::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
|
928
|
-
{
|
929
|
-
:ssl_version=>"SSLv23",
|
930
|
-
:verify_mode=>1,
|
931
|
-
:ciphers=>"HIGH:!aNULL:!eNULL:!EXPORT:!LOW:!MEDIUM:!SSLv2",
|
932
|
-
:options=>-2147480577,
|
933
|
-
}
|
934
|
-
)
|
935
|
-
|
936
|
-
@request = RestClient::Request.new(
|
937
|
-
:method => :put,
|
938
|
-
:url => 'https://some/resource',
|
939
|
-
:payload => 'payload',
|
940
|
-
)
|
941
|
-
|
942
|
-
expect(@net).not_to receive(:ciphers=)
|
943
|
-
|
944
|
-
allow(@http).to receive(:request)
|
945
|
-
allow(@request).to receive(:process_result)
|
946
|
-
allow(@request).to receive(:response_log)
|
947
|
-
@request.send(:transmit, @uri, 'req', 'payload')
|
948
|
-
end
|
949
|
-
|
950
936
|
it "should set the ssl_client_cert if provided" do
|
951
937
|
@request = RestClient::Request.new(
|
952
938
|
:method => :put,
|
data/spec/unit/resource_spec.rb
CHANGED
@@ -94,7 +94,11 @@ describe RestClient::Resource do
|
|
94
94
|
expect(parent.send(:[], 'posts', &block2).block).not_to eq block1
|
95
95
|
end
|
96
96
|
|
97
|
-
|
97
|
+
# Test fails on jruby 9.1.[0-5].* due to
|
98
|
+
# https://github.com/jruby/jruby/issues/4217
|
99
|
+
it "the block should be overrideable in ruby 1.9 syntax",
|
100
|
+
:unless => (RUBY_ENGINE == 'jruby' && JRUBY_VERSION =~ /\A9\.1\.[0-5]\./) \
|
101
|
+
do
|
98
102
|
block1 = proc {|r| r}
|
99
103
|
block2 = ->(r) {}
|
100
104
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rest-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- REST Client Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-04-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: webmock
|
@@ -75,7 +75,7 @@ dependencies:
|
|
75
75
|
version: 2.4.2
|
76
76
|
- - "<"
|
77
77
|
- !ruby/object:Gem::Version
|
78
|
-
version: '
|
78
|
+
version: '6.0'
|
79
79
|
type: :development
|
80
80
|
prerelease: false
|
81
81
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -85,7 +85,7 @@ dependencies:
|
|
85
85
|
version: 2.4.2
|
86
86
|
- - "<"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
88
|
+
version: '6.0'
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: rubocop
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
@@ -239,12 +239,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
239
239
|
version: 2.0.0
|
240
240
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
241
241
|
requirements:
|
242
|
-
- - "
|
242
|
+
- - ">="
|
243
243
|
- !ruby/object:Gem::Version
|
244
|
-
version:
|
244
|
+
version: '0'
|
245
245
|
requirements: []
|
246
246
|
rubyforge_project:
|
247
|
-
rubygems_version: 2.
|
247
|
+
rubygems_version: 2.6.11
|
248
248
|
signing_key:
|
249
249
|
specification_version: 4
|
250
250
|
summary: Simple HTTP and REST client for Ruby, inspired by microframework syntax for
|
@@ -280,4 +280,3 @@ test_files:
|
|
280
280
|
- spec/unit/restclient_spec.rb
|
281
281
|
- spec/unit/utils_spec.rb
|
282
282
|
- spec/unit/windows/root_certs_spec.rb
|
283
|
-
has_rdoc:
|