rest-client 1.6.7 → 1.8.0
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 +7 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.travis.yml +14 -0
- data/AUTHORS +81 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.rdoc +63 -24
- data/Rakefile +85 -35
- data/bin/restclient +9 -8
- data/history.md +63 -1
- data/lib/restclient/abstract_response.rb +44 -15
- data/lib/restclient/exceptions.rb +20 -10
- data/lib/restclient/payload.rb +21 -18
- data/lib/restclient/platform.rb +30 -0
- data/lib/restclient/raw_response.rb +3 -2
- data/lib/restclient/request.rb +368 -63
- data/lib/restclient/resource.rb +3 -4
- data/lib/restclient/response.rb +2 -5
- data/lib/restclient/version.rb +7 -0
- data/lib/restclient/windows/root_certs.rb +105 -0
- data/lib/restclient/windows.rb +8 -0
- data/lib/restclient.rb +6 -15
- data/rest-client.gemspec +30 -0
- data/rest-client.windows.gemspec +19 -0
- data/spec/integration/capath_digicert/244b5494.0 +19 -0
- data/spec/integration/capath_digicert/81b9768f.0 +19 -0
- data/spec/integration/capath_digicert/README +8 -0
- data/spec/integration/capath_digicert/digicert.crt +19 -0
- data/spec/integration/capath_verisign/415660c1.0 +14 -0
- data/spec/integration/capath_verisign/7651b327.0 +14 -0
- data/spec/integration/capath_verisign/README +8 -0
- data/spec/integration/capath_verisign/verisign.crt +14 -0
- data/spec/integration/certs/digicert.crt +19 -0
- data/spec/{integration_spec.rb → integration/integration_spec.rb} +10 -13
- data/spec/integration/request_spec.rb +86 -7
- data/spec/spec_helper.rb +2 -0
- data/spec/{abstract_response_spec.rb → unit/abstract_response_spec.rb} +18 -15
- data/spec/{exceptions_spec.rb → unit/exceptions_spec.rb} +17 -20
- data/spec/unit/master_shake.jpg +0 -0
- data/spec/{payload_spec.rb → unit/payload_spec.rb} +42 -31
- data/spec/unit/raw_response_spec.rb +18 -0
- data/spec/{request2_spec.rb → unit/request2_spec.rb} +6 -14
- data/spec/unit/request_spec.rb +917 -0
- data/spec/{resource_spec.rb → unit/resource_spec.rb} +27 -31
- data/spec/{response_spec.rb → unit/response_spec.rb} +63 -57
- data/spec/{restclient_spec.rb → unit/restclient_spec.rb} +8 -2
- data/spec/unit/windows/root_certs_spec.rb +22 -0
- metadata +210 -112
- data/VERSION +0 -1
- data/lib/restclient/net_http_ext.rb +0 -55
- data/spec/base.rb +0 -16
- data/spec/integration/certs/equifax.crt +0 -19
- data/spec/master_shake.jpg +0 -0
- data/spec/raw_response_spec.rb +0 -17
- data/spec/request_spec.rb +0 -529
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'openssl'
|
2
|
+
require 'ffi'
|
3
|
+
|
4
|
+
# Adapted from Puppet, Copyright (c) Puppet Labs Inc,
|
5
|
+
# licensed under the Apache License, Version 2.0.
|
6
|
+
#
|
7
|
+
# https://github.com/puppetlabs/puppet/blob/bbe30e0a/lib/puppet/util/windows/root_certs.rb
|
8
|
+
|
9
|
+
# Represents a collection of trusted root certificates.
|
10
|
+
#
|
11
|
+
# @api public
|
12
|
+
class RestClient::Windows::RootCerts
|
13
|
+
include Enumerable
|
14
|
+
extend FFI::Library
|
15
|
+
|
16
|
+
typedef :ulong, :dword
|
17
|
+
typedef :uintptr_t, :handle
|
18
|
+
|
19
|
+
def initialize(roots)
|
20
|
+
@roots = roots
|
21
|
+
end
|
22
|
+
|
23
|
+
# Enumerates each root certificate.
|
24
|
+
# @yieldparam cert [OpenSSL::X509::Certificate] each root certificate
|
25
|
+
# @api public
|
26
|
+
def each
|
27
|
+
@roots.each {|cert| yield cert}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Returns a new instance.
|
31
|
+
# @return [RestClient::Windows::RootCerts] object constructed from current root certificates
|
32
|
+
def self.instance
|
33
|
+
new(self.load_certs)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns an array of root certificates.
|
37
|
+
#
|
38
|
+
# @return [Array<[OpenSSL::X509::Certificate]>] an array of root certificates
|
39
|
+
# @api private
|
40
|
+
def self.load_certs
|
41
|
+
certs = []
|
42
|
+
|
43
|
+
# This is based on a patch submitted to openssl:
|
44
|
+
# http://www.mail-archive.com/openssl-dev@openssl.org/msg26958.html
|
45
|
+
ptr = FFI::Pointer::NULL
|
46
|
+
store = CertOpenSystemStoreA(nil, "ROOT")
|
47
|
+
begin
|
48
|
+
while (ptr = CertEnumCertificatesInStore(store, ptr)) and not ptr.null?
|
49
|
+
context = CERT_CONTEXT.new(ptr)
|
50
|
+
cert_buf = context[:pbCertEncoded].read_bytes(context[:cbCertEncoded])
|
51
|
+
begin
|
52
|
+
certs << OpenSSL::X509::Certificate.new(cert_buf)
|
53
|
+
rescue => detail
|
54
|
+
warn("Failed to import root certificate: #{detail.inspect}")
|
55
|
+
end
|
56
|
+
end
|
57
|
+
ensure
|
58
|
+
CertCloseStore(store, 0)
|
59
|
+
end
|
60
|
+
|
61
|
+
certs
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# typedef ULONG_PTR HCRYPTPROV_LEGACY;
|
67
|
+
# typedef void *HCERTSTORE;
|
68
|
+
|
69
|
+
class CERT_CONTEXT < FFI::Struct
|
70
|
+
layout(
|
71
|
+
:dwCertEncodingType, :dword,
|
72
|
+
:pbCertEncoded, :pointer,
|
73
|
+
:cbCertEncoded, :dword,
|
74
|
+
:pCertInfo, :pointer,
|
75
|
+
:hCertStore, :handle
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
79
|
+
# HCERTSTORE
|
80
|
+
# WINAPI
|
81
|
+
# CertOpenSystemStoreA(
|
82
|
+
# __in_opt HCRYPTPROV_LEGACY hProv,
|
83
|
+
# __in LPCSTR szSubsystemProtocol
|
84
|
+
# );
|
85
|
+
ffi_lib :crypt32
|
86
|
+
attach_function :CertOpenSystemStoreA, [:pointer, :string], :handle
|
87
|
+
|
88
|
+
# PCCERT_CONTEXT
|
89
|
+
# WINAPI
|
90
|
+
# CertEnumCertificatesInStore(
|
91
|
+
# __in HCERTSTORE hCertStore,
|
92
|
+
# __in_opt PCCERT_CONTEXT pPrevCertContext
|
93
|
+
# );
|
94
|
+
ffi_lib :crypt32
|
95
|
+
attach_function :CertEnumCertificatesInStore, [:handle, :pointer], :pointer
|
96
|
+
|
97
|
+
# BOOL
|
98
|
+
# WINAPI
|
99
|
+
# CertCloseStore(
|
100
|
+
# __in_opt HCERTSTORE hCertStore,
|
101
|
+
# __in DWORD dwFlags
|
102
|
+
# );
|
103
|
+
ffi_lib :crypt32
|
104
|
+
attach_function :CertCloseStore, [:handle, :dword], :bool
|
105
|
+
end
|
data/lib/restclient.rb
CHANGED
@@ -1,14 +1,11 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'openssl'
|
3
|
+
require 'stringio'
|
1
4
|
require 'uri'
|
2
5
|
require 'zlib'
|
3
|
-
require 'stringio'
|
4
|
-
|
5
|
-
begin
|
6
|
-
require 'net/https'
|
7
|
-
rescue LoadError => e
|
8
|
-
raise e unless RUBY_PLATFORM =~ /linux/
|
9
|
-
raise LoadError, "no such file to load -- net/https. Try running apt-get install libopenssl-ruby"
|
10
|
-
end
|
11
6
|
|
7
|
+
require File.dirname(__FILE__) + '/restclient/version'
|
8
|
+
require File.dirname(__FILE__) + '/restclient/platform'
|
12
9
|
require File.dirname(__FILE__) + '/restclient/exceptions'
|
13
10
|
require File.dirname(__FILE__) + '/restclient/request'
|
14
11
|
require File.dirname(__FILE__) + '/restclient/abstract_response'
|
@@ -16,7 +13,7 @@ require File.dirname(__FILE__) + '/restclient/response'
|
|
16
13
|
require File.dirname(__FILE__) + '/restclient/raw_response'
|
17
14
|
require File.dirname(__FILE__) + '/restclient/resource'
|
18
15
|
require File.dirname(__FILE__) + '/restclient/payload'
|
19
|
-
require File.dirname(__FILE__) + '/restclient/
|
16
|
+
require File.dirname(__FILE__) + '/restclient/windows'
|
20
17
|
|
21
18
|
# This module's static methods are the entry point for using the REST client.
|
22
19
|
#
|
@@ -103,12 +100,6 @@ module RestClient
|
|
103
100
|
@@log = create_log log
|
104
101
|
end
|
105
102
|
|
106
|
-
def self.version
|
107
|
-
version_path = File.dirname(__FILE__) + "/../VERSION"
|
108
|
-
return File.read(version_path).chomp if File.file?(version_path)
|
109
|
-
"0.0.0"
|
110
|
-
end
|
111
|
-
|
112
103
|
# Create a log that respond to << like a logger
|
113
104
|
# param can be 'stdout', 'stderr', a string (then we will log to that file) or a logger (then we return it)
|
114
105
|
def self.create_log param
|
data/rest-client.gemspec
ADDED
@@ -0,0 +1,30 @@
|
|
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 -z`.split("\0")
|
15
|
+
s.test_files = `git ls-files -z spec/`.split("\0")
|
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_development_dependency('webmock', '~> 1.4')
|
20
|
+
s.add_development_dependency('rspec', '~> 2.4')
|
21
|
+
s.add_development_dependency('pry')
|
22
|
+
s.add_development_dependency('pry-doc')
|
23
|
+
s.add_development_dependency('rdoc', '>= 2.4.2', '< 5.0')
|
24
|
+
|
25
|
+
s.add_dependency('http-cookie', '>= 1.0.2', '< 2.0')
|
26
|
+
s.add_dependency('mime-types', '>= 1.16', '< 3.0')
|
27
|
+
s.add_dependency('netrc', '~> 0.7')
|
28
|
+
|
29
|
+
s.required_ruby_version = '>= 1.9.2'
|
30
|
+
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,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,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,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,7 +1,4 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'webmock/rspec'
|
4
|
-
include WebMock
|
1
|
+
require 'spec_helper'
|
5
2
|
|
6
3
|
describe RestClient do
|
7
4
|
|
@@ -9,15 +6,15 @@ describe RestClient do
|
|
9
6
|
body = 'abc'
|
10
7
|
stub_request(:get, "www.example.com").to_return(:body => body, :status => 200)
|
11
8
|
response = RestClient.get "www.example.com"
|
12
|
-
response.code.should
|
13
|
-
response.body.should
|
9
|
+
response.code.should eq 200
|
10
|
+
response.body.should eq body
|
14
11
|
end
|
15
12
|
|
16
13
|
it "a simple request with gzipped content" do
|
17
14
|
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' } )
|
18
15
|
response = RestClient.get "www.example.com"
|
19
|
-
response.code.should
|
20
|
-
response.body.should
|
16
|
+
response.code.should eq 200
|
17
|
+
response.body.should eq "i'm gziped\n"
|
21
18
|
end
|
22
19
|
|
23
20
|
it "a 404" do
|
@@ -27,12 +24,12 @@ describe RestClient do
|
|
27
24
|
RestClient.get "www.example.com"
|
28
25
|
raise
|
29
26
|
rescue RestClient::ResourceNotFound => e
|
30
|
-
e.http_code.should
|
31
|
-
e.response.code.should
|
32
|
-
e.response.body.should
|
33
|
-
e.http_body.should
|
27
|
+
e.http_code.should eq 404
|
28
|
+
e.response.code.should eq 404
|
29
|
+
e.response.body.should eq body
|
30
|
+
e.http_body.should eq body
|
34
31
|
end
|
35
32
|
end
|
36
33
|
|
37
34
|
|
38
|
-
end
|
35
|
+
end
|
@@ -1,25 +1,104 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
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
|
-
:url => 'https://www.mozilla.
|
9
|
-
:
|
10
|
-
|
16
|
+
:url => 'https://www.mozilla.org',
|
17
|
+
:ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "digicert.crt")
|
18
|
+
)
|
19
|
+
expect { request.execute }.to_not raise_error
|
20
|
+
end
|
21
|
+
|
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")
|
11
27
|
)
|
12
28
|
expect { request.execute }.to_not raise_error
|
13
29
|
end
|
14
30
|
|
15
|
-
|
31
|
+
# TODO: deprecate and remove RestClient::SSLCertificateNotVerified and just
|
32
|
+
# pass through OpenSSL::SSL::SSLError directly. See note in
|
33
|
+
# lib/restclient/request.rb.
|
34
|
+
#
|
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
|
16
38
|
request = RestClient::Request.new(
|
17
39
|
:method => :get,
|
18
|
-
:url => 'https://www.mozilla.
|
19
|
-
:verify_ssl => OpenSSL::SSL::VERIFY_PEER,
|
40
|
+
:url => 'https://www.mozilla.org',
|
20
41
|
:ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt")
|
21
42
|
)
|
22
43
|
expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
|
23
44
|
end
|
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
|
+
|
66
|
+
it "executes the verify_callback" do
|
67
|
+
ran_callback = false
|
68
|
+
request = RestClient::Request.new(
|
69
|
+
:method => :get,
|
70
|
+
:url => 'https://www.mozilla.org',
|
71
|
+
:verify_ssl => true,
|
72
|
+
:ssl_verify_callback => lambda { |preverify_ok, store_ctx|
|
73
|
+
ran_callback = true
|
74
|
+
preverify_ok
|
75
|
+
},
|
76
|
+
)
|
77
|
+
expect {request.execute }.to_not raise_error
|
78
|
+
ran_callback.should eq(true)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "fails verification when the callback returns false",
|
82
|
+
:unless => RestClient::Platform.mac_mri? do
|
83
|
+
request = RestClient::Request.new(
|
84
|
+
:method => :get,
|
85
|
+
:url => 'https://www.mozilla.org',
|
86
|
+
:verify_ssl => true,
|
87
|
+
:ssl_verify_callback => lambda { |preverify_ok, store_ctx| false },
|
88
|
+
)
|
89
|
+
expect { request.execute }.to raise_error(RestClient::SSLCertificateNotVerified)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "succeeds verification when the callback returns true",
|
93
|
+
:unless => RestClient::Platform.mac_mri? do
|
94
|
+
request = RestClient::Request.new(
|
95
|
+
:method => :get,
|
96
|
+
:url => 'https://www.mozilla.org',
|
97
|
+
:verify_ssl => true,
|
98
|
+
:ssl_ca_file => File.join(File.dirname(__FILE__), "certs", "verisign.crt"),
|
99
|
+
:ssl_verify_callback => lambda { |preverify_ok, store_ctx| true },
|
100
|
+
)
|
101
|
+
expect { request.execute }.to_not raise_error
|
102
|
+
end
|
24
103
|
end
|
25
104
|
end
|
data/spec/spec_helper.rb
ADDED
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe RestClient::AbstractResponse do
|
4
4
|
|
@@ -8,63 +8,66 @@ describe RestClient::AbstractResponse do
|
|
8
8
|
|
9
9
|
attr_accessor :size
|
10
10
|
|
11
|
-
def initialize net_http_res, args
|
11
|
+
def initialize net_http_res, args, request
|
12
12
|
@net_http_res = net_http_res
|
13
13
|
@args = args
|
14
|
+
@request = request
|
14
15
|
end
|
15
16
|
|
16
17
|
end
|
17
18
|
|
18
19
|
before do
|
19
|
-
@net_http_res =
|
20
|
-
@
|
20
|
+
@net_http_res = double('net http response')
|
21
|
+
@request = double('restclient request', :url => 'http://example.com')
|
22
|
+
@response = MyAbstractResponse.new(@net_http_res, {}, @request)
|
21
23
|
end
|
22
24
|
|
23
25
|
it "fetches the numeric response code" do
|
24
26
|
@net_http_res.should_receive(:code).and_return('200')
|
25
|
-
@response.code.should
|
27
|
+
@response.code.should eq 200
|
26
28
|
end
|
27
29
|
|
28
30
|
it "has a nice description" do
|
29
31
|
@net_http_res.should_receive(:to_hash).and_return({'Content-Type' => ['application/pdf']})
|
30
32
|
@net_http_res.should_receive(:code).and_return('200')
|
31
|
-
@response.description
|
33
|
+
@response.description.should eq "200 OK | application/pdf bytes\n"
|
32
34
|
end
|
33
35
|
|
34
36
|
it "beautifies the headers by turning the keys to symbols" do
|
35
37
|
h = RestClient::AbstractResponse.beautify_headers('content-type' => [ 'x' ])
|
36
|
-
h.keys.first.should
|
38
|
+
h.keys.first.should eq :content_type
|
37
39
|
end
|
38
40
|
|
39
41
|
it "beautifies the headers by turning the values to strings instead of one-element arrays" do
|
40
42
|
h = RestClient::AbstractResponse.beautify_headers('x' => [ 'text/html' ] )
|
41
|
-
h.values.first.should
|
43
|
+
h.values.first.should eq 'text/html'
|
42
44
|
end
|
43
45
|
|
44
46
|
it "fetches the headers" do
|
45
47
|
@net_http_res.should_receive(:to_hash).and_return('content-type' => [ 'text/html' ])
|
46
|
-
@response.headers.should
|
48
|
+
@response.headers.should eq({ :content_type => 'text/html' })
|
47
49
|
end
|
48
50
|
|
49
51
|
it "extracts cookies from response headers" do
|
50
52
|
@net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=1; path=/'])
|
51
|
-
@response.cookies.should
|
53
|
+
@response.cookies.should eq({ 'session_id' => '1' })
|
52
54
|
end
|
53
55
|
|
54
56
|
it "extract strange cookies" do
|
55
57
|
@net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=ZJ/HQVH6YE+rVkTpn0zvTQ==; path=/'])
|
56
|
-
@response.
|
58
|
+
@response.headers.should eq({:set_cookie => ['session_id=ZJ/HQVH6YE+rVkTpn0zvTQ==; path=/']})
|
59
|
+
@response.cookies.should eq({ 'session_id' => 'ZJ/HQVH6YE+rVkTpn0zvTQ==' })
|
57
60
|
end
|
58
61
|
|
59
62
|
it "doesn't escape cookies" do
|
60
63
|
@net_http_res.should_receive(:to_hash).and_return('set-cookie' => ['session_id=BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca; path=/'])
|
61
|
-
@response.cookies.should
|
64
|
+
@response.cookies.should eq({ 'session_id' => 'BAh7BzoNYXBwX25hbWUiEGFwcGxpY2F0aW9uOgpsb2dpbiIKYWRtaW4%3D%0A--08114ba654f17c04d20dcc5228ec672508f738ca' })
|
62
65
|
end
|
63
66
|
|
64
67
|
it "can access the net http result directly" do
|
65
|
-
@response.net_http_res.should
|
68
|
+
@response.net_http_res.should eq @net_http_res
|
66
69
|
end
|
67
|
-
|
70
|
+
|
68
71
|
describe "#return!" do
|
69
72
|
it "should return the response itself on 200-codes" do
|
70
73
|
@net_http_res.should_receive(:code).and_return('200')
|
@@ -75,7 +78,7 @@ describe RestClient::AbstractResponse do
|
|
75
78
|
@net_http_res.should_receive(:code).and_return('1000')
|
76
79
|
lambda { @response.return! }.should raise_error RestClient::RequestFailed
|
77
80
|
end
|
78
|
-
|
81
|
+
|
79
82
|
it "should raise an error on a redirection after non-GET/HEAD requests" do
|
80
83
|
@net_http_res.should_receive(:code).and_return('301')
|
81
84
|
@response.args.merge(:method => :put)
|