rest-client 2.0.0.rc4 → 2.0.2
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.
- 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
|
-
[](https://rubygems.org/gems/rest-client)
|
4
4
|
[](https://travis-ci.org/rest-client/rest-client)
|
5
5
|
[](https://codeclimate.com/github/rest-client/rest-client)
|
6
6
|
[](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:
|