rest-client 1.6.1 → 1.6.14

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.

Potentially problematic release.


This version of rest-client might be problematic. Click here for more details.

Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +3 -0
  5. data/AUTHORS +75 -0
  6. data/Gemfile +7 -0
  7. data/README.rdoc +52 -21
  8. data/Rakefile +15 -35
  9. data/bin/restclient +45 -39
  10. data/history.md +67 -1
  11. data/lib/restclient.rb +11 -6
  12. data/lib/restclient/abstract_response.rb +6 -2
  13. data/lib/restclient/exceptions.rb +22 -5
  14. data/lib/restclient/net_http_ext.rb +41 -7
  15. data/lib/restclient/payload.rb +28 -8
  16. data/lib/restclient/platform.rb +29 -0
  17. data/lib/restclient/request.rb +96 -36
  18. data/lib/restclient/resource.rb +17 -0
  19. data/lib/restclient/response.rb +3 -1
  20. data/lib/restclient/version.rb +7 -0
  21. data/rest-client.gemspec +26 -0
  22. data/spec/abstract_response_spec.rb +28 -10
  23. data/spec/base.rb +1 -4
  24. data/spec/exceptions_spec.rb +31 -12
  25. data/spec/integration/capath_digicert/244b5494.0 +19 -0
  26. data/spec/integration/capath_digicert/81b9768f.0 +19 -0
  27. data/spec/integration/capath_digicert/README +8 -0
  28. data/spec/integration/capath_digicert/digicert.crt +19 -0
  29. data/spec/integration/certs/digicert.crt +19 -0
  30. data/spec/integration/certs/verisign.crt +14 -14
  31. data/spec/integration/request_spec.rb +54 -4
  32. data/spec/integration_spec.rb +9 -9
  33. data/spec/master_shake.jpg +0 -0
  34. data/spec/payload_spec.rb +60 -35
  35. data/spec/raw_response_spec.rb +4 -4
  36. data/spec/request2_spec.rb +22 -4
  37. data/spec/request_spec.rb +129 -130
  38. data/spec/resource_spec.rb +30 -18
  39. data/spec/response_spec.rb +48 -36
  40. data/spec/restclient_spec.rb +6 -1
  41. metadata +142 -74
  42. data/VERSION +0 -1
  43. data/spec/integration/certs/equifax.crt +0 -19
@@ -54,6 +54,14 @@ module RestClient
54
54
  :headers => headers), &(block || @block))
55
55
  end
56
56
 
57
+ def head(additional_headers={}, &block)
58
+ headers = (options[:headers] || {}).merge(additional_headers)
59
+ Request.execute(options.merge(
60
+ :method => :head,
61
+ :url => url,
62
+ :headers => headers), &(block || @block))
63
+ end
64
+
57
65
  def post(payload, additional_headers={}, &block)
58
66
  headers = (options[:headers] || {}).merge(additional_headers)
59
67
  Request.execute(options.merge(
@@ -72,6 +80,15 @@ module RestClient
72
80
  :headers => headers), &(block || @block))
73
81
  end
74
82
 
83
+ def patch(payload, additional_headers={}, &block)
84
+ headers = (options[:headers] || {}).merge(additional_headers)
85
+ Request.execute(options.merge(
86
+ :method => :patch,
87
+ :url => url,
88
+ :payload => payload,
89
+ :headers => headers), &(block || @block))
90
+ end
91
+
75
92
  def delete(additional_headers={}, &block)
76
93
  headers = (options[:headers] || {}).merge(additional_headers)
77
94
  Request.execute(options.merge(
@@ -6,7 +6,9 @@ module RestClient
6
6
 
7
7
  include AbstractResponse
8
8
 
9
- attr_accessor :args, :body, :net_http_res
9
+ attr_accessor :args, :net_http_res
10
+
11
+ attr_writer :body
10
12
 
11
13
  def body
12
14
  self
@@ -0,0 +1,7 @@
1
+ module RestClient
2
+ VERSION = '1.6.14' unless defined?(self::VERSION)
3
+
4
+ def self.version
5
+ VERSION
6
+ end
7
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ require File.expand_path("../lib/restclient/version", __FILE__)
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'rest-client'
7
+ s.version = RestClient::VERSION
8
+ s.authors = ['REST Client Team']
9
+ s.description = 'A simple HTTP and REST client for Ruby, inspired by the Sinatra microframework style of specifying actions: get, put, post, delete.'
10
+ s.license = 'MIT'
11
+ s.email = 'rest.client@librelist.com'
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")
16
+ s.homepage = 'https://github.com/rest-client/rest-client'
17
+ s.summary = 'Simple HTTP and REST client for Ruby, inspired by microframework syntax for specifying actions.'
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
26
+
@@ -16,52 +16,70 @@ describe RestClient::AbstractResponse do
16
16
  end
17
17
 
18
18
  before do
19
- @net_http_res = mock('net http response')
19
+ @net_http_res = double('net http response')
20
20
  @response = MyAbstractResponse.new(@net_http_res, {})
21
21
  end
22
22
 
23
23
  it "fetches the numeric response code" do
24
24
  @net_http_res.should_receive(:code).and_return('200')
25
- @response.code.should == 200
25
+ @response.code.should eq 200
26
26
  end
27
27
 
28
28
  it "has a nice description" do
29
29
  @net_http_res.should_receive(:to_hash).and_return({'Content-Type' => ['application/pdf']})
30
30
  @net_http_res.should_receive(:code).and_return('200')
31
- @response.description == '200 OK | application/pdf bytes\n'
31
+ @response.description.should eq "200 OK | application/pdf bytes\n"
32
32
  end
33
33
 
34
34
  it "beautifies the headers by turning the keys to symbols" do
35
35
  h = RestClient::AbstractResponse.beautify_headers('content-type' => [ 'x' ])
36
- h.keys.first.should == :content_type
36
+ h.keys.first.should eq :content_type
37
37
  end
38
38
 
39
39
  it "beautifies the headers by turning the values to strings instead of one-element arrays" do
40
40
  h = RestClient::AbstractResponse.beautify_headers('x' => [ 'text/html' ] )
41
- h.values.first.should == 'text/html'
41
+ h.values.first.should eq 'text/html'
42
42
  end
43
43
 
44
44
  it "fetches the headers" do
45
45
  @net_http_res.should_receive(:to_hash).and_return('content-type' => [ 'text/html' ])
46
- @response.headers.should == { :content_type => 'text/html' }
46
+ @response.headers.should eq({ :content_type => 'text/html' })
47
47
  end
48
48
 
49
49
  it "extracts cookies from response headers" do
50
50
  @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
51
- @response.cookies.should == { 'session_id' => '1' }
51
+ @response.cookies.should eq({ 'session_id' => '1' })
52
52
  end
53
53
 
54
54
  it "extract strange cookies" do
55
55
  @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=ZJ/HQVH6YE+rVkTpn0zvTQ==; path=/'])
56
- @response.cookies.should == { 'session_id' => 'ZJ%2FHQVH6YE+rVkTpn0zvTQ%3D%3D' }
56
+ @response.cookies.should eq({ 'session_id' => 'ZJ%2FHQVH6YE+rVkTpn0zvTQ%3D%3D' })
57
57
  end
58
58
 
59
59
  it "doesn't escape cookies" do
60
60
  @net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca; path=/'])
61
- @response.cookies.should == { 'session_id' => 'BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca' }
61
+ @response.cookies.should eq({ 'session_id' => 'BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca' })
62
62
  end
63
63
 
64
64
  it "can access the net http result directly" do
65
- @response.net_http_res.should == @net_http_res
65
+ @response.net_http_res.should eq @net_http_res
66
+ end
67
+
68
+ describe "#return!" do
69
+ it "should return the response itself on 200-codes" do
70
+ @net_http_res.should_receive(:code).and_return('200')
71
+ @response.return!.should be_equal(@response)
72
+ end
73
+
74
+ it "should raise RequestFailed on unknown codes" do
75
+ @net_http_res.should_receive(:code).and_return('1000')
76
+ lambda { @response.return! }.should raise_error RestClient::RequestFailed
77
+ end
78
+
79
+ it "should raise an error on a redirection after non-GET/HEAD requests" do
80
+ @net_http_res.should_receive(:code).and_return('301')
81
+ @response.args.merge(:method => :put)
82
+ lambda { @response.return! }.should raise_error RestClient::RequestFailed
83
+ end
66
84
  end
67
85
  end
@@ -1,11 +1,8 @@
1
1
  def is_ruby_19?
2
- RUBY_VERSION == '1.9.1' or RUBY_VERSION == '1.9.2'
2
+ RUBY_VERSION > '1.9'
3
3
  end
4
4
 
5
- Encoding.default_internal = Encoding.default_external = "ASCII-8BIT" if is_ruby_19?
6
-
7
5
  require 'rubygems'
8
- require 'spec'
9
6
 
10
7
  begin
11
8
  require "ruby-debug"
@@ -1,11 +1,23 @@
1
1
  require File.join( File.dirname(File.expand_path(__FILE__)), 'base')
2
2
 
3
3
  require 'webmock/rspec'
4
- include WebMock
4
+ include WebMock::API
5
5
 
6
6
  describe RestClient::Exception do
7
+ it "returns a 'message' equal to the class name if the message is not set, because 'message' should not be nil" do
8
+ e = RestClient::Exception.new
9
+ e.message.should eq "RestClient::Exception"
10
+ end
11
+
12
+ it "returns the 'message' that was set" do
13
+ e = RestClient::Exception.new
14
+ message = "An explicitly set message"
15
+ e.message = message
16
+ e.message.should eq message
17
+ end
18
+
7
19
  it "sets the exception message to ErrorMessage" do
8
- RestClient::ResourceNotFound.new.message.should == 'Resource Not Found'
20
+ RestClient::ResourceNotFound.new.message.should eq 'Resource Not Found'
9
21
  end
10
22
 
11
23
  it "contains exceptions in RestClient" do
@@ -14,9 +26,16 @@ describe RestClient::Exception do
14
26
  end
15
27
  end
16
28
 
29
+ describe RestClient::ServerBrokeConnection do
30
+ it "should have a default message of 'Server broke connection'" do
31
+ e = RestClient::ServerBrokeConnection.new
32
+ e.message.should eq 'Server broke connection'
33
+ end
34
+ end
35
+
17
36
  describe RestClient::RequestFailed do
18
37
  before do
19
- @response = mock('HTTP Response', :code => '502')
38
+ @response = double('HTTP Response', :code => '502')
20
39
  end
21
40
 
22
41
  it "stores the http response on the exception" do
@@ -24,17 +43,17 @@ describe RestClient::RequestFailed do
24
43
  begin
25
44
  raise RestClient::RequestFailed, response
26
45
  rescue RestClient::RequestFailed => e
27
- e.response.should == response
46
+ e.response.should eq response
28
47
  end
29
48
  end
30
49
 
31
50
  it "http_code convenience method for fetching the code as an integer" do
32
- RestClient::RequestFailed.new(@response).http_code.should == 502
51
+ RestClient::RequestFailed.new(@response).http_code.should eq 502
33
52
  end
34
53
 
35
54
  it "http_body convenience method for fetching the body (decoding when necessary)" do
36
- RestClient::RequestFailed.new(@response).http_code.should == 502
37
- RestClient::RequestFailed.new(@response).message.should == 'HTTP status code 502'
55
+ RestClient::RequestFailed.new(@response).http_code.should eq 502
56
+ RestClient::RequestFailed.new(@response).message.should eq 'HTTP status code 502'
38
57
  end
39
58
 
40
59
  it "shows the status code in the message" do
@@ -48,22 +67,22 @@ describe RestClient::ResourceNotFound do
48
67
  begin
49
68
  raise RestClient::ResourceNotFound, response
50
69
  rescue RestClient::ResourceNotFound => e
51
- e.response.should == response
70
+ e.response.should eq response
52
71
  end
53
72
  end
54
73
  end
55
74
 
56
75
  describe "backwards compatibility" do
57
76
  it "alias RestClient::Request::Redirect to RestClient::Redirect" do
58
- RestClient::Request::Redirect.should == RestClient::Redirect
77
+ RestClient::Request::Redirect.should eq RestClient::Redirect
59
78
  end
60
79
 
61
80
  it "alias RestClient::Request::Unauthorized to RestClient::Unauthorized" do
62
- RestClient::Request::Unauthorized.should == RestClient::Unauthorized
81
+ RestClient::Request::Unauthorized.should eq RestClient::Unauthorized
63
82
  end
64
83
 
65
84
  it "alias RestClient::Request::RequestFailed to RestClient::RequestFailed" do
66
- RestClient::Request::RequestFailed.should == RestClient::RequestFailed
85
+ RestClient::Request::RequestFailed.should eq RestClient::RequestFailed
67
86
  end
68
87
 
69
88
  it "make the exception's response act like an Net::HTTPResponse" do
@@ -73,7 +92,7 @@ describe "backwards compatibility" do
73
92
  RestClient.get "www.example.com"
74
93
  raise
75
94
  rescue RestClient::ResourceNotFound => e
76
- e.response.body.should == body
95
+ e.response.body.should eq body
77
96
  end
78
97
  end
79
98
  end
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
3
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
4
+ KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
5
+ MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
6
+ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
7
+ Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
8
+ Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
9
+ OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
10
+ MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
11
+ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
12
+ h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
13
+ Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
14
+ JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
15
+ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
16
+ myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
17
+ mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
18
+ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
3
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
4
+ KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
5
+ MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
6
+ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
7
+ Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
8
+ Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
9
+ OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
10
+ MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
11
+ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
12
+ h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
13
+ Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
14
+ JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
15
+ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
16
+ myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
17
+ mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
18
+ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
19
+ -----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,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
3
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
4
+ KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
5
+ MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
6
+ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
7
+ Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
8
+ Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
9
+ OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
10
+ MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
11
+ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
12
+ h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
13
+ Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
14
+ JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
15
+ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
16
+ myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
17
+ mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
18
+ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
19
+ -----END CERTIFICATE-----
@@ -0,0 +1,19 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG
3
+ EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw
4
+ KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw
5
+ MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
6
+ MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu
7
+ Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t
8
+ Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS
9
+ OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3
10
+ MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ
11
+ NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe
12
+ h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB
13
+ Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY
14
+ JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ
15
+ V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp
16
+ myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK
17
+ mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
18
+ vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K
19
+ -----END CERTIFICATE-----
@@ -1,14 +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-----
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-----
@@ -5,21 +5,71 @@ describe RestClient::Request do
5
5
  it "is successful with the correct ca_file" do
6
6
  request = RestClient::Request.new(
7
7
  :method => :get,
8
- :url => 'https://www.google.com',
8
+ :url => 'https://www.mozilla.org',
9
9
  :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
10
- :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt")
10
+ :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
11
11
  )
12
12
  expect { request.execute }.to_not raise_error
13
13
  end
14
14
 
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???
23
+ #
24
+ # also see https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L237
15
25
  it "is unsuccessful with an incorrect ca_file" do
16
26
  request = RestClient::Request.new(
17
27
  :method => :get,
18
- :url => 'https://www.google.com',
28
+ :url => 'https://www.mozilla.com',
19
29
  :verify_ssl => OpenSSL::SSL::VERIFY_PEER,
20
- :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "equifax.crt")
30
+ :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt")
21
31
  )
22
32
  expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
23
33
  end
34
+
35
+ it "executes the verify_callback" do
36
+ ran_callback = false
37
+ request = RestClient::Request.new(
38
+ :method => :get,
39
+ :url => 'https://www.mozilla.org',
40
+ :verify_ssl => true,
41
+ :ssl_verify_callback => lambda { |preverify_ok, store_ctx|
42
+ ran_callback = true
43
+ preverify_ok
44
+ },
45
+ :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
46
+ )
47
+ expect {request.execute }.to_not raise_error
48
+ ran_callback.should eq(true)
49
+ end
50
+
51
+ it "fails verification when the callback returns false",
52
+ :unless => RestClient::Platform.mac? do
53
+ request = RestClient::Request.new(
54
+ :method => :get,
55
+ :url => 'https://www.mozilla.org',
56
+ :verify_ssl => true,
57
+ :ssl_verify_callback => lambda { |preverify_ok, store_ctx| false },
58
+ :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
59
+ )
60
+ expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
61
+ end
62
+
63
+ it "succeeds verification when the callback returns true",
64
+ :unless => RestClient::Platform.mac? do
65
+ request = RestClient::Request.new(
66
+ :method => :get,
67
+ :url => 'https://www.mozilla.org',
68
+ :verify_ssl => true,
69
+ :ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt"),
70
+ :ssl_verify_callback => lambda { |preverify_ok, store_ctx| true }
71
+ )
72
+ expect { request.execute }.to_not raise_error
73
+ end
24
74
  end
25
75
  end