rest-client 1.6.14 → 1.7.0.rc1
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.
- checksums.yaml +5 -5
- data/.gitignore +4 -3
- data/.travis.yml +12 -1
- data/AUTHORS +10 -4
- data/Gemfile +5 -1
- data/LICENSE +21 -0
- data/README.rdoc +27 -2
- data/Rakefile +78 -10
- data/bin/restclient +1 -1
- data/history.md +22 -16
- data/lib/restclient.rb +2 -8
- data/lib/restclient/exceptions.rb +7 -2
- data/lib/restclient/platform.rb +2 -1
- data/lib/restclient/request.rb +270 -48
- data/lib/restclient/response.rb +0 -2
- data/lib/restclient/version.rb +1 -1
- data/lib/restclient/windows.rb +8 -0
- data/lib/restclient/windows/root_certs.rb +105 -0
- data/rest-client.gemspec +14 -10
- data/rest-client.windows.gemspec +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_spec.rb → integration/integration_spec.rb} +2 -5
- data/spec/integration/request_spec.rb +46 -17
- data/spec/{base.rb → spec_helper.rb} +2 -3
- data/spec/{abstract_response_spec.rb → unit/abstract_response_spec.rb} +1 -1
- data/spec/{exceptions_spec.rb → unit/exceptions_spec.rb} +1 -4
- data/spec/{master_shake.jpg → unit/master_shake.jpg} +0 -0
- data/spec/{payload_spec.rb → unit/payload_spec.rb} +2 -1
- data/spec/{raw_response_spec.rb → unit/raw_response_spec.rb} +1 -1
- data/spec/{request2_spec.rb → unit/request2_spec.rb} +1 -4
- data/spec/{request_spec.rb → unit/request_spec.rb} +386 -9
- data/spec/{resource_spec.rb → unit/resource_spec.rb} +1 -4
- data/spec/{response_spec.rb → unit/response_spec.rb} +1 -4
- data/spec/{restclient_spec.rb → unit/restclient_spec.rb} +7 -1
- data/spec/unit/windows/root_certs_spec.rb +22 -0
- metadata +93 -58
- data/lib/restclient/net_http_ext.rb +0 -55
data/lib/restclient/response.rb
CHANGED
data/lib/restclient/version.rb
CHANGED
@@ -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/rest-client.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
2
|
|
3
|
-
require File.expand_path(
|
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,21 @@ 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 = [
|
14
|
-
s.files = `git ls-files`.split("\
|
15
|
-
s.test_files = `git ls-files
|
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
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.
|
20
|
-
s.add_development_dependency(
|
21
|
-
s.add_development_dependency(
|
22
|
-
s.add_development_dependency(
|
23
|
-
s.add_development_dependency(
|
24
|
-
|
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('mime-types', '~> 2.0')
|
26
|
+
s.add_dependency('netrc', '~> 0.7')
|
27
|
+
|
28
|
+
s.required_ruby_version = '>= 1.9.2'
|
25
29
|
end
|
26
30
|
|
@@ -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,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-----
|
@@ -1,37 +1,68 @@
|
|
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
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
-
#
|
25
|
-
|
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? do
|
26
38
|
request = RestClient::Request.new(
|
27
39
|
:method => :get,
|
28
|
-
:url => 'https://www.mozilla.
|
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? 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,7 +73,6 @@ 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
78
|
ran_callback.should eq(true)
|
@@ -55,7 +85,6 @@ describe RestClient::Request do
|
|
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
|
@@ -67,7 +96,7 @@ describe RestClient::Request do
|
|
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
|
@@ -2,12 +2,11 @@ def is_ruby_19?
|
|
2
2
|
RUBY_VERSION > '1.9'
|
3
3
|
end
|
4
4
|
|
5
|
-
require 'rubygems'
|
6
|
-
|
7
5
|
begin
|
8
6
|
require "ruby-debug"
|
9
7
|
rescue LoadError
|
10
8
|
# NOP, ignore
|
11
9
|
end
|
12
10
|
|
13
|
-
require
|
11
|
+
require 'webmock/rspec'
|
12
|
+
require 'restclient'
|
@@ -1,7 +1,4 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'webmock/rspec'
|
4
|
-
include WebMock::API
|
1
|
+
require 'spec_helper'
|
5
2
|
|
6
3
|
describe RestClient::Exception do
|
7
4
|
it "returns a 'message' equal to the class name if the message is not set, because 'message' should not be nil" do
|
File without changes
|
@@ -1,7 +1,4 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
require 'webmock/rspec'
|
4
|
-
include WebMock::API
|
1
|
+
require 'spec_helper'
|
5
2
|
|
6
3
|
describe RestClient::Request do
|
7
4
|
before do
|
@@ -18,6 +15,9 @@ describe RestClient::Request do
|
|
18
15
|
@net.stub(:start).and_yield(@http)
|
19
16
|
@net.stub(:use_ssl=)
|
20
17
|
@net.stub(:verify_mode=)
|
18
|
+
@net.stub(:verify_callback=)
|
19
|
+
allow(@net).to receive(:ciphers=)
|
20
|
+
allow(@net).to receive(:cert_store=)
|
21
21
|
RestClient.log = nil
|
22
22
|
end
|
23
23
|
|
@@ -109,6 +109,57 @@ describe RestClient::Request do
|
|
109
109
|
@request.make_headers({}).should eq({ 'Foo' => 'bar', 'Cookie' => 'session_id=1; user_id=someone'})
|
110
110
|
end
|
111
111
|
|
112
|
+
it "does not escape or unescape cookies" do
|
113
|
+
cookie = 'Foo%20:Bar%0A~'
|
114
|
+
@request = RestClient::Request.new(:method => 'get', :url => 'example.com',
|
115
|
+
:cookies => {:test => cookie})
|
116
|
+
@request.should_receive(:default_headers).and_return({'Foo' => 'bar'})
|
117
|
+
@request.make_headers({}).should eq({
|
118
|
+
'Foo' => 'bar',
|
119
|
+
'Cookie' => "test=#{cookie}"
|
120
|
+
})
|
121
|
+
end
|
122
|
+
|
123
|
+
it "rejects cookie names containing invalid characters" do
|
124
|
+
# Cookie validity is something of a mess, but we should reject the worst of
|
125
|
+
# the RFC 6265 (4.1.1) prohibited characters such as control characters.
|
126
|
+
|
127
|
+
['', 'foo=bar', 'foo;bar', "foo\nbar"].each do |cookie_name|
|
128
|
+
lambda {
|
129
|
+
RestClient::Request.new(:method => 'get', :url => 'example.com',
|
130
|
+
:cookies => {cookie_name => 'value'})
|
131
|
+
}.should raise_error(ArgumentError, /\AInvalid cookie name/)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
it "rejects cookie values containing invalid characters" do
|
136
|
+
# Cookie validity is something of a mess, but we should reject the worst of
|
137
|
+
# the RFC 6265 (4.1.1) prohibited characters such as control characters.
|
138
|
+
|
139
|
+
['foo,bar', 'foo;bar', "foo\nbar"].each do |cookie_value|
|
140
|
+
lambda {
|
141
|
+
RestClient::Request.new(:method => 'get', :url => 'example.com',
|
142
|
+
:cookies => {'test' => cookie_value})
|
143
|
+
}.should raise_error(ArgumentError, /\AInvalid cookie value/)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it "uses netrc credentials" do
|
148
|
+
URI.stub(:parse).and_return(double('uri', :user => nil, :password => nil, :host => 'example.com'))
|
149
|
+
Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
|
150
|
+
@request.parse_url_with_auth('http://example.com/resource')
|
151
|
+
@request.user.should eq 'a'
|
152
|
+
@request.password.should eq 'b'
|
153
|
+
end
|
154
|
+
|
155
|
+
it "uses credentials in the url in preference to netrc" do
|
156
|
+
URI.stub(:parse).and_return(double('uri', :user => 'joe%20', :password => 'pass1', :host => 'example.com'))
|
157
|
+
Netrc.stub(:read).and_return('example.com' => ['a', 'b'])
|
158
|
+
@request.parse_url_with_auth('http://joe%20:pass1@example.com/resource')
|
159
|
+
@request.user.should eq 'joe '
|
160
|
+
@request.password.should eq 'pass1'
|
161
|
+
end
|
162
|
+
|
112
163
|
it "determines the Net::HTTP class to instantiate by the method name" do
|
113
164
|
@request.net_http_request_class(:put).should eq Net::HTTP::Put
|
114
165
|
end
|
@@ -129,6 +180,13 @@ describe RestClient::Request do
|
|
129
180
|
headers.should have_key('1')
|
130
181
|
headers['1'].should eq '3'
|
131
182
|
end
|
183
|
+
|
184
|
+
it "converts user headers to string before calling CGI::unescape which fails on non string values" do
|
185
|
+
@request.should_receive(:default_headers).and_return({ '1' => '2' })
|
186
|
+
headers = @request.make_headers('1' => 3)
|
187
|
+
headers.should have_key('1')
|
188
|
+
headers['1'].should eq '3'
|
189
|
+
end
|
132
190
|
end
|
133
191
|
|
134
192
|
describe "header symbols" do
|
@@ -218,6 +276,7 @@ describe RestClient::Request do
|
|
218
276
|
describe "credentials" do
|
219
277
|
it "sets up the credentials prior to the request" do
|
220
278
|
@http.stub(:request)
|
279
|
+
|
221
280
|
@request.stub(:process_result)
|
222
281
|
@request.stub(:response_log)
|
223
282
|
|
@@ -249,6 +308,21 @@ describe RestClient::Request do
|
|
249
308
|
lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::ServerBrokeConnection)
|
250
309
|
end
|
251
310
|
|
311
|
+
it "catches OpenSSL::SSL::SSLError and raise it back without more informative message" do
|
312
|
+
@http.stub(:request).and_raise(OpenSSL::SSL::SSLError)
|
313
|
+
lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(OpenSSL::SSL::SSLError)
|
314
|
+
end
|
315
|
+
|
316
|
+
it "catches Timeout::Error and raise the more informative RequestTimeout" do
|
317
|
+
@http.stub(:request).and_raise(Timeout::Error)
|
318
|
+
lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
|
319
|
+
end
|
320
|
+
|
321
|
+
it "catches Timeout::Error and raise the more informative RequestTimeout" do
|
322
|
+
@http.stub(:request).and_raise(Errno::ETIMEDOUT)
|
323
|
+
lambda { @request.transmit(@uri, 'req', nil) }.should raise_error(RestClient::RequestTimeout)
|
324
|
+
end
|
325
|
+
|
252
326
|
it "class method execute wraps constructor" do
|
253
327
|
req = double("rest request")
|
254
328
|
RestClient::Request.should_receive(:new).with(1 => 2).and_return(req)
|
@@ -351,6 +425,18 @@ describe RestClient::Request do
|
|
351
425
|
end
|
352
426
|
|
353
427
|
describe "timeout" do
|
428
|
+
it "does not set timeouts if not specified" do
|
429
|
+
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload')
|
430
|
+
@http.stub(:request)
|
431
|
+
@request.stub(:process_result)
|
432
|
+
@request.stub(:response_log)
|
433
|
+
|
434
|
+
@net.should_not_receive(:read_timeout=)
|
435
|
+
@net.should_not_receive(:open_timeout=)
|
436
|
+
|
437
|
+
@request.transmit(@uri, 'req', nil)
|
438
|
+
end
|
439
|
+
|
354
440
|
it "set read_timeout" do
|
355
441
|
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => 123)
|
356
442
|
@http.stub(:request)
|
@@ -372,6 +458,33 @@ describe RestClient::Request do
|
|
372
458
|
|
373
459
|
@request.transmit(@uri, 'req', nil)
|
374
460
|
end
|
461
|
+
|
462
|
+
it "disable timeout by setting it to nil" do
|
463
|
+
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => nil, :open_timeout => nil)
|
464
|
+
@http.stub(:request)
|
465
|
+
@request.stub(:process_result)
|
466
|
+
@request.stub(:response_log)
|
467
|
+
|
468
|
+
@net.should_receive(:read_timeout=).with(nil)
|
469
|
+
@net.should_receive(:open_timeout=).with(nil)
|
470
|
+
|
471
|
+
@request.transmit(@uri, 'req', nil)
|
472
|
+
end
|
473
|
+
|
474
|
+
it "deprecated: disable timeout by setting it to -1" do
|
475
|
+
@request = RestClient::Request.new(:method => :put, :url => 'http://some/resource', :payload => 'payload', :timeout => -1, :open_timeout => -1)
|
476
|
+
@http.stub(:request)
|
477
|
+
@request.stub(:process_result)
|
478
|
+
@request.stub(:response_log)
|
479
|
+
|
480
|
+
@request.should_receive(:warn)
|
481
|
+
@net.should_receive(:read_timeout=).with(nil)
|
482
|
+
|
483
|
+
@request.should_receive(:warn)
|
484
|
+
@net.should_receive(:open_timeout=).with(nil)
|
485
|
+
|
486
|
+
@request.transmit(@uri, 'req', nil)
|
487
|
+
end
|
375
488
|
end
|
376
489
|
|
377
490
|
describe "ssl" do
|
@@ -384,11 +497,17 @@ describe RestClient::Request do
|
|
384
497
|
@request.transmit(@uri, 'req', 'payload')
|
385
498
|
end
|
386
499
|
|
387
|
-
it "should default to
|
388
|
-
@request.verify_ssl.should eq
|
500
|
+
it "should default to verifying ssl certificates" do
|
501
|
+
@request.verify_ssl.should eq OpenSSL::SSL::VERIFY_PEER
|
502
|
+
end
|
503
|
+
|
504
|
+
it "should have expected values for VERIFY_PEER and VERIFY_NONE" do
|
505
|
+
OpenSSL::SSL::VERIFY_NONE.should eq(0)
|
506
|
+
OpenSSL::SSL::VERIFY_PEER.should eq(1)
|
389
507
|
end
|
390
508
|
|
391
509
|
it "should set net.verify_mode to OpenSSL::SSL::VERIFY_NONE if verify_ssl is false" do
|
510
|
+
@request = RestClient::Request.new(:method => :put, :verify_ssl => false, :url => 'http://some/resource', :payload => 'payload')
|
392
511
|
@net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_NONE)
|
393
512
|
@http.stub(:request)
|
394
513
|
@request.stub(:process_result)
|
@@ -405,6 +524,24 @@ describe RestClient::Request do
|
|
405
524
|
@request.transmit(@uri, 'req', 'payload')
|
406
525
|
end
|
407
526
|
|
527
|
+
it "should set net.verify_mode to OpenSSL::SSL::VERIFY_PEER if verify_ssl is true" do
|
528
|
+
@request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload', :verify_ssl => true)
|
529
|
+
@net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
530
|
+
@http.stub(:request)
|
531
|
+
@request.stub(:process_result)
|
532
|
+
@request.stub(:response_log)
|
533
|
+
@request.transmit(@uri, 'req', 'payload')
|
534
|
+
end
|
535
|
+
|
536
|
+
it "should set net.verify_mode to OpenSSL::SSL::VERIFY_PEER if verify_ssl is not given" do
|
537
|
+
@request = RestClient::Request.new(:method => :put, :url => 'https://some/resource', :payload => 'payload')
|
538
|
+
@net.should_receive(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
539
|
+
@http.stub(:request)
|
540
|
+
@request.stub(:process_result)
|
541
|
+
@request.stub(:response_log)
|
542
|
+
@request.transmit(@uri, 'req', 'payload')
|
543
|
+
end
|
544
|
+
|
408
545
|
it "should set net.verify_mode to the passed value if verify_ssl is an OpenSSL constant" do
|
409
546
|
mode = OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
|
410
547
|
@request = RestClient::Request.new( :method => :put,
|
@@ -422,6 +559,112 @@ describe RestClient::Request do
|
|
422
559
|
@request.ssl_client_cert.should be(nil)
|
423
560
|
end
|
424
561
|
|
562
|
+
it "should set the ssl_version if provided" do
|
563
|
+
@request = RestClient::Request.new(
|
564
|
+
:method => :put,
|
565
|
+
:url => 'https://some/resource',
|
566
|
+
:payload => 'payload',
|
567
|
+
:ssl_version => "TLSv1"
|
568
|
+
)
|
569
|
+
@net.should_receive(:ssl_version=).with("TLSv1")
|
570
|
+
@http.stub(:request)
|
571
|
+
@request.stub(:process_result)
|
572
|
+
@request.stub(:response_log)
|
573
|
+
@request.transmit(@uri, 'req', 'payload')
|
574
|
+
end
|
575
|
+
|
576
|
+
it "should not set the ssl_version if not provided" do
|
577
|
+
@request = RestClient::Request.new(
|
578
|
+
:method => :put,
|
579
|
+
:url => 'https://some/resource',
|
580
|
+
:payload => 'payload'
|
581
|
+
)
|
582
|
+
@net.should_not_receive(:ssl_version=).with("TLSv1")
|
583
|
+
@http.stub(:request)
|
584
|
+
@request.stub(:process_result)
|
585
|
+
@request.stub(:response_log)
|
586
|
+
@request.transmit(@uri, 'req', 'payload')
|
587
|
+
end
|
588
|
+
|
589
|
+
it "should set the ssl_ciphers if provided" do
|
590
|
+
ciphers = 'AESGCM:HIGH:!aNULL:!eNULL:RC4+RSA'
|
591
|
+
@request = RestClient::Request.new(
|
592
|
+
:method => :put,
|
593
|
+
:url => 'https://some/resource',
|
594
|
+
:payload => 'payload',
|
595
|
+
:ssl_ciphers => ciphers
|
596
|
+
)
|
597
|
+
@net.should_receive(:ciphers=).with(ciphers)
|
598
|
+
@http.stub(:request)
|
599
|
+
@request.stub(:process_result)
|
600
|
+
@request.stub(:response_log)
|
601
|
+
@request.transmit(@uri, 'req', 'payload')
|
602
|
+
end
|
603
|
+
|
604
|
+
it "should not set the ssl_ciphers if set to nil" do
|
605
|
+
@request = RestClient::Request.new(
|
606
|
+
:method => :put,
|
607
|
+
:url => 'https://some/resource',
|
608
|
+
:payload => 'payload',
|
609
|
+
:ssl_ciphers => nil,
|
610
|
+
)
|
611
|
+
@net.should_not_receive(:ciphers=)
|
612
|
+
@http.stub(:request)
|
613
|
+
@request.stub(:process_result)
|
614
|
+
@request.stub(:response_log)
|
615
|
+
@request.transmit(@uri, 'req', 'payload')
|
616
|
+
end
|
617
|
+
|
618
|
+
it "should override ssl_ciphers with better defaults with weak default ciphers" do
|
619
|
+
stub_const(
|
620
|
+
'::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
|
621
|
+
{
|
622
|
+
:ssl_version=>"SSLv23",
|
623
|
+
:verify_mode=>1,
|
624
|
+
:ciphers=>"ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW",
|
625
|
+
:options=>-2147480577,
|
626
|
+
}
|
627
|
+
)
|
628
|
+
|
629
|
+
@request = RestClient::Request.new(
|
630
|
+
:method => :put,
|
631
|
+
:url => 'https://some/resource',
|
632
|
+
:payload => 'payload',
|
633
|
+
)
|
634
|
+
|
635
|
+
@net.should_receive(:ciphers=).with(RestClient::Request::DefaultCiphers)
|
636
|
+
|
637
|
+
@http.stub(:request)
|
638
|
+
@request.stub(:process_result)
|
639
|
+
@request.stub(:response_log)
|
640
|
+
@request.transmit(@uri, 'req', 'payload')
|
641
|
+
end
|
642
|
+
|
643
|
+
it "should not override ssl_ciphers with better defaults with different default ciphers" do
|
644
|
+
stub_const(
|
645
|
+
'::OpenSSL::SSL::SSLContext::DEFAULT_PARAMS',
|
646
|
+
{
|
647
|
+
:ssl_version=>"SSLv23",
|
648
|
+
:verify_mode=>1,
|
649
|
+
:ciphers=>"HIGH:!aNULL:!eNULL:!EXPORT:!LOW:!MEDIUM:!SSLv2",
|
650
|
+
:options=>-2147480577,
|
651
|
+
}
|
652
|
+
)
|
653
|
+
|
654
|
+
@request = RestClient::Request.new(
|
655
|
+
:method => :put,
|
656
|
+
:url => 'https://some/resource',
|
657
|
+
:payload => 'payload',
|
658
|
+
)
|
659
|
+
|
660
|
+
@net.should_not_receive(:ciphers=)
|
661
|
+
|
662
|
+
@http.stub(:request)
|
663
|
+
@request.stub(:process_result)
|
664
|
+
@request.stub(:response_log)
|
665
|
+
@request.transmit(@uri, 'req', 'payload')
|
666
|
+
end
|
667
|
+
|
425
668
|
it "should set the ssl_client_cert if provided" do
|
426
669
|
@request = RestClient::Request.new(
|
427
670
|
:method => :put,
|
@@ -442,7 +685,7 @@ describe RestClient::Request do
|
|
442
685
|
:url => 'https://some/resource',
|
443
686
|
:payload => 'payload'
|
444
687
|
)
|
445
|
-
@net.should_not_receive(:cert=)
|
688
|
+
@net.should_not_receive(:cert=)
|
446
689
|
@http.stub(:request)
|
447
690
|
@request.stub(:process_result)
|
448
691
|
@request.stub(:response_log)
|
@@ -473,7 +716,7 @@ describe RestClient::Request do
|
|
473
716
|
:url => 'https://some/resource',
|
474
717
|
:payload => 'payload'
|
475
718
|
)
|
476
|
-
@net.should_not_receive(:key=)
|
719
|
+
@net.should_not_receive(:key=)
|
477
720
|
@http.stub(:request)
|
478
721
|
@request.stub(:process_result)
|
479
722
|
@request.stub(:response_log)
|
@@ -492,6 +735,7 @@ describe RestClient::Request do
|
|
492
735
|
:ssl_ca_file => "Certificate Authority File"
|
493
736
|
)
|
494
737
|
@net.should_receive(:ca_file=).with("Certificate Authority File")
|
738
|
+
@net.should_not_receive(:cert_store=)
|
495
739
|
@http.stub(:request)
|
496
740
|
@request.stub(:process_result)
|
497
741
|
@request.stub(:response_log)
|
@@ -504,12 +748,129 @@ describe RestClient::Request do
|
|
504
748
|
:url => 'https://some/resource',
|
505
749
|
:payload => 'payload'
|
506
750
|
)
|
507
|
-
@net.should_not_receive(:ca_file=)
|
751
|
+
@net.should_not_receive(:ca_file=)
|
752
|
+
@http.stub(:request)
|
753
|
+
@request.stub(:process_result)
|
754
|
+
@request.stub(:response_log)
|
755
|
+
@request.transmit(@uri, 'req', 'payload')
|
756
|
+
end
|
757
|
+
|
758
|
+
it "should default to not having an ssl_ca_path" do
|
759
|
+
@request.ssl_ca_path.should be(nil)
|
760
|
+
end
|
761
|
+
|
762
|
+
it "should set the ssl_ca_path if provided" do
|
763
|
+
@request = RestClient::Request.new(
|
764
|
+
:method => :put,
|
765
|
+
:url => 'https://some/resource',
|
766
|
+
:payload => 'payload',
|
767
|
+
:ssl_ca_path => "Certificate Authority Path"
|
768
|
+
)
|
769
|
+
@net.should_receive(:ca_path=).with("Certificate Authority Path")
|
770
|
+
@net.should_not_receive(:cert_store=)
|
771
|
+
@http.stub(:request)
|
772
|
+
@request.stub(:process_result)
|
773
|
+
@request.stub(:response_log)
|
774
|
+
@request.transmit(@uri, 'req', 'payload')
|
775
|
+
end
|
776
|
+
|
777
|
+
it "should not set the ssl_ca_path if it is not provided" do
|
778
|
+
@request = RestClient::Request.new(
|
779
|
+
:method => :put,
|
780
|
+
:url => 'https://some/resource',
|
781
|
+
:payload => 'payload'
|
782
|
+
)
|
783
|
+
@net.should_not_receive(:ca_path=)
|
784
|
+
@http.stub(:request)
|
785
|
+
@request.stub(:process_result)
|
786
|
+
@request.stub(:response_log)
|
787
|
+
@request.transmit(@uri, 'req', 'payload')
|
788
|
+
end
|
789
|
+
|
790
|
+
it "should set the ssl_cert_store if provided" do
|
791
|
+
store = OpenSSL::X509::Store.new
|
792
|
+
store.set_default_paths
|
793
|
+
|
794
|
+
@request = RestClient::Request.new(
|
795
|
+
:method => :put,
|
796
|
+
:url => 'https://some/resource',
|
797
|
+
:payload => 'payload',
|
798
|
+
:ssl_cert_store => store
|
799
|
+
)
|
800
|
+
@net.should_receive(:cert_store=).with(store)
|
801
|
+
@net.should_not_receive(:ca_path=)
|
802
|
+
@net.should_not_receive(:ca_file=)
|
803
|
+
@http.stub(:request)
|
804
|
+
@request.stub(:process_result)
|
805
|
+
@request.stub(:response_log)
|
806
|
+
@request.transmit(@uri, 'req', 'payload')
|
807
|
+
end
|
808
|
+
|
809
|
+
it "should by default set the ssl_cert_store if no CA info is provided" do
|
810
|
+
@request = RestClient::Request.new(
|
811
|
+
:method => :put,
|
812
|
+
:url => 'https://some/resource',
|
813
|
+
:payload => 'payload'
|
814
|
+
)
|
815
|
+
@net.should_receive(:cert_store=)
|
816
|
+
@net.should_not_receive(:ca_path=)
|
817
|
+
@net.should_not_receive(:ca_file=)
|
508
818
|
@http.stub(:request)
|
509
819
|
@request.stub(:process_result)
|
510
820
|
@request.stub(:response_log)
|
511
821
|
@request.transmit(@uri, 'req', 'payload')
|
512
822
|
end
|
823
|
+
|
824
|
+
it "should not set the ssl_cert_store if it is set falsy" do
|
825
|
+
@request = RestClient::Request.new(
|
826
|
+
:method => :put,
|
827
|
+
:url => 'https://some/resource',
|
828
|
+
:payload => 'payload',
|
829
|
+
:ssl_cert_store => nil,
|
830
|
+
)
|
831
|
+
@net.should_not_receive(:cert_store=)
|
832
|
+
@http.stub(:request)
|
833
|
+
@request.stub(:process_result)
|
834
|
+
@request.stub(:response_log)
|
835
|
+
@request.transmit(@uri, 'req', 'payload')
|
836
|
+
end
|
837
|
+
|
838
|
+
it "should not set the ssl_verify_callback by default" do
|
839
|
+
@request = RestClient::Request.new(
|
840
|
+
:method => :put,
|
841
|
+
:url => 'https://some/resource',
|
842
|
+
:payload => 'payload',
|
843
|
+
)
|
844
|
+
@net.should_not_receive(:verify_callback=)
|
845
|
+
@http.stub(:request)
|
846
|
+
@request.stub(:process_result)
|
847
|
+
@request.stub(:response_log)
|
848
|
+
@request.transmit(@uri, 'req', 'payload')
|
849
|
+
end
|
850
|
+
|
851
|
+
it "should set the ssl_verify_callback if passed" do
|
852
|
+
callback = lambda {}
|
853
|
+
@request = RestClient::Request.new(
|
854
|
+
:method => :put,
|
855
|
+
:url => 'https://some/resource',
|
856
|
+
:payload => 'payload',
|
857
|
+
:ssl_verify_callback => callback,
|
858
|
+
)
|
859
|
+
@net.should_receive(:verify_callback=).with(callback)
|
860
|
+
|
861
|
+
# we'll read cert_store on jruby
|
862
|
+
# https://github.com/jruby/jruby/issues/597
|
863
|
+
if RestClient::Platform.jruby?
|
864
|
+
allow(@net).to receive(:cert_store)
|
865
|
+
end
|
866
|
+
|
867
|
+
@http.stub(:request)
|
868
|
+
@request.stub(:process_result)
|
869
|
+
@request.stub(:response_log)
|
870
|
+
@request.transmit(@uri, 'req', 'payload')
|
871
|
+
end
|
872
|
+
|
873
|
+
# </ssl>
|
513
874
|
end
|
514
875
|
|
515
876
|
it "should still return a response object for 204 No Content responses" do
|
@@ -525,4 +886,20 @@ describe RestClient::Request do
|
|
525
886
|
response.should_not be_nil
|
526
887
|
response.code.should eq 204
|
527
888
|
end
|
889
|
+
|
890
|
+
describe "raw response" do
|
891
|
+
it "should read the response into a binary-mode tempfile" do
|
892
|
+
@request = RestClient::Request.new(:method => "get", :url => "example.com", :raw_response => true)
|
893
|
+
|
894
|
+
tempfile = double("tempfile")
|
895
|
+
tempfile.should_receive(:binmode)
|
896
|
+
tempfile.stub(:open)
|
897
|
+
tempfile.stub(:close)
|
898
|
+
Tempfile.should_receive(:new).with("rest-client").and_return(tempfile)
|
899
|
+
|
900
|
+
net_http_res = Net::HTTPOK.new(nil, "200", "body")
|
901
|
+
net_http_res.stub(:read_body).and_return("body")
|
902
|
+
@request.fetch_body(net_http_res)
|
903
|
+
end
|
904
|
+
end
|
528
905
|
end
|