rest-client 1.6.14 → 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.
Files changed (65) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +6 -6
  3. data/.rspec +2 -1
  4. data/.rubocop-disables.yml +384 -0
  5. data/.rubocop.yml +3 -0
  6. data/.travis.yml +46 -1
  7. data/AUTHORS +28 -5
  8. data/Gemfile +5 -1
  9. data/LICENSE +21 -0
  10. data/README.md +784 -0
  11. data/Rakefile +95 -12
  12. data/bin/restclient +11 -12
  13. data/history.md +180 -16
  14. data/lib/restclient.rb +25 -11
  15. data/lib/restclient/abstract_response.rb +171 -51
  16. data/lib/restclient/exceptions.rb +102 -56
  17. data/lib/restclient/params_array.rb +72 -0
  18. data/lib/restclient/payload.rb +43 -74
  19. data/lib/restclient/platform.rb +22 -2
  20. data/lib/restclient/raw_response.rb +7 -3
  21. data/lib/restclient/request.rb +672 -179
  22. data/lib/restclient/resource.rb +6 -7
  23. data/lib/restclient/response.rb +64 -10
  24. data/lib/restclient/utils.rb +235 -0
  25. data/lib/restclient/version.rb +2 -1
  26. data/lib/restclient/windows.rb +8 -0
  27. data/lib/restclient/windows/root_certs.rb +105 -0
  28. data/rest-client.gemspec +16 -11
  29. data/rest-client.windows.gemspec +19 -0
  30. data/spec/helpers.rb +22 -0
  31. data/spec/integration/_lib.rb +1 -0
  32. data/spec/integration/capath_verisign/415660c1.0 +14 -0
  33. data/spec/integration/capath_verisign/7651b327.0 +14 -0
  34. data/spec/integration/capath_verisign/README +8 -0
  35. data/spec/integration/capath_verisign/verisign.crt +14 -0
  36. data/spec/integration/httpbin_spec.rb +87 -0
  37. data/spec/integration/integration_spec.rb +125 -0
  38. data/spec/integration/request_spec.rb +72 -20
  39. data/spec/spec_helper.rb +29 -0
  40. data/spec/unit/_lib.rb +1 -0
  41. data/spec/unit/abstract_response_spec.rb +145 -0
  42. data/spec/unit/exceptions_spec.rb +108 -0
  43. data/spec/{master_shake.jpg → unit/master_shake.jpg} +0 -0
  44. data/spec/unit/params_array_spec.rb +36 -0
  45. data/spec/{payload_spec.rb → unit/payload_spec.rb} +73 -54
  46. data/spec/{raw_response_spec.rb → unit/raw_response_spec.rb} +5 -4
  47. data/spec/unit/request2_spec.rb +54 -0
  48. data/spec/unit/request_spec.rb +1250 -0
  49. data/spec/unit/resource_spec.rb +134 -0
  50. data/spec/unit/response_spec.rb +241 -0
  51. data/spec/unit/restclient_spec.rb +79 -0
  52. data/spec/unit/utils_spec.rb +147 -0
  53. data/spec/unit/windows/root_certs_spec.rb +22 -0
  54. metadata +143 -53
  55. data/README.rdoc +0 -300
  56. data/lib/restclient/net_http_ext.rb +0 -55
  57. data/spec/abstract_response_spec.rb +0 -85
  58. data/spec/base.rb +0 -13
  59. data/spec/exceptions_spec.rb +0 -98
  60. data/spec/integration_spec.rb +0 -38
  61. data/spec/request2_spec.rb +0 -35
  62. data/spec/request_spec.rb +0 -528
  63. data/spec/resource_spec.rb +0 -136
  64. data/spec/response_spec.rb +0 -169
  65. data/spec/restclient_spec.rb +0 -73
@@ -1,6 +1,6 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
- require File.expand_path("../lib/restclient/version", __FILE__)
3
+ require File.expand_path('../lib/restclient/version', __FILE__)
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = 'rest-client'
@@ -10,17 +10,22 @@ Gem::Specification.new do |s|
10
10
  s.license = 'MIT'
11
11
  s.email = 'rest.client@librelist.com'
12
12
  s.executables = ['restclient']
13
- s.extra_rdoc_files = ["README.rdoc", "history.md"]
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- spec/*`.split("\n")
13
+ s.extra_rdoc_files = ['README.md', 'history.md']
14
+ s.files = `git ls-files -z`.split("\0")
15
+ s.test_files = `git ls-files -z spec/`.split("\0")
16
16
  s.homepage = 'https://github.com/rest-client/rest-client'
17
17
  s.summary = 'Simple HTTP and REST client for Ruby, inspired by microframework syntax for specifying actions.'
18
18
 
19
- s.add_dependency(%q<mime-types>, ["~> 1.16"])
20
- s.add_development_dependency(%q<rdoc>, [">= 2.4.2"])
21
- s.add_development_dependency(%q<rake>, ["~> 10.0"])
22
- s.add_development_dependency(%q<webmock>, ["~> 1.4"])
23
- s.add_development_dependency(%q<rspec>, ["~> 2.4"])
24
- s.add_development_dependency(%q<pry>)
25
- end
19
+ s.add_development_dependency('webmock', '~> 2.0')
20
+ s.add_development_dependency('rspec', '~> 3.0')
21
+ s.add_development_dependency('pry', '~> 0')
22
+ s.add_development_dependency('pry-doc', '~> 0')
23
+ s.add_development_dependency('rdoc', '>= 2.4.2', '< 6.0')
24
+ s.add_development_dependency('rubocop', '~> 0')
25
+
26
+ s.add_dependency('http-cookie', '>= 1.0.2', '< 2.0')
27
+ s.add_dependency('mime-types', '>= 1.16', '< 4.0')
28
+ s.add_dependency('netrc', '~> 0.8')
26
29
 
30
+ s.required_ruby_version = '>= 2.0.0'
31
+ end
@@ -0,0 +1,19 @@
1
+ #
2
+ # Gemspec for Windows platforms. We can't put these in the main gemspec because
3
+ # it results in bundler platform hell when trying to build the gem.
4
+ #
5
+ # Set $BUILD_PLATFORM when calling gem build with this gemspec to build for
6
+ # Windows platforms like x86-mingw32.
7
+ #
8
+ s = eval(File.read(File.join(File.dirname(__FILE__), 'rest-client.gemspec')))
9
+
10
+ platform = ENV['BUILD_PLATFORM'] || RUBY_PLATFORM
11
+
12
+ case platform
13
+ when /(mingw32|mswin32)/
14
+ # ffi is needed for RestClient::Windows::RootCerts
15
+ s.add_dependency('ffi', '~> 1.9')
16
+ s.platform = platform
17
+ end
18
+
19
+ s
@@ -0,0 +1,22 @@
1
+ require 'uri'
2
+
3
+ module Helpers
4
+ def response_double(opts={})
5
+ double('response', {:to_hash => {}}.merge(opts))
6
+ end
7
+
8
+ def fake_stderr
9
+ original_stderr = $stderr
10
+ $stderr = StringIO.new
11
+ yield
12
+ $stderr.string
13
+ ensure
14
+ $stderr = original_stderr
15
+ end
16
+
17
+ def request_double(url: 'http://example.com', method: 'get')
18
+ double('request', url: url, uri: URI.parse(url), method: method,
19
+ user: nil, password: nil, cookie_jar: HTTP::CookieJar.new,
20
+ redirection_history: nil, args: {url: url, method: method})
21
+ end
22
+ end
@@ -0,0 +1 @@
1
+ require_relative '../spec_helper'
@@ -0,0 +1,14 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
3
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
4
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
5
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
6
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
7
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
8
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
9
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
10
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
11
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
12
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
13
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
14
+ -----END CERTIFICATE-----
@@ -0,0 +1,14 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
3
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
4
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
5
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
6
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
7
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
8
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
9
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
10
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
11
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
12
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
13
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
14
+ -----END CERTIFICATE-----
@@ -0,0 +1,8 @@
1
+ The CA path symlinks can be created by c_rehash(1ssl).
2
+
3
+ But in order for the tests to work on Windows, they have to be regular files.
4
+ You can turn them all into regular files by running this on a GNU system:
5
+
6
+ for file in $(find . -type l); do
7
+ cp -iv --remove-destination $(readlink -e $file) $file
8
+ done
@@ -0,0 +1,14 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
3
+ A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
4
+ cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
5
+ MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
6
+ BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
7
+ YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
8
+ ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
9
+ BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
10
+ I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
11
+ CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
12
+ lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
13
+ AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
14
+ -----END CERTIFICATE-----
@@ -0,0 +1,87 @@
1
+ require_relative '_lib'
2
+ require 'json'
3
+
4
+ describe RestClient::Request do
5
+ before(:all) do
6
+ WebMock.disable!
7
+ end
8
+
9
+ after(:all) do
10
+ WebMock.enable!
11
+ end
12
+
13
+ def default_httpbin_url
14
+ # add a hack to work around java/jruby bug
15
+ # java.lang.RuntimeException: Could not generate DH keypair with backtrace
16
+ # Also (2017-04-09) Travis Jruby versions have a broken CA keystore
17
+ if ENV['TRAVIS_RUBY_VERSION'] =~ /\Ajruby-/
18
+ 'http://httpbin.org/'
19
+ else
20
+ 'https://httpbin.org/'
21
+ end
22
+ end
23
+
24
+ def httpbin(suffix='')
25
+ url = ENV.fetch('HTTPBIN_URL', default_httpbin_url)
26
+ unless url.end_with?('/')
27
+ url += '/'
28
+ end
29
+
30
+ url + suffix
31
+ end
32
+
33
+ def execute_httpbin(suffix, opts={})
34
+ opts = {url: httpbin(suffix)}.merge(opts)
35
+ RestClient::Request.execute(opts)
36
+ end
37
+
38
+ def execute_httpbin_json(suffix, opts={})
39
+ JSON.parse(execute_httpbin(suffix, opts))
40
+ end
41
+
42
+ describe '.execute' do
43
+ it 'sends a user agent' do
44
+ data = execute_httpbin_json('user-agent', method: :get)
45
+ expect(data['user-agent']).to match(/rest-client/)
46
+ end
47
+
48
+ it 'receives cookies on 302' do
49
+ expect {
50
+ execute_httpbin('cookies/set?foo=bar', method: :get, max_redirects: 0)
51
+ }.to raise_error(RestClient::Found) { |ex|
52
+ expect(ex.http_code).to eq 302
53
+ expect(ex.response.cookies['foo']).to eq 'bar'
54
+ }
55
+ end
56
+
57
+ it 'passes along cookies through 302' do
58
+ data = execute_httpbin_json('cookies/set?foo=bar', method: :get)
59
+ expect(data).to have_key('cookies')
60
+ expect(data['cookies']['foo']).to eq 'bar'
61
+ end
62
+
63
+ it 'handles quote wrapped cookies' do
64
+ expect {
65
+ execute_httpbin('cookies/set?foo=' + CGI.escape('"bar:baz"'),
66
+ method: :get, max_redirects: 0)
67
+ }.to raise_error(RestClient::Found) { |ex|
68
+ expect(ex.http_code).to eq 302
69
+ expect(ex.response.cookies['foo']).to eq '"bar:baz"'
70
+ }
71
+ end
72
+
73
+ it 'sends basic auth' do
74
+ user = 'user'
75
+ pass = 'pass'
76
+
77
+ data = execute_httpbin_json("basic-auth/#{user}/#{pass}", method: :get, user: user, password: pass)
78
+ expect(data).to eq({'authenticated' => true, 'user' => user})
79
+
80
+ expect {
81
+ execute_httpbin_json("basic-auth/#{user}/#{pass}", method: :get, user: user, password: 'badpass')
82
+ }.to raise_error(RestClient::Unauthorized) { |ex|
83
+ expect(ex.http_code).to eq 401
84
+ }
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,125 @@
1
+ # -*- coding: utf-8 -*-
2
+ require_relative '_lib'
3
+ require 'base64'
4
+
5
+ describe RestClient do
6
+
7
+ it "a simple request" do
8
+ body = 'abc'
9
+ stub_request(:get, "www.example.com").to_return(:body => body, :status => 200)
10
+ response = RestClient.get "www.example.com"
11
+ expect(response.code).to eq 200
12
+ expect(response.body).to eq body
13
+ end
14
+
15
+ it "a simple request with gzipped content" do
16
+ stub_request(:get, "www.example.com").with(:headers => { 'Accept-Encoding' => 'gzip, deflate' }).to_return(:body => "\037\213\b\b\006'\252H\000\003t\000\313T\317UH\257\312,HM\341\002\000G\242(\r\v\000\000\000", :status => 200, :headers => { 'Content-Encoding' => 'gzip' } )
17
+ response = RestClient.get "www.example.com"
18
+ expect(response.code).to eq 200
19
+ expect(response.body).to eq "i'm gziped\n"
20
+ end
21
+
22
+ it "a 404" do
23
+ body = "Ho hai ! I'm not here !"
24
+ stub_request(:get, "www.example.com").to_return(:body => body, :status => 404)
25
+ begin
26
+ RestClient.get "www.example.com"
27
+ raise
28
+ rescue RestClient::ResourceNotFound => e
29
+ expect(e.http_code).to eq 404
30
+ expect(e.response.code).to eq 404
31
+ expect(e.response.body).to eq body
32
+ expect(e.http_body).to eq body
33
+ end
34
+ end
35
+
36
+ describe 'charset parsing' do
37
+ it 'handles utf-8' do
38
+ body = "λ".force_encoding('ASCII-8BIT')
39
+ stub_request(:get, "www.example.com").to_return(
40
+ :body => body, :status => 200, :headers => {
41
+ 'Content-Type' => 'text/plain; charset=UTF-8'
42
+ })
43
+ response = RestClient.get "www.example.com"
44
+ expect(response.encoding).to eq Encoding::UTF_8
45
+ expect(response.valid_encoding?).to eq true
46
+ end
47
+
48
+ it 'handles windows-1252' do
49
+ body = "\xff".force_encoding('ASCII-8BIT')
50
+ stub_request(:get, "www.example.com").to_return(
51
+ :body => body, :status => 200, :headers => {
52
+ 'Content-Type' => 'text/plain; charset=windows-1252'
53
+ })
54
+ response = RestClient.get "www.example.com"
55
+ expect(response.encoding).to eq Encoding::WINDOWS_1252
56
+ expect(response.encode('utf-8')).to eq "ÿ"
57
+ expect(response.valid_encoding?).to eq true
58
+ end
59
+
60
+ it 'handles binary' do
61
+ body = "\xfe".force_encoding('ASCII-8BIT')
62
+ stub_request(:get, "www.example.com").to_return(
63
+ :body => body, :status => 200, :headers => {
64
+ 'Content-Type' => 'application/octet-stream; charset=binary'
65
+ })
66
+ response = RestClient.get "www.example.com"
67
+ expect(response.encoding).to eq Encoding::BINARY
68
+ expect {
69
+ response.encode('utf-8')
70
+ }.to raise_error(Encoding::UndefinedConversionError)
71
+ expect(response.valid_encoding?).to eq true
72
+ end
73
+
74
+ it 'handles euc-jp' do
75
+ body = "\xA4\xA2\xA4\xA4\xA4\xA6\xA4\xA8\xA4\xAA".
76
+ force_encoding(Encoding::BINARY)
77
+ body_utf8 = 'あいうえお'
78
+ expect(body_utf8.encoding).to eq Encoding::UTF_8
79
+
80
+ stub_request(:get, 'www.example.com').to_return(
81
+ :body => body, :status => 200, :headers => {
82
+ 'Content-Type' => 'text/plain; charset=EUC-JP'
83
+ })
84
+ response = RestClient.get 'www.example.com'
85
+ expect(response.encoding).to eq Encoding::EUC_JP
86
+ expect(response.valid_encoding?).to eq true
87
+ expect(response.length).to eq 5
88
+ expect(response.encode('utf-8')).to eq body_utf8
89
+ end
90
+
91
+ it 'defaults to the default encoding' do
92
+ stub_request(:get, 'www.example.com').to_return(
93
+ body: 'abc', status: 200, headers: {
94
+ 'Content-Type' => 'text/plain'
95
+ })
96
+
97
+ response = RestClient.get 'www.example.com'
98
+ # expect(response.encoding).to eq Encoding.default_external
99
+ expect(response.encoding).to eq Encoding::UTF_8
100
+ end
101
+
102
+ it 'handles invalid encoding' do
103
+ stub_request(:get, 'www.example.com').to_return(
104
+ body: 'abc', status: 200, headers: {
105
+ 'Content-Type' => 'text; charset=plain'
106
+ })
107
+
108
+ response = RestClient.get 'www.example.com'
109
+ # expect(response.encoding).to eq Encoding.default_external
110
+ expect(response.encoding).to eq Encoding::UTF_8
111
+ end
112
+
113
+ it 'leaves images as binary' do
114
+ gif = Base64.strict_decode64('R0lGODlhAQABAAAAADs=')
115
+
116
+ stub_request(:get, 'www.example.com').to_return(
117
+ body: gif, status: 200, headers: {
118
+ 'Content-Type' => 'image/gif'
119
+ })
120
+
121
+ response = RestClient.get 'www.example.com'
122
+ expect(response.encoding).to eq Encoding::BINARY
123
+ end
124
+ end
125
+ end
@@ -1,37 +1,68 @@
1
- require File.join( File.dirname(File.expand_path(__FILE__)), '../base')
1
+ require_relative '_lib'
2
2
 
3
3
  describe RestClient::Request do
4
+ before(:all) do
5
+ WebMock.disable!
6
+ end
7
+
8
+ after(:all) do
9
+ WebMock.enable!
10
+ end
11
+
4
12
  describe "ssl verification" do
5
13
  it "is successful with the correct ca_file" do
6
14
  request = RestClient::Request.new(
7
15
  :method => :get,
8
16
  :url => 'https://www.mozilla.org',
9
- :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
10
17
  :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
11
18
  )
12
19
  expect { request.execute }.to_not raise_error
13
20
  end
14
21
 
15
- # I don' think this feature is useful anymore (under 1.9.3 at the very least).
16
- #
17
- # Exceptions in verify_callback are ignored; RestClient has to catch OpenSSL::SSL::SSLError
18
- # and either re-throw it as is, or throw SSLCertificateNotVerified
19
- # based on the contents of the message field of the original exception
20
- #.
21
- # The client has to handle OpenSSL::SSL::SSLError exceptions anyway,
22
- # why make them handle both OpenSSL *AND* RestClient exceptions???
22
+ it "is successful with the correct ca_path" do
23
+ request = RestClient::Request.new(
24
+ :method => :get,
25
+ :url => 'https://www.mozilla.org',
26
+ :ssl_ca_path => File.join(File.dirname(__FILE__), "capath_digicert")
27
+ )
28
+ expect { request.execute }.to_not raise_error
29
+ end
30
+
31
+ # TODO: deprecate and remove RestClient::SSLCertificateNotVerified and just
32
+ # pass through OpenSSL::SSL::SSLError directly. See note in
33
+ # lib/restclient/request.rb.
23
34
  #
24
- # also see https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L237
25
- it "is unsuccessful with an incorrect ca_file" do
35
+ # On OS X, this test fails since Apple has patched OpenSSL to always fall
36
+ # back on the system CA store.
37
+ it "is unsuccessful with an incorrect ca_file", :unless => RestClient::Platform.mac_mri? do
26
38
  request = RestClient::Request.new(
27
39
  :method => :get,
28
- :url => 'https://www.mozilla.com',
29
- :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
40
+ :url => 'https://www.mozilla.org',
30
41
  :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt")
31
42
  )
32
43
  expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
33
44
  end
34
45
 
46
+ # On OS X, this test fails since Apple has patched OpenSSL to always fall
47
+ # back on the system CA store.
48
+ it "is unsuccessful with an incorrect ca_path", :unless => RestClient::Platform.mac_mri? do
49
+ request = RestClient::Request.new(
50
+ :method => :get,
51
+ :url => 'https://www.mozilla.org',
52
+ :ssl_ca_path => File.join(File.dirname(__FILE__), "capath_verisign")
53
+ )
54
+ expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
55
+ end
56
+
57
+ it "is successful using the default system cert store" do
58
+ request = RestClient::Request.new(
59
+ :method => :get,
60
+ :url => 'https://www.mozilla.org',
61
+ :verify_ssl => true,
62
+ )
63
+ expect {request.execute }.to_not raise_error
64
+ end
65
+
35
66
  it "executes the verify_callback" do
36
67
  ran_callback = false
37
68
  request = RestClient::Request.new(
@@ -42,34 +73,55 @@ describe RestClient::Request do
42
73
  ran_callback = true
43
74
  preverify_ok
44
75
  },
45
- :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
46
76
  )
47
77
  expect {request.execute }.to_not raise_error
48
- ran_callback.should eq(true)
78
+ expect(ran_callback).to eq(true)
49
79
  end
50
80
 
51
81
  it "fails verification when the callback returns false",
52
- :unless => RestClient::Platform.mac? do
82
+ :unless => RestClient::Platform.mac_mri? do
53
83
  request = RestClient::Request.new(
54
84
  :method => :get,
55
85
  :url => 'https://www.mozilla.org',
56
86
  :verify_ssl => true,
57
87
  :ssl_verify_callback => lambda { |preverify_ok, store_ctx| false },
58
- :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
59
88
  )
60
89
  expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
61
90
  end
62
91
 
63
92
  it "succeeds verification when the callback returns true",
64
- :unless => RestClient::Platform.mac? do
93
+ :unless => RestClient::Platform.mac_mri? do
65
94
  request = RestClient::Request.new(
66
95
  :method => :get,
67
96
  :url => 'https://www.mozilla.org',
68
97
  :verify_ssl => true,
69
98
  :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt"),
70
- :ssl_verify_callback => lambda { |preverify_ok, store_ctx| true }
99
+ :ssl_verify_callback => lambda { |preverify_ok, store_ctx| true },
71
100
  )
72
101
  expect { request.execute }.to_not raise_error
73
102
  end
74
103
  end
104
+
105
+ describe "timeouts" do
106
+ it "raises OpenTimeout when it hits an open timeout" do
107
+ request = RestClient::Request.new(
108
+ :method => :get,
109
+ :url => 'http://www.mozilla.org',
110
+ :open_timeout => 1e-10,
111
+ )
112
+ expect { request.execute }.to(
113
+ raise_error(RestClient::Exceptions::OpenTimeout))
114
+ end
115
+
116
+ it "raises ReadTimeout when it hits a read timeout via :read_timeout" do
117
+ request = RestClient::Request.new(
118
+ :method => :get,
119
+ :url => 'https://www.mozilla.org',
120
+ :read_timeout => 1e-10,
121
+ )
122
+ expect { request.execute }.to(
123
+ raise_error(RestClient::Exceptions::ReadTimeout))
124
+ end
125
+ end
126
+
75
127
  end