mirror of
https://github.com/jnunemaker/httparty
synced 2023-03-27 23:23:07 -04:00
Add ssl_ca_file and ssl_ca_path options to allow SSL certificate verification.
This commit is contained in:
parent
c068bbfeae
commit
f9c74788d5
15 changed files with 305 additions and 2 deletions
|
@ -201,6 +201,26 @@ module HTTParty
|
||||||
default_options[:pem] = pem_contents
|
default_options[:pem] = pem_contents
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Allows setting an OpenSSL certificate authority file
|
||||||
|
#
|
||||||
|
# class Foo
|
||||||
|
# include HTTParty
|
||||||
|
# ssl_ca_file '/etc/ssl/certs/ca-certificates.crt'
|
||||||
|
# end
|
||||||
|
def ssl_ca_file(path)
|
||||||
|
default_options[:ssl_ca_file] = path
|
||||||
|
end
|
||||||
|
|
||||||
|
# Allows setting an OpenSSL certificate authority path (directory)
|
||||||
|
#
|
||||||
|
# class Foo
|
||||||
|
# include HTTParty
|
||||||
|
# ssl_ca_path '/etc/ssl/certs/'
|
||||||
|
# end
|
||||||
|
def ssl_ca_path(path)
|
||||||
|
default_options[:ssl_ca_path] = path
|
||||||
|
end
|
||||||
|
|
||||||
# Allows setting a custom parser for the response.
|
# Allows setting a custom parser for the response.
|
||||||
#
|
#
|
||||||
# class Foo
|
# class Foo
|
||||||
|
|
|
@ -68,12 +68,22 @@ module HTTParty
|
||||||
http.read_timeout = options[:timeout]
|
http.read_timeout = options[:timeout]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# By default, don't do any SSL verification (!), but this can be overridden.
|
||||||
|
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||||
|
# Client certificate authentication
|
||||||
if options[:pem] && http.use_ssl?
|
if options[:pem] && http.use_ssl?
|
||||||
http.cert = OpenSSL::X509::Certificate.new(options[:pem])
|
http.cert = OpenSSL::X509::Certificate.new(options[:pem])
|
||||||
http.key = OpenSSL::PKey::RSA.new(options[:pem])
|
http.key = OpenSSL::PKey::RSA.new(options[:pem])
|
||||||
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||||
else
|
end
|
||||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
# SSL certificate authority file and/or directory
|
||||||
|
if options[:ssl_ca_file] && http.use_ssl?
|
||||||
|
http.ca_file = options[:ssl_ca_file]
|
||||||
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||||
|
end
|
||||||
|
if options[:ssl_ca_path] && http.use_ssl?
|
||||||
|
http.ca_path = options[:ssl_ca_path]
|
||||||
|
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
||||||
end
|
end
|
||||||
|
|
||||||
if options[:debug_output]
|
if options[:debug_output]
|
||||||
|
|
29
spec/fixtures/ssl/generate.sh
vendored
Executable file
29
spec/fixtures/ssl/generate.sh
vendored
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -d "generated" ] ; then
|
||||||
|
echo >&2 "error: 'generated' directory already exists. Delete it first."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir generated
|
||||||
|
|
||||||
|
# Generate the CA private key and certificate
|
||||||
|
openssl req -batch -subj '/CN=INSECURE Test Certificate Authority' -newkey rsa:1024 -new -x509 -days 999999 -keyout generated/ca.key -nodes -out generated/ca.crt
|
||||||
|
|
||||||
|
# Create symlinks for ssl_ca_path
|
||||||
|
c_rehash generated
|
||||||
|
|
||||||
|
# Generate the server private key and self-signed certificate
|
||||||
|
openssl req -batch -subj '/CN=localhost' -newkey rsa:1024 -new -x509 -days 999999 -keyout generated/server.key -nodes -out generated/selfsigned.crt
|
||||||
|
|
||||||
|
# Generate certificate signing request with bogus hostname
|
||||||
|
openssl req -batch -subj '/CN=bogo' -new -days 999999 -key generated/server.key -nodes -out generated/bogushost.csr
|
||||||
|
|
||||||
|
# Sign the certificate requests
|
||||||
|
openssl x509 -CA generated/ca.crt -CAkey generated/ca.key -set_serial 1 -in generated/selfsigned.crt -out generated/server.crt -clrext -extfile openssl-exts.cnf -extensions cert
|
||||||
|
openssl x509 -req -CA generated/ca.crt -CAkey generated/ca.key -set_serial 1 -in generated/bogushost.csr -out generated/bogushost.crt -clrext -extfile openssl-exts.cnf -extensions cert
|
||||||
|
|
||||||
|
# Remove certificate signing requests
|
||||||
|
rm -f generated/*.csr
|
||||||
|
|
1
spec/fixtures/ssl/generated/1fe462c2.0
vendored
Symbolic link
1
spec/fixtures/ssl/generated/1fe462c2.0
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
ca.crt
|
13
spec/fixtures/ssl/generated/bogushost.crt
vendored
Normal file
13
spec/fixtures/ssl/generated/bogushost.crt
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICAzCCAWygAwIBAgIBATANBgkqhkiG9w0BAQUFADAuMSwwKgYDVQQDEyNJTlNF
|
||||||
|
Q1VSRSBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMDA3MDkwMTU5MTda
|
||||||
|
Fw0xMDA4MDgwMTU5MTdaMA8xDTALBgNVBAMTBGJvZ28wgZ8wDQYJKoZIhvcNAQEB
|
||||||
|
BQADgY0AMIGJAoGBAKMU3pAeBZzKYcYF8eDIPvb9qYF8odH9ZK23IGn1T9D9Oxd0
|
||||||
|
2+IltkMJ0sOWpknp+kTzbAP0dammMNExt/YFuFqN4MenTMp87FFQAXSK0WhtjNcb
|
||||||
|
Fl9gv4iThWedFVSq3qZs8c+ZTCrrC/A/ScGAH7g4C57Degci7SCdf4v97m7nAgMB
|
||||||
|
AAGjUDBOMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFMXuuqokuPcMMS7OFu0jeoGK
|
||||||
|
oJsDMB8GA1UdIwQYMBaAFJYXkYdQ2afmGvLRN9YGOqrGK/MLMA0GCSqGSIb3DQEB
|
||||||
|
BQUAA4GBAIPfOu+RadQpZlSaMg3m7t7wn3yPPp2yXtz6s98JqBvoTtZZ0f9JMG6z
|
||||||
|
muVss0JmHPTyPDlNk54DaySa0wAUArAqTUvq05U+VoxtN7QEqR9bgdsRSByowVax
|
||||||
|
/01r5CdrMC/xDs4OWz3sv8Kyw0hmd9nnCvMoMUQgEZsjNcEPmN7K
|
||||||
|
-----END CERTIFICATE-----
|
15
spec/fixtures/ssl/generated/ca.crt
vendored
Normal file
15
spec/fixtures/ssl/generated/ca.crt
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICazCCAdSgAwIBAgIJAMBBDJhEZSUlMA0GCSqGSIb3DQEBBQUAMC4xLDAqBgNV
|
||||||
|
BAMTI0lOU0VDVVJFIFRlc3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTEwMDcw
|
||||||
|
OTAxNTkxN1oXDTI2MDUxOTE2MzM1N1owLjEsMCoGA1UEAxMjSU5TRUNVUkUgVGVz
|
||||||
|
dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
|
||||||
|
AoGBAMAfEr8RkcWZhIwj7zz2F+phGpASWiO6EPUNsltXvksPo06DGJJJqWWJ/zUm
|
||||||
|
/1m9Wjd0yx1dinT+C1jpViWTvJZ0KaSs29PW1EFuwZ8tOlm4TdWti6mGp9QZ5KVU
|
||||||
|
24QXAAbrvXrEVBUfCmhd1gxrqvXH9gMbtndXtDnmbba6u2ehAgMBAAGjgZAwgY0w
|
||||||
|
HQYDVR0OBBYEFJYXkYdQ2afmGvLRN9YGOqrGK/MLMF4GA1UdIwRXMFWAFJYXkYdQ
|
||||||
|
2afmGvLRN9YGOqrGK/MLoTKkMDAuMSwwKgYDVQQDEyNJTlNFQ1VSRSBUZXN0IENl
|
||||||
|
cnRpZmljYXRlIEF1dGhvcml0eYIJAMBBDJhEZSUlMAwGA1UdEwQFMAMBAf8wDQYJ
|
||||||
|
KoZIhvcNAQEFBQADgYEAgN+TxBq4sYMnJZ3WHZ/RLcnpIbZdElUuM3lBbwKOmL5E
|
||||||
|
KZ7uh5ZzyihNMnuw61MqvSMjwZfipyD0xNhX7e4dF47Q1oOUaMSxTS92PgQ22otY
|
||||||
|
IMVtP7r8h8op7oKsiaSu4Y984abXirhMdVa1nUvyliBSYs94YIyZtwujhQJKN5Y=
|
||||||
|
-----END CERTIFICATE-----
|
15
spec/fixtures/ssl/generated/ca.key
vendored
Normal file
15
spec/fixtures/ssl/generated/ca.key
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXgIBAAKBgQDAHxK/EZHFmYSMI+889hfqYRqQElojuhD1DbJbV75LD6NOgxiS
|
||||||
|
Sallif81Jv9ZvVo3dMsdXYp0/gtY6VYlk7yWdCmkrNvT1tRBbsGfLTpZuE3VrYup
|
||||||
|
hqfUGeSlVNuEFwAG6716xFQVHwpoXdYMa6r1x/YDG7Z3V7Q55m22urtnoQIDAQAB
|
||||||
|
AoGAMJMqsDiG/Mj15GDpiiZGobHvf2HEfKf8xZiy8blbmarYhW9L9SC+vbeIWS4E
|
||||||
|
/fGML91NxZzy9uWMhOxqJZIW6hsPbaZaxWcI/Ar78YcwskKRZC8vZd2bZ+jbwp6Y
|
||||||
|
rI0/FVla42wcFXr6dbdnLKOeYBurB/F/839jeErjoWJ5F2kCQQDsmOl9A+ni+OYI
|
||||||
|
We8/Vc/BASVnpKbvYYUi4BlzDjhcj5cn44pIuGRS/VDfmiQTGPf/gMOd6GM2jDUm
|
||||||
|
kvFUZY5fAkEAz+BwsTZAwF9vPOBu9iuVsCzJ+OhyNtl1PrWDqEdMkFRHN++eXkL0
|
||||||
|
U4uNMLma3pCDLJ2bv49mTPzDu2AY03bJ/wJBALMSzW5MvwKGhnz9rOJQDa20M15t
|
||||||
|
tdfrBLyvxzNZKPmNyMdtJiYCQhS6HDMRVIqL1HCzQdvLnwQTPMtUXooVT5sCQQDF
|
||||||
|
BpFJJYbRzqJ8LKx/HmhOBuWXyZkXa5y4xwn2YT2sPnUSC0crSIKS/N3hpMmo0YfC
|
||||||
|
rc+FDMGFjr1lx3tAUoK5AkEAiEbs3Kn1donT7bT5+WeTGSIIBnWN2s93Gq7AXpV3
|
||||||
|
K96lVDUnXa4qGwGdhmvlhXpwhYrzMNHkzaU/AcSOi3Cqww==
|
||||||
|
-----END RSA PRIVATE KEY-----
|
14
spec/fixtures/ssl/generated/selfsigned.crt
vendored
Normal file
14
spec/fixtures/ssl/generated/selfsigned.crt
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICGzCCAYSgAwIBAgIJALEY3/cqVrhXMA0GCSqGSIb3DQEBBQUAMBQxEjAQBgNV
|
||||||
|
BAMTCWxvY2FsaG9zdDAeFw0xMDA3MDkwMTU5MTdaFw0yNjA1MTkxNjMzNTdaMBQx
|
||||||
|
EjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
|
||||||
|
oxTekB4FnMphxgXx4Mg+9v2pgXyh0f1krbcgafVP0P07F3Tb4iW2QwnSw5amSen6
|
||||||
|
RPNsA/R1qaYw0TG39gW4Wo3gx6dMynzsUVABdIrRaG2M1xsWX2C/iJOFZ50VVKre
|
||||||
|
pmzxz5lMKusL8D9JwYAfuDgLnsN6ByLtIJ1/i/3ubucCAwEAAaN1MHMwHQYDVR0O
|
||||||
|
BBYEFMXuuqokuPcMMS7OFu0jeoGKoJsDMEQGA1UdIwQ9MDuAFMXuuqokuPcMMS7O
|
||||||
|
Fu0jeoGKoJsDoRikFjAUMRIwEAYDVQQDEwlsb2NhbGhvc3SCCQCxGN/3Kla4VzAM
|
||||||
|
BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GBAKC8iJBjfAe78/QzKmMk6QJN
|
||||||
|
kdLolcGGdINaCyGJRG67givjgkLj9N0JDJImeXWebyykrb/RKSNh7jAcBah+qnvS
|
||||||
|
SkuXG5E2qKvG66rN/4sjhP68pvD10psvKY/pYmZTPu1VHLZXWwNHtKy/F/ktj/7P
|
||||||
|
HyuNWpYma8yzHT8RMizZ
|
||||||
|
-----END CERTIFICATE-----
|
13
spec/fixtures/ssl/generated/server.crt
vendored
Normal file
13
spec/fixtures/ssl/generated/server.crt
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
-----BEGIN CERTIFICATE-----
|
||||||
|
MIICCDCCAXGgAwIBAgIBATANBgkqhkiG9w0BAQUFADAuMSwwKgYDVQQDEyNJTlNF
|
||||||
|
Q1VSRSBUZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xMDA3MDkwMTU5MTda
|
||||||
|
Fw0xMDA4MDgwMTU5MTdaMBQxEjAQBgNVBAMTCWxvY2FsaG9zdDCBnzANBgkqhkiG
|
||||||
|
9w0BAQEFAAOBjQAwgYkCgYEAoxTekB4FnMphxgXx4Mg+9v2pgXyh0f1krbcgafVP
|
||||||
|
0P07F3Tb4iW2QwnSw5amSen6RPNsA/R1qaYw0TG39gW4Wo3gx6dMynzsUVABdIrR
|
||||||
|
aG2M1xsWX2C/iJOFZ50VVKrepmzxz5lMKusL8D9JwYAfuDgLnsN6ByLtIJ1/i/3u
|
||||||
|
bucCAwEAAaNQME4wDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUxe66qiS49wwxLs4W
|
||||||
|
7SN6gYqgmwMwHwYDVR0jBBgwFoAUlheRh1DZp+Ya8tE31gY6qsYr8wswDQYJKoZI
|
||||||
|
hvcNAQEFBQADgYEAPRrgDgJG0YSDNUl57cghBqHvlb4QOZDGgW1XLiG2GYLl1o5Q
|
||||||
|
jbHij7BZBdk4CBwr1vzExL6Ef7ktvhEEvgXEJQeiOU9Y+v/w3EG914dpJp39Epv6
|
||||||
|
vBvO9yAyAaozk7JvRGlB8nbb36pYuFnv+KsRNn/KFjauCXm+gknQRSP9vpE=
|
||||||
|
-----END CERTIFICATE-----
|
15
spec/fixtures/ssl/generated/server.key
vendored
Normal file
15
spec/fixtures/ssl/generated/server.key
vendored
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIICXQIBAAKBgQCjFN6QHgWcymHGBfHgyD72/amBfKHR/WSttyBp9U/Q/TsXdNvi
|
||||||
|
JbZDCdLDlqZJ6fpE82wD9HWppjDRMbf2BbhajeDHp0zKfOxRUAF0itFobYzXGxZf
|
||||||
|
YL+Ik4VnnRVUqt6mbPHPmUwq6wvwP0nBgB+4OAuew3oHIu0gnX+L/e5u5wIDAQAB
|
||||||
|
AoGBAJpAsie1De/5CbRJiTjpj40F79/3qAQ83o7lqTYv/7gY3lzYfucQbq5IS2AP
|
||||||
|
TeiZ9MxlRuUSxHycIo6srWl6jZ0u1M4vfRvmQf2aXZbN4MPcY+XnpUCYGKgKBVLC
|
||||||
|
tXoD9iHgCpvexbxjJgLIeeWotUoY3xAo8YnX2Luf+Vtah6dRAkEA03hLG+w8lov2
|
||||||
|
J3AfHQgKjKfRrMU5eC4P9I4LN+nLyHd7i6T+JP5V5NadRkN+xj0zHfo8PxjaPmDv
|
||||||
|
QQqkhUlV3wJBAMVsGqa6NbtnCvHPc/M0XanBRuGejz2mDJqqaXMCBw8tY318XEMs
|
||||||
|
gRdlDVWrNg7AcSEuzh48OA7c6lazKLa5N/kCQHhA69VRHZMuvCfpJohHzlf2BtIM
|
||||||
|
xYWGDCSxscd1+CBjcaoThUJcL1QWhxExyKHKo4rkheYLp+/ZB7Ug7DWvYlkCQQCZ
|
||||||
|
SO+Ehs5TfJVF3UJ1EjKrLHNhmOA1CKl+qVQIxQlAIoi+FQH58iMlTAPHgZEOcSMl
|
||||||
|
lZbaaP1JpQOaX677+OHZAkA8vVYbYC+7t0SUqoY0X8z11Iobttpqir9trNq1CK8A
|
||||||
|
/3To+/BFK2A6Sj7R5u90Vi523FpWq1a74oNAsnB3x7TU
|
||||||
|
-----END RSA PRIVATE KEY-----
|
9
spec/fixtures/ssl/openssl-exts.cnf
vendored
Normal file
9
spec/fixtures/ssl/openssl-exts.cnf
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[ca]
|
||||||
|
basicConstraints=critical,CA:true
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid:always,issuer:always
|
||||||
|
|
||||||
|
[cert]
|
||||||
|
basicConstraints=critical,CA:false
|
||||||
|
subjectKeyIdentifier=hash
|
||||||
|
authorityKeyIdentifier=keyid,issuer
|
54
spec/httparty/ssl_spec.rb
Normal file
54
spec/httparty/ssl_spec.rb
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
||||||
|
|
||||||
|
describe HTTParty::Request do
|
||||||
|
context "SSL certificate verification" do
|
||||||
|
before do
|
||||||
|
FakeWeb.allow_net_connect = true # enable network connections just for this test
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
FakeWeb.allow_net_connect = false # Restore allow_net_connect value for testing
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work with when no trusted CA list is specified" do
|
||||||
|
ssl_verify_test(nil, nil, "selfsigned.crt").should == {'success' => true}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work with when no trusted CA list is specified, even with a bogus hostname" do
|
||||||
|
ssl_verify_test(nil, nil, "bogushost.crt").should == {'success' => true}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work when using ssl_ca_file with a self-signed CA" do
|
||||||
|
ssl_verify_test(:ssl_ca_file, "selfsigned.crt", "selfsigned.crt").should == {'success' => true}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should work when using ssl_ca_file with a certificate authority" do
|
||||||
|
ssl_verify_test(:ssl_ca_file, "ca.crt", "server.crt").should == {'success' => true}
|
||||||
|
end
|
||||||
|
it "should work when using ssl_ca_path with a certificate authority" do
|
||||||
|
ssl_verify_test(:ssl_ca_path, ".", "server.crt").should == {'success' => true}
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should fail when using ssl_ca_file and the server uses an unrecognized certificate authority" do
|
||||||
|
lambda do
|
||||||
|
ssl_verify_test(:ssl_ca_file, "ca.crt", "selfsigned.crt")
|
||||||
|
end.should raise_error(OpenSSL::SSL::SSLError)
|
||||||
|
end
|
||||||
|
it "should fail when using ssl_ca_path and the server uses an unrecognized certificate authority" do
|
||||||
|
lambda do
|
||||||
|
ssl_verify_test(:ssl_ca_path, ".", "selfsigned.crt")
|
||||||
|
end.should raise_error(OpenSSL::SSL::SSLError)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should fail when using ssl_ca_file and the server uses a bogus hostname" do
|
||||||
|
lambda do
|
||||||
|
ssl_verify_test(:ssl_ca_file, "ca.crt", "bogushost.crt")
|
||||||
|
end.should raise_error(OpenSSL::SSL::SSLError)
|
||||||
|
end
|
||||||
|
it "should fail when using ssl_ca_path and the server uses a bogus hostname" do
|
||||||
|
lambda do
|
||||||
|
ssl_verify_test(:ssl_ca_path, ".", "bogushost.crt")
|
||||||
|
end.should raise_error(OpenSSL::SSL::SSLError)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,6 +10,7 @@ Dir[File.expand_path(File.join(File.dirname(__FILE__),'support','**','*.rb'))].e
|
||||||
|
|
||||||
Spec::Runner.configure do |config|
|
Spec::Runner.configure do |config|
|
||||||
config.include HTTParty::StubResponse
|
config.include HTTParty::StubResponse
|
||||||
|
config.include HTTParty::SSLTestHelper
|
||||||
config.before(:suite) do
|
config.before(:suite) do
|
||||||
FakeWeb.allow_net_connect = false
|
FakeWeb.allow_net_connect = false
|
||||||
end
|
end
|
||||||
|
|
25
spec/support/ssl_test_helper.rb
Normal file
25
spec/support/ssl_test_helper.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
module HTTParty
|
||||||
|
module SSLTestHelper
|
||||||
|
def ssl_verify_test(mode, ca_basename, server_cert_filename)
|
||||||
|
test_server = nil
|
||||||
|
begin
|
||||||
|
# Start an HTTPS server
|
||||||
|
test_server = SSLTestServer.new(
|
||||||
|
:rsa_key => File.read(File.expand_path("../../fixtures/ssl/generated/server.key", __FILE__)),
|
||||||
|
:cert => File.read(File.expand_path("../../fixtures/ssl/generated/#{server_cert_filename}", __FILE__)))
|
||||||
|
test_server.start
|
||||||
|
|
||||||
|
# Build a request
|
||||||
|
if mode
|
||||||
|
ca_path = File.expand_path("../../fixtures/ssl/generated/#{ca_basename}", __FILE__)
|
||||||
|
raise ArgumentError.new("#{ca_path} does not exist") unless File.exist?(ca_path)
|
||||||
|
return HTTParty.get("https://localhost:#{test_server.port}/", :format => :json, :timeout=>30, mode => ca_path)
|
||||||
|
else
|
||||||
|
return HTTParty.get("https://localhost:#{test_server.port}/", :format => :json, :timeout=>30)
|
||||||
|
end
|
||||||
|
ensure
|
||||||
|
test_server.stop if test_server
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
69
spec/support/ssl_test_server.rb
Normal file
69
spec/support/ssl_test_server.rb
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
require 'openssl'
|
||||||
|
require 'socket'
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
|
# NOTE: This code is garbage. It probably has deadlocks, it might leak
|
||||||
|
# threads, and otherwise cause problems in a real system. It's really only
|
||||||
|
# intended for testing HTTParty.
|
||||||
|
class SSLTestServer
|
||||||
|
attr_accessor :ctx # SSLContext object
|
||||||
|
attr_reader :port
|
||||||
|
|
||||||
|
def initialize(options={})
|
||||||
|
@ctx = OpenSSL::SSL::SSLContext.new
|
||||||
|
@ctx.cert = OpenSSL::X509::Certificate.new(options[:cert])
|
||||||
|
@ctx.key = OpenSSL::PKey::RSA.new(options[:rsa_key])
|
||||||
|
@ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE # Don't verify client certificate
|
||||||
|
@port = options[:port] || 0
|
||||||
|
@thread = nil
|
||||||
|
@stopping_mutex = Mutex.new
|
||||||
|
@stopping = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def start
|
||||||
|
@raw_server = TCPServer.new(@port)
|
||||||
|
if @port == 0
|
||||||
|
@port = Socket::getnameinfo(@raw_server.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)[1].to_i
|
||||||
|
end
|
||||||
|
@ssl_server = OpenSSL::SSL::SSLServer.new(@raw_server, @ctx)
|
||||||
|
@stopping_mutex.synchronize{
|
||||||
|
return if @stopping
|
||||||
|
@thread = Thread.new{ thread_main }
|
||||||
|
}
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def stop
|
||||||
|
@stopping_mutex.synchronize{
|
||||||
|
return if @stopping
|
||||||
|
@stopping = true
|
||||||
|
}
|
||||||
|
@thread.join
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def thread_main
|
||||||
|
until @stopping_mutex.synchronize{ @stopping }
|
||||||
|
(rr,ww,ee) = select([@ssl_server.to_io], nil, nil, 0.1)
|
||||||
|
next unless rr && rr.include?(@ssl_server.to_io)
|
||||||
|
socket = @ssl_server.accept
|
||||||
|
Thread.new{
|
||||||
|
header = []
|
||||||
|
until (line = socket.readline).rstrip.empty?
|
||||||
|
header << line
|
||||||
|
end
|
||||||
|
|
||||||
|
socket.write <<'EOF'.gsub(/\r\n/n, "\n").gsub(/\n/n, "\r\n")
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
Connection: close
|
||||||
|
Content-Type: application/json; charset=UTF-8
|
||||||
|
|
||||||
|
{"success":true}
|
||||||
|
EOF
|
||||||
|
socket.close
|
||||||
|
}
|
||||||
|
end
|
||||||
|
@ssl_server.close
|
||||||
|
end
|
||||||
|
end
|
Loading…
Add table
Reference in a new issue