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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 68b80b5b33ba926c8c3a2b4c0aac27b4e7f756f0
4
- data.tar.gz: ba56b4b86dc27028889674a840132c6f88671f9f
3
+ metadata.gz: 10312217af6f5a0312bdce748c8fd82f428fce64
4
+ data.tar.gz: 67846732a7926b335a7082eb1fba0b7178f0c5c4
5
5
  SHA512:
6
- metadata.gz: c83b06c417fd471f0c80ad5a7f93c645a5748ebec48785269c8af59e198c8cb9b7b6b52c0c36be48c6c9c0cee61e9faacafe5e4012ca8be655b0edf739d0b799
7
- data.tar.gz: cea931e95b38351d4c6236189fbb781a1f2e0067eb95e3d65d94bae1eddeff7217158d1a3ca5875747371d7ceb5cd98fe2cb3fd0e189ed0db322cc913c1428b8
6
+ metadata.gz: 56d9d3140ee5418e9b4e877e9756bbb1a1858314c4487b5d7e41ca5fc72f70532f764dcf480c8c3098f4297025fa66c7d8db0bd890e9ae46459e7478a34a685a
7
+ data.tar.gz: 812f11c8a6c2c4ac5ec68852e75f64ae2d7416ae4683f5ff6525055dbf8e472baed3cc01a85eb76e5da2cb39233ff2dc2129cbdab7165dec89637987b346359b
@@ -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" # latest 2.2.x
11
- - "2.3.1" # TODO: switch to "2.3" once travis fixes it
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-04)
37
+ # (last tested: 2016-11)
24
38
  matrix:
25
- exclude:
26
- - os: osx
27
- rvm: '2.2'
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
- - os: osx
36
- rvm: 'jruby-9.0.5.0'
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/rails.svg)](https://rubygems.org/gems/rest-client)
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', {:params => {:id => 50, 'foo' => 'bar'}}
100
+ RestClient.get 'http://example.com/resource', {params: {id: 50, 'foo' => 'bar'}}
55
101
 
56
- RestClient.get 'https://user:password@example.com/private/resource', {:accept => :json}
102
+ RestClient.get 'https://user:password@example.com/private/resource', {accept: :json}
57
103
 
58
- RestClient.post 'http://example.com/resource', :param1 => 'one', :nested => { :param2 => 'two' }
104
+ RestClient.post 'http://example.com/resource', {param1: 'one', nested: {param2: 'two'}}
59
105
 
60
- RestClient.post "http://example.com/resource", { 'x' => 1 }.to_json, :content_type => :json, :accept => :json
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
- response.code
66
- 200
67
- response.cookies
68
- {"Foo"=>"BAR", "QUUX"=>"QUUUUX"}
69
- response.headers
70
- {:content_type=>"text/html; charset=utf-8", :cache_control=>"private" ...
71
- response.to_str
72
- \n<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n \"http://www.w3.org/TR/html4/strict.dtd\">\n\n<html ....
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::Exception` holding the Response will be raised; a specific exception class will be thrown for known error codes
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/resource'
170
- RestClient::ResourceNotFound: RestClient::ResourceNotFound
216
+ >> RestClient.get 'http://example.com/nonexistent'
217
+ Exception: RestClient::NotFound: 404 Not Found
171
218
 
172
- begin
173
- RestClient.get 'http://example.com/resource'
174
- rescue => e
175
- e.response
176
- end
177
- 404 Resource Not Found | text/html 282 bytes
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
- ### Manually following redirection
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/resource'){|response, request, result| response }
251
- 404 Resource Not Found | text/html 282 bytes
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://my-rest-service.com/resource'){ |response, request, result, &block|
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
- RestClient.get('http://my-rest-service.com/resource'){ |response, request, result, &block|
271
- if [301, 302, 307].include? response.code
272
- response.follow_redirection(request, result, &block)
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!(request, result, &block)
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
- | REST Client Team | Andy Brody |
594
- | Creator | Adam Wiggins |
595
- | Maintainers Emeriti | Lawrence Leonard Gilbert, Matthew Manning, Julien Kirch |
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.
@@ -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
- headers.merge!(@payload.headers) if @payload
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
@@ -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 effectively end up using `Encoding.default_external` when
12
- # this method returns nil.
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
  #
@@ -1,5 +1,5 @@
1
1
  module RestClient
2
- VERSION_INFO = [2, 0, 0, 'rc4'] unless defined?(self::VERSION_INFO)
2
+ VERSION_INFO = [2, 0, 2] unless defined?(self::VERSION_INFO)
3
3
  VERSION = VERSION_INFO.map(&:to_s).join('.') unless defined?(self::VERSION)
4
4
 
5
5
  def self.version
@@ -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', '< 5.0')
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
- if ENV['TRAVIS_RUBY_VERSION'] == 'jruby-19mode'
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 Encoding.default_external' do
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
@@ -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(ENV).to receive(:[]).with("NETRC").and_return(nil)
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,
@@ -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
- it "the block should be overrideable in ruby 1.9 syntax" do
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.0.rc4
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: 2016-06-19 00:00:00.000000000 Z
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: '5.0'
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: '5.0'
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: 1.3.1
244
+ version: '0'
245
245
  requirements: []
246
246
  rubyforge_project:
247
- rubygems_version: 2.4.5.1
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: