httpclient 2.6.0.1 → 2.8.3
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 +4 -4
- data/README.md +1 -1
- data/bin/httpclient +7 -1
- data/lib/http-access2.rb +1 -1
- data/lib/httpclient/auth.rb +3 -3
- data/lib/httpclient/cacert.pem +3952 -0
- data/lib/httpclient/connection.rb +1 -1
- data/lib/httpclient/cookie.rb +10 -10
- data/lib/httpclient/http.rb +9 -4
- data/lib/httpclient/jruby_ssl_socket.rb +588 -0
- data/lib/httpclient/session.rb +199 -262
- data/lib/httpclient/ssl_config.rb +123 -114
- data/lib/httpclient/ssl_socket.rb +150 -0
- data/lib/httpclient/timeout.rb +1 -1
- data/lib/httpclient/util.rb +33 -1
- data/lib/httpclient/version.rb +1 -1
- data/lib/httpclient/webagent-cookie.rb +2 -2
- data/lib/httpclient.rb +72 -20
- data/lib/oauthclient.rb +2 -1
- data/test/helper.rb +7 -5
- data/test/jruby_ssl_socket/test_pemutils.rb +32 -0
- data/test/test_auth.rb +28 -9
- data/test/test_cookie.rb +2 -2
- data/test/test_http-access2.rb +2 -0
- data/test/test_httpclient.rb +143 -23
- data/test/test_ssl.rb +295 -17
- data/test/test_webagent-cookie.rb +2 -2
- metadata +14 -10
- /data/lib/httpclient/{cacert.p7s → cacert1024.pem} +0 -0
- /data/test/{ca-chain.cert → ca-chain.pem} +0 -0
data/test/test_ssl.rb
CHANGED
@@ -4,13 +4,13 @@ require 'webrick/https'
|
|
4
4
|
|
5
5
|
class TestSSL < Test::Unit::TestCase
|
6
6
|
include Helper
|
7
|
+
|
7
8
|
DIR = File.dirname(File.expand_path(__FILE__))
|
8
9
|
|
9
10
|
def setup
|
10
11
|
super
|
11
12
|
@serverpid = @client = nil
|
12
13
|
@verify_callback_called = false
|
13
|
-
@verbose, $VERBOSE = $VERBOSE, nil
|
14
14
|
setup_server
|
15
15
|
setup_client
|
16
16
|
@url = "https://localhost:#{serverport}/hello"
|
@@ -18,13 +18,26 @@ class TestSSL < Test::Unit::TestCase
|
|
18
18
|
|
19
19
|
def teardown
|
20
20
|
super
|
21
|
-
$VERBOSE = @verbose
|
22
21
|
end
|
23
22
|
|
24
23
|
def path(filename)
|
25
24
|
File.expand_path(filename, DIR)
|
26
25
|
end
|
27
26
|
|
27
|
+
def test_proxy_ssl
|
28
|
+
setup_proxyserver
|
29
|
+
escape_noproxy do
|
30
|
+
@client.proxy = proxyurl
|
31
|
+
@client.ssl_config.set_client_cert_file(path('client.cert'), path('client.key'))
|
32
|
+
@client.ssl_config.add_trust_ca(path('ca.cert'))
|
33
|
+
@client.ssl_config.add_trust_ca(path('subca.cert'))
|
34
|
+
@client.debug_dev = str = ""
|
35
|
+
assert_equal(200, @client.get(@url).status)
|
36
|
+
assert(/accept/ =~ @proxyio.string, 'proxy is not used')
|
37
|
+
assert(/Host: localhost:#{serverport}/ =~ str)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
28
41
|
def test_options
|
29
42
|
cfg = @client.ssl_config
|
30
43
|
assert_nil(cfg.client_cert)
|
@@ -41,6 +54,8 @@ class TestSSL < Test::Unit::TestCase
|
|
41
54
|
assert_instance_of(OpenSSL::X509::Store, cfg.cert_store)
|
42
55
|
end
|
43
56
|
|
57
|
+
unless defined?(HTTPClient::JRubySSLSocket)
|
58
|
+
# JRubySSLSocket does not support sync mode.
|
44
59
|
def test_sync
|
45
60
|
cfg = @client.ssl_config
|
46
61
|
cfg.set_client_cert_file(path('client.cert'), path('client.key'))
|
@@ -52,18 +67,29 @@ class TestSSL < Test::Unit::TestCase
|
|
52
67
|
@client.reset_all
|
53
68
|
assert_equal("hello", @client.get_content(@url))
|
54
69
|
end
|
70
|
+
end
|
55
71
|
|
56
72
|
def test_debug_dev
|
57
73
|
str = @client.debug_dev = ''
|
58
74
|
cfg = @client.ssl_config
|
59
|
-
cfg.client_cert =
|
60
|
-
cfg.client_key =
|
75
|
+
cfg.client_cert = path("client.cert")
|
76
|
+
cfg.client_key = path("client.key")
|
61
77
|
cfg.add_trust_ca(path('ca.cert'))
|
62
78
|
cfg.add_trust_ca(path('subca.cert'))
|
63
79
|
assert_equal("hello", @client.get_content(@url))
|
64
80
|
assert(str.scan(/^hello$/)[0])
|
65
81
|
end
|
66
82
|
|
83
|
+
def test_verification_without_httpclient
|
84
|
+
raw_cert = "-----BEGIN CERTIFICATE-----\nMIIDOTCCAiGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB\nGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5\nIENBMB4XDTE2MDgxMDE3MjEzNFoXDTE3MDgxMDE3MjEzNFowSzETMBEGCgmSJomT\n8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEZMBcGA1UEAwwQ\nUnVieSBjZXJ0aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB\nAJCfsSXpSMpmZCVa+ZCM+QDgomnhDlvnrGDq6pasTaIspGTXgws+7r8Dt/cNe6EH\nHJpRH2cGRiO4yPcfcT9eS4X7k8OC4f33wHfACOmLu6LeoNE8ujmSk6L6WzLUI+sE\nnLZbFrXxoAo4XHsm8vEG9C+jEoXZ1p+47wrAGaDwDQTnzlMy4dT9pRQEJP2G/Rry\nUkuZn8SUWmh3/YS78iaSzsNF1cgE1ealHOrPPFDjiCGDaH/LHyUPYlbFSLZ/B7Qx\nLxi5sePLcywWq/EJrmWpgeVTDjtNijsdKv/A3qkY+fm/oD0pzt7XsfJaP9YKNyJO\nQFdxWZeiPcDF+Hwf+IwSr+kCAwEAAaMxMC8wDgYDVR0PAQH/BAQDAgeAMB0GA1Ud\nDgQWBBQNvzYzJyXemGhxbA8NMXLolDnPyjANBgkqhkiG9w0BAQsFAAOCAQEARIJV\noKejGlOTn71QutnNnu07UtTu0IHs6YqjYzzND+m4JXLN+wvYm72AFUG0b1L7dRg0\niK8XjQrlNQNVqP1Mc6tffchy20neOPOHeiO6qTdRU8P2S8D3Uwe+1qhgxjfE+cWc\nwZmWxYK4HA8c58PxWMqrkr2QqXDplG9KWLvOgrtPGiLLZcQSKhvvB63QzItHBDU6\nRayiJY3oPkK/HrIvFlySqFqzWmuyknkciOFywEHQMz/tcSFJ2QFpPj/tBz9VXohH\nZ8KscmfhZrTPBjo+ky1lz/WraWoz4LMiLnkC2ABczWLRSawu+v3Irx1NFJngt05e\npqwtqIUeg7j+JLiTaA==\n-----END CERTIFICATE-----"
|
85
|
+
raw_ca_cert = "-----BEGIN CERTIFICATE-----\nMIIDYjCCAkqgAwIBAgIBATANBgkqhkiG9w0BAQsFADBCMRMwEQYKCZImiZPyLGQB\nGRYDb3JnMRkwFwYKCZImiZPyLGQBGRYJcnVieS1sYW5nMRAwDgYDVQQDDAdSdWJ5\nIENBMB4XDTE2MDgxMDE3MjA1NFoXDTE4MDgxMDE3MjA1NFowQjETMBEGCgmSJomT\n8ixkARkWA29yZzEZMBcGCgmSJomT8ixkARkWCXJ1YnktbGFuZzEQMA4GA1UEAwwH\nUnVieSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALKGwyM3Ejtl\npo7CqaDlS71gDZn3gm6IwWpmRMLJofSI9LCwAbjijSC2HvO0xUWoYW40FbzjnnEi\ngszsWyPwuQIx9t0bhuAyllNIfImmkaQkrikXKBKzia4jPnbc4iXPnfjuThjESFWl\ntfbN6y1B5TjKhD1KelfakUO+iMu8WlIA9NKQZYfJ/F3QSpP5Iqb3KN/jVifFbDV8\nbAl3Ln4rT2kTCKrZZcl1jmWsJv8jBw6+P7hk0/Mu0JeHAITsjbNbpHd8UXpCfbVs\nsNGZrBU4uJdZ2YTG+Y27/t25jFNQwb+TWbvig7rfdX2sjssuxa00BBxarC08tIVj\nZprM37KcNn8CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\nAQYwHQYDVR0OBBYEFA2/NjMnJd6YaHFsDw0xcuiUOc/KMB8GA1UdIwQYMBYEFA2/\nNjMnJd6YaHFsDw0xcuiUOc/KMA0GCSqGSIb3DQEBCwUAA4IBAQAJSOw49XqvUll0\n3vU9EAO6yUdeZSsQENIfYbRMQgapbnN1vTyrUjPZkGC5hIE1pVdoHtEoUEICxIwy\nr6BKxiSLBDLp+rvIuDdzMkXIWdUVvTZguVRyKtM2gfnpsPLpVnv+stBmAW2SMyxm\nkymhOpkjdv3He+45uorB3tdfBS9VVomDEUJdg38UE1b5eXRQ3D6gG0iCPFzKszXg\nLoAYhGxtjCJaKlbzduMK0YO6aelgW1+XnVIKcA7DJ9egk5d/dFZBPFfwumwr9hTH\nh7/fp3Fr87weI+CkfmFyJZrsEBlXJBVuvPesMVHTh3Whm5kmCdWcBJU0QmSq42ZL\n72U0PXLR\n-----END CERTIFICATE-----"
|
86
|
+
ca_cert = ::OpenSSL::X509::Certificate.new(raw_ca_cert)
|
87
|
+
cert = ::OpenSSL::X509::Certificate.new(raw_cert)
|
88
|
+
store = ::OpenSSL::X509::Store.new
|
89
|
+
store.add_cert(ca_cert)
|
90
|
+
assert(store.verify(cert))
|
91
|
+
end
|
92
|
+
|
67
93
|
def test_verification
|
68
94
|
cfg = @client.ssl_config
|
69
95
|
cfg.verify_callback = method(:verify_callback).to_proc
|
@@ -72,18 +98,18 @@ class TestSSL < Test::Unit::TestCase
|
|
72
98
|
@client.get(@url)
|
73
99
|
assert(false)
|
74
100
|
rescue OpenSSL::SSL::SSLError => ssle
|
75
|
-
assert_match(/certificate verify failed/, ssle.message)
|
101
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
76
102
|
assert(@verify_callback_called)
|
77
103
|
end
|
78
104
|
#
|
79
|
-
cfg.client_cert =
|
80
|
-
cfg.client_key =
|
105
|
+
cfg.client_cert = path("client.cert")
|
106
|
+
cfg.client_key = path("client.key")
|
81
107
|
@verify_callback_called = false
|
82
108
|
begin
|
83
109
|
@client.get(@url)
|
84
110
|
assert(false)
|
85
111
|
rescue OpenSSL::SSL::SSLError => ssle
|
86
|
-
assert_match(/certificate verify failed/, ssle.message)
|
112
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
87
113
|
assert(@verify_callback_called)
|
88
114
|
end
|
89
115
|
#
|
@@ -93,7 +119,7 @@ class TestSSL < Test::Unit::TestCase
|
|
93
119
|
@client.get(@url)
|
94
120
|
assert(false)
|
95
121
|
rescue OpenSSL::SSL::SSLError => ssle
|
96
|
-
assert_match(/certificate verify failed/, ssle.message)
|
122
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
97
123
|
assert(@verify_callback_called)
|
98
124
|
end
|
99
125
|
#
|
@@ -102,16 +128,16 @@ class TestSSL < Test::Unit::TestCase
|
|
102
128
|
assert_equal("hello", @client.get_content(@url))
|
103
129
|
assert(@verify_callback_called)
|
104
130
|
#
|
105
|
-
|
106
|
-
#
|
107
|
-
#
|
131
|
+
if false
|
132
|
+
# JRubySSLSocket does not support depth.
|
133
|
+
# Also on travis environment, verify_depth seems to not work properly.
|
108
134
|
cfg.verify_depth = 1 # 2 required: root-sub
|
109
135
|
@verify_callback_called = false
|
110
136
|
begin
|
111
137
|
@client.get(@url)
|
112
138
|
assert(false, "verify_depth is not supported? #{OpenSSL::OPENSSL_VERSION}")
|
113
139
|
rescue OpenSSL::SSL::SSLError => ssle
|
114
|
-
assert_match(/certificate verify failed/, ssle.message)
|
140
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
115
141
|
assert(@verify_callback_called)
|
116
142
|
end
|
117
143
|
#
|
@@ -128,13 +154,62 @@ end
|
|
128
154
|
@client.get_content(@url)
|
129
155
|
assert(false)
|
130
156
|
rescue OpenSSL::SSL::SSLError => ssle
|
131
|
-
assert_match(/certificate verify failed/, ssle.message)
|
157
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
132
158
|
end
|
133
159
|
#
|
134
160
|
cfg.verify_mode = nil
|
135
161
|
assert_equal("hello", @client.get_content(@url))
|
162
|
+
cfg.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
163
|
+
assert_equal("hello", @client.get_content(@url))
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_cert_store
|
167
|
+
cfg = @client.ssl_config
|
168
|
+
cfg.cert_store.add_cert(cert('ca.cert'))
|
169
|
+
begin
|
170
|
+
@client.get(@url)
|
171
|
+
assert(false)
|
172
|
+
rescue OpenSSL::SSL::SSLError => ssle
|
173
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
174
|
+
end
|
175
|
+
#
|
176
|
+
cfg.cert_store.add_cert(cert('subca.cert'))
|
177
|
+
assert_equal("hello", @client.get_content(@url))
|
178
|
+
cfg.clear_cert_store
|
179
|
+
begin
|
180
|
+
@client.get(@url)
|
181
|
+
assert(false)
|
182
|
+
rescue OpenSSL::SSL::SSLError => ssle
|
183
|
+
assert_match(/(certificate verify failed|unable to find valid certification path to requested target)/, ssle.message)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
if defined?(HTTPClient::JRubySSLSocket)
|
188
|
+
def test_ciphers
|
189
|
+
cfg = @client.ssl_config
|
190
|
+
cfg.set_client_cert_file(path('client.cert'), path('client-pass.key'), 'pass4key')
|
191
|
+
cfg.add_trust_ca(path('ca.cert'))
|
192
|
+
cfg.add_trust_ca(path('subca.cert'))
|
193
|
+
cfg.timeout = 123
|
194
|
+
assert_equal("hello", @client.get_content(@url))
|
195
|
+
#
|
196
|
+
cfg.ciphers = []
|
197
|
+
begin
|
198
|
+
@client.get(@url)
|
199
|
+
assert(false)
|
200
|
+
rescue OpenSSL::SSL::SSLError => ssle
|
201
|
+
assert_match(/No appropriate protocol/, ssle.message)
|
202
|
+
end
|
203
|
+
#
|
204
|
+
cfg.ciphers = %w(TLS_RSA_WITH_AES_128_CBC_SHA)
|
205
|
+
assert_equal("hello", @client.get_content(@url))
|
206
|
+
#
|
207
|
+
cfg.ciphers = HTTPClient::SSLConfig::CIPHERS_DEFAULT
|
208
|
+
assert_equal("hello", @client.get_content(@url))
|
136
209
|
end
|
137
210
|
|
211
|
+
else
|
212
|
+
|
138
213
|
def test_ciphers
|
139
214
|
cfg = @client.ssl_config
|
140
215
|
cfg.set_client_cert_file(path('client.cert'), path('client-pass.key'), 'pass4key')
|
@@ -157,13 +232,14 @@ end
|
|
157
232
|
cfg.ciphers = "DEFAULT"
|
158
233
|
assert_equal("hello", @client.get_content(@url))
|
159
234
|
end
|
235
|
+
end
|
160
236
|
|
161
237
|
def test_set_default_paths
|
162
238
|
assert_raise(OpenSSL::SSL::SSLError) do
|
163
239
|
@client.get(@url)
|
164
240
|
end
|
165
241
|
escape_env do
|
166
|
-
ENV['SSL_CERT_FILE'] = File.join(DIR, 'ca-chain.
|
242
|
+
ENV['SSL_CERT_FILE'] = File.join(DIR, 'ca-chain.pem')
|
167
243
|
@client.ssl_config.set_default_paths
|
168
244
|
@client.get(@url)
|
169
245
|
end
|
@@ -180,13 +256,177 @@ end
|
|
180
256
|
|
181
257
|
def test_allow_tlsv1
|
182
258
|
teardown_server
|
183
|
-
|
259
|
+
setup_server_with_ssl_version(:TLSv1)
|
260
|
+
assert_nothing_raised do
|
261
|
+
@client.ssl_config.verify_mode = nil
|
262
|
+
@client.get("https://localhost:#{serverport}/hello")
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_use_higher_TLS
|
267
|
+
omit('TODO: it does not pass with Java 7 or old openssl ')
|
268
|
+
teardown_server
|
269
|
+
setup_server_with_ssl_version('TLSv1_2')
|
184
270
|
assert_nothing_raised do
|
185
271
|
@client.ssl_config.verify_mode = nil
|
186
272
|
@client.get("https://localhost:#{serverport}/hello")
|
273
|
+
# TODO: should check JRubySSLSocket.ssl_socket.getSession.getProtocol
|
274
|
+
# but it's not thread safe. How can I return protocol version to the caller?
|
187
275
|
end
|
188
276
|
end
|
189
277
|
|
278
|
+
VERIFY_TEST_CERT_LOCALHOST = OpenSSL::X509::Certificate.new(<<-EOS)
|
279
|
+
-----BEGIN CERTIFICATE-----
|
280
|
+
MIIB9jCCAV+gAwIBAgIJAIH8Gsm4PcNKMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
281
|
+
BAMMCWxvY2FsaG9zdDAeFw0xNjA4MTgxMDI2MDVaFw00NDAxMDMxMDI2MDVaMBQx
|
282
|
+
EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
|
283
|
+
p7D8q0lcx5EZEV5+zPnQsxrbft5xyhH/MCStbH46DRATGPNSOaLRCG5r8gTKQzpD
|
284
|
+
4swGrQFYe2ienQ+7o4aEHErsXp4O/EmDKeiXWWrMqPr23r3HOBDebuynC/sCwy7N
|
285
|
+
epnX9u1VLB03eo+suj4d86OoOF+o11t9ZP+GA29Rsf8CAwEAAaNQME4wHQYDVR0O
|
286
|
+
BBYEFIxsJuPVvd5KKFcAvHGSeKSsWiUJMB8GA1UdIwQYMBaAFIxsJuPVvd5KKFcA
|
287
|
+
vHGSeKSsWiUJMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADgYEAMJaVCrrM
|
288
|
+
SM2I06Vr4BL+jtDFhZh3HmJFEDpwEFQ5Y9hduwdUGRBGCpkuea3fE2FKwWW9gLM1
|
289
|
+
w7rFMzYFtCEqm78dJWIU79MRy0wjO4LgtYfoikgBh6JKWuV5ed/+L3sLyLG0ZTtv
|
290
|
+
lrD7lzDtXgwvj007PxDoYRp3JwYzKRmTbH8=
|
291
|
+
-----END CERTIFICATE-----
|
292
|
+
EOS
|
293
|
+
|
294
|
+
VERIFY_TEST_CERT_FOO_DOMAIN = OpenSSL::X509::Certificate.new(<<-EOS)
|
295
|
+
-----BEGIN CERTIFICATE-----
|
296
|
+
MIIB8jCCAVugAwIBAgIJAL/od7Whx7VTMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNV
|
297
|
+
BAMMB2Zvby5jb20wHhcNMTYwODE4MTAyMzUyWhcNNDQwMTAzMTAyMzUyWjASMRAw
|
298
|
+
DgYDVQQDDAdmb28uY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnsPyr
|
299
|
+
SVzHkRkRXn7M+dCzGtt+3nHKEf8wJK1sfjoNEBMY81I5otEIbmvyBMpDOkPizAat
|
300
|
+
AVh7aJ6dD7ujhoQcSuxeng78SYMp6JdZasyo+vbevcc4EN5u7KcL+wLDLs16mdf2
|
301
|
+
7VUsHTd6j6y6Ph3zo6g4X6jXW31k/4YDb1Gx/wIDAQABo1AwTjAdBgNVHQ4EFgQU
|
302
|
+
jGwm49W93kooVwC8cZJ4pKxaJQkwHwYDVR0jBBgwFoAUjGwm49W93kooVwC8cZJ4
|
303
|
+
pKxaJQkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOBgQCVKTvfxx+yezuR
|
304
|
+
5WpVKw1E9qabKOYFB5TqdHMHreRubMJTaoZC+YzhcCwtyLlAA9+axKINAiMM8T+z
|
305
|
+
jjfOHQSa2GS2TaaVDJWmXIgsAlEbjd2BEiQF0LZYGJRG9pyq0WbTV+CyFdrghjcO
|
306
|
+
xX/t7OG7NfOG9dhv3J+5SX10S5V5Dg==
|
307
|
+
-----END CERTIFICATE-----
|
308
|
+
EOS
|
309
|
+
|
310
|
+
VERIFY_TEST_CERT_ALT_NAME = OpenSSL::X509::Certificate.new(<<-EOS)
|
311
|
+
-----BEGIN CERTIFICATE-----
|
312
|
+
MIICDDCCAXWgAwIBAgIJAOxXY4nOwxhGMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
313
|
+
BAMMCWxvY2FsaG9zdDAeFw0xNjA4MTgxMDM0NTJaFw00NDAxMDMxMDM0NTJaMBQx
|
314
|
+
EjAQBgNVBAMMCWxvY2FsaG9zdDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA
|
315
|
+
p7D8q0lcx5EZEV5+zPnQsxrbft5xyhH/MCStbH46DRATGPNSOaLRCG5r8gTKQzpD
|
316
|
+
4swGrQFYe2ienQ+7o4aEHErsXp4O/EmDKeiXWWrMqPr23r3HOBDebuynC/sCwy7N
|
317
|
+
epnX9u1VLB03eo+suj4d86OoOF+o11t9ZP+GA29Rsf8CAwEAAaNmMGQwFAYDVR0R
|
318
|
+
BA0wC4IJKi5mb28uY29tMB0GA1UdDgQWBBSMbCbj1b3eSihXALxxknikrFolCTAf
|
319
|
+
BgNVHSMEGDAWgBSMbCbj1b3eSihXALxxknikrFolCTAMBgNVHRMEBTADAQH/MA0G
|
320
|
+
CSqGSIb3DQEBCwUAA4GBADJlKNFuOnsDIhHGW72HuQw4naN6lM3eZE9JJ+UF/XIF
|
321
|
+
ghGtgqw+00Yy5wMFc1K2Wm4p5NymmDfC/P1FOe34bpxt9/IWm6mEoIWoodC3N4Cm
|
322
|
+
PtnSS1/CRWzVIPGMglTGGDcUc70tfeAWgyTxgcNQd4vTFtnN0f0RDdaXa8kfKMTw
|
323
|
+
-----END CERTIFICATE-----
|
324
|
+
EOS
|
325
|
+
|
326
|
+
VERIFY_TEST_PKEY = OpenSSL::PKey::RSA.new(<<-EOS)
|
327
|
+
-----BEGIN RSA PRIVATE KEY-----
|
328
|
+
MIICXQIBAAKBgQCnsPyrSVzHkRkRXn7M+dCzGtt+3nHKEf8wJK1sfjoNEBMY81I5
|
329
|
+
otEIbmvyBMpDOkPizAatAVh7aJ6dD7ujhoQcSuxeng78SYMp6JdZasyo+vbevcc4
|
330
|
+
EN5u7KcL+wLDLs16mdf27VUsHTd6j6y6Ph3zo6g4X6jXW31k/4YDb1Gx/wIDAQAB
|
331
|
+
AoGAe0RHx+WKtQx8/96VmTl951qzxMPho2etTYd4kAsNwzJwx2N9qu57eBYrdWF+
|
332
|
+
CQMYievucFhP4Y+bINtC1Eb6btz9TCUwjCfeIxfGRoFf3cxVmxlsRJJmN1kSZlu1
|
333
|
+
yYlcMVuP4noeFIMQBRrt5pyLCx2Z9A01NCQT4Y6VoREBIeECQQDWeNhsL6xkrmdB
|
334
|
+
M9+zl+SqHdNKhgKwMdp74+UNnAV9I8GB7bGlOWhc83aqMLgS+JBDFXcmNF/KawTR
|
335
|
+
zcnkod5xAkEAyClFgr3lZQSnwUwoA/AOcyW0+H63taaaXS/g8n3H8ENK6kL4ldUx
|
336
|
+
IgCk2ekbQ5Y3S2WScIGXNxMOza9MlsOvbwJAPUtoPvMZB+U4KVBT/JXKijvf6QqH
|
337
|
+
tidpU8L78XnHr84KPcHa5WeUxgvmvBkUYoebYzC9TrPlNIqFZBi2PJtuYQJBAMda
|
338
|
+
E5j7eJT75fhm2RPS6xFT5MH5sw6AOA3HucrJ63AoFVzsBpl0E9NBwO4ndLgDzF6T
|
339
|
+
cx4Kc4iuunewuB8QFpECQQCfvsHCjIJ/X4kiqeBzxDq2GR/oDgQkOzY+4H9U7Lwl
|
340
|
+
e61RBaxk5OHOA0bLtvJblV6NL72ZEZhX60wAWbrOPhpT
|
341
|
+
-----END RSA PRIVATE KEY-----
|
342
|
+
EOS
|
343
|
+
|
344
|
+
def test_post_connection_check
|
345
|
+
teardown_server
|
346
|
+
setup_server_with_server_cert(nil, VERIFY_TEST_CERT_LOCALHOST, VERIFY_TEST_PKEY)
|
347
|
+
file = Tempfile.new('cert')
|
348
|
+
File.write(file.path, VERIFY_TEST_CERT_LOCALHOST.to_pem)
|
349
|
+
@client.ssl_config.add_trust_ca(file.path)
|
350
|
+
assert_nothing_raised do
|
351
|
+
@client.get("https://localhost:#{serverport}/hello")
|
352
|
+
end
|
353
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
354
|
+
assert_nothing_raised do
|
355
|
+
@client.get("https://localhost:#{serverport}/hello")
|
356
|
+
end
|
357
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
358
|
+
|
359
|
+
teardown_server
|
360
|
+
setup_server_with_server_cert(nil, VERIFY_TEST_CERT_FOO_DOMAIN, VERIFY_TEST_PKEY)
|
361
|
+
File.write(file.path, VERIFY_TEST_CERT_FOO_DOMAIN.to_pem)
|
362
|
+
@client.ssl_config.add_trust_ca(file.path)
|
363
|
+
assert_raises(OpenSSL::SSL::SSLError) do
|
364
|
+
@client.get("https://localhost:#{serverport}/hello")
|
365
|
+
end
|
366
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
367
|
+
assert_nothing_raised do
|
368
|
+
@client.get("https://localhost:#{serverport}/hello")
|
369
|
+
end
|
370
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
371
|
+
|
372
|
+
teardown_server
|
373
|
+
setup_server_with_server_cert(nil, VERIFY_TEST_CERT_ALT_NAME, VERIFY_TEST_PKEY)
|
374
|
+
File.write(file.path, VERIFY_TEST_CERT_ALT_NAME.to_pem)
|
375
|
+
@client.ssl_config.add_trust_ca(file.path)
|
376
|
+
assert_raises(OpenSSL::SSL::SSLError) do
|
377
|
+
@client.get("https://localhost:#{serverport}/hello")
|
378
|
+
end
|
379
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
380
|
+
assert_nothing_raised do
|
381
|
+
@client.get("https://localhost:#{serverport}/hello")
|
382
|
+
end
|
383
|
+
@client.ssl_config.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
384
|
+
end
|
385
|
+
|
386
|
+
def test_x509_store_add_cert_prepend
|
387
|
+
store = OpenSSL::X509::Store.new
|
388
|
+
assert_equal(store, store.add_cert(OpenSSL::X509::Certificate.new(VERIFY_TEST_CERT_LOCALHOST)))
|
389
|
+
end
|
390
|
+
|
391
|
+
def test_tcp_keepalive
|
392
|
+
@client.tcp_keepalive = true
|
393
|
+
@client.ssl_config.add_trust_ca(path('ca-chain.pem'))
|
394
|
+
@client.get_content(@url)
|
395
|
+
|
396
|
+
# expecting HTTP keepalive caches the socket
|
397
|
+
session = @client.instance_variable_get(:@session_manager).send(:get_cached_session, HTTPClient::Site.new(URI.parse(@url)))
|
398
|
+
socket = session.instance_variable_get(:@socket).instance_variable_get(:@socket)
|
399
|
+
|
400
|
+
assert_true(session.tcp_keepalive)
|
401
|
+
if RUBY_ENGINE == 'jruby'
|
402
|
+
assert_true(socket.getKeepAlive())
|
403
|
+
else
|
404
|
+
assert_equal(Socket::SO_KEEPALIVE, socket.getsockopt(Socket::SOL_SOCKET, Socket::SO_KEEPALIVE).optname)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
|
408
|
+
def test_timeout
|
409
|
+
url = "https://localhost:#{serverport}/"
|
410
|
+
@client.ssl_config.add_trust_ca(path('ca-chain.pem'))
|
411
|
+
assert_equal('sleep', @client.get_content(url + 'sleep?sec=2'))
|
412
|
+
@client.receive_timeout = 1
|
413
|
+
@client.reset_all
|
414
|
+
assert_equal('sleep', @client.get_content(url + 'sleep?sec=0'))
|
415
|
+
|
416
|
+
start = Time.now
|
417
|
+
assert_raise(HTTPClient::ReceiveTimeoutError) do
|
418
|
+
@client.get_content(url + 'sleep?sec=5')
|
419
|
+
end
|
420
|
+
if Time.now - start > 3
|
421
|
+
# before #342 it detected timeout when IO was freed
|
422
|
+
fail 'timeout does not work'
|
423
|
+
end
|
424
|
+
|
425
|
+
@client.receive_timeout = 3
|
426
|
+
@client.reset_all
|
427
|
+
assert_equal('sleep', @client.get_content(url + 'sleep?sec=2'))
|
428
|
+
end
|
429
|
+
|
190
430
|
private
|
191
431
|
|
192
432
|
def cert(filename)
|
@@ -219,7 +459,7 @@ private
|
|
219
459
|
:SSLCertName => nil
|
220
460
|
)
|
221
461
|
@serverport = @server.config[:Port]
|
222
|
-
[:hello].each do |sym|
|
462
|
+
[:hello, :sleep].each do |sym|
|
223
463
|
@server.mount(
|
224
464
|
"/#{sym}",
|
225
465
|
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
|
@@ -229,6 +469,10 @@ private
|
|
229
469
|
end
|
230
470
|
|
231
471
|
def setup_server_with_ssl_version(ssl_version)
|
472
|
+
# JRubyOpenSSL does not support "TLSv1_2" as an known version, and some JCE provides TLS v1.2 as "TLSv1.2" not "TLSv1_2"
|
473
|
+
if RUBY_ENGINE == 'jruby' && ['TLSv1_1', 'TLSv1_2'].include?(ssl_version)
|
474
|
+
ssl_version = ssl_version.tr('_', '.')
|
475
|
+
end
|
232
476
|
logger = Logger.new(STDERR)
|
233
477
|
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
|
234
478
|
@server = WEBrick::HTTPServer.new(
|
@@ -253,11 +497,45 @@ private
|
|
253
497
|
@server_thread = start_server_thread(@server)
|
254
498
|
end
|
255
499
|
|
500
|
+
def setup_server_with_server_cert(ca_cert, server_cert, server_key)
|
501
|
+
logger = Logger.new(STDERR)
|
502
|
+
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
|
503
|
+
@server = WEBrick::HTTPServer.new(
|
504
|
+
:BindAddress => "localhost",
|
505
|
+
:Logger => logger,
|
506
|
+
:Port => 0,
|
507
|
+
:AccessLog => [],
|
508
|
+
:DocumentRoot => DIR,
|
509
|
+
:SSLEnable => true,
|
510
|
+
:SSLCACertificateFile => ca_cert,
|
511
|
+
:SSLCertificate => server_cert,
|
512
|
+
:SSLPrivateKey => server_key,
|
513
|
+
:SSLVerifyClient => nil,
|
514
|
+
:SSLClientCA => nil,
|
515
|
+
:SSLCertName => nil
|
516
|
+
)
|
517
|
+
@serverport = @server.config[:Port]
|
518
|
+
[:hello].each do |sym|
|
519
|
+
@server.mount(
|
520
|
+
"/#{sym}",
|
521
|
+
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
|
522
|
+
)
|
523
|
+
end
|
524
|
+
@server_thread = start_server_thread(@server)
|
525
|
+
end
|
526
|
+
|
256
527
|
def do_hello(req, res)
|
257
528
|
res['content-type'] = 'text/html'
|
258
529
|
res.body = "hello"
|
259
530
|
end
|
260
531
|
|
532
|
+
def do_sleep(req, res)
|
533
|
+
sec = req.query['sec'].to_i
|
534
|
+
sleep sec
|
535
|
+
res['content-type'] = 'text/html'
|
536
|
+
res.body = "sleep"
|
537
|
+
end
|
538
|
+
|
261
539
|
def start_server_thread(server)
|
262
540
|
t = Thread.new {
|
263
541
|
Thread.current.abort_on_exception = true
|
@@ -440,8 +440,8 @@ EOF
|
|
440
440
|
def test_load_cookies_escaped
|
441
441
|
uri = urify('http://example.org/')
|
442
442
|
f = Tempfile.new('test_cookie')
|
443
|
-
File.open(f.path, 'w') do |
|
444
|
-
|
443
|
+
File.open(f.path, 'w') do |out|
|
444
|
+
out.write <<EOF
|
445
445
|
http://example.org/ key "value" 0 .example.org / 13 0
|
446
446
|
http://example.org/ key "" .example.org / 13 0
|
447
447
|
http://example.org/ key .example.org / 13 0
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpclient
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Hiroshi Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: nahi@ruby-lang.org
|
@@ -17,25 +17,29 @@ executables:
|
|
17
17
|
extensions: []
|
18
18
|
extra_rdoc_files: []
|
19
19
|
files:
|
20
|
+
- README.md
|
20
21
|
- bin/httpclient
|
21
22
|
- bin/jsonclient
|
22
23
|
- lib/hexdump.rb
|
24
|
+
- lib/http-access2.rb
|
23
25
|
- lib/http-access2/cookie.rb
|
24
26
|
- lib/http-access2/http.rb
|
25
|
-
- lib/
|
27
|
+
- lib/httpclient.rb
|
26
28
|
- lib/httpclient/auth.rb
|
27
|
-
- lib/httpclient/cacert.
|
29
|
+
- lib/httpclient/cacert.pem
|
30
|
+
- lib/httpclient/cacert1024.pem
|
28
31
|
- lib/httpclient/connection.rb
|
29
32
|
- lib/httpclient/cookie.rb
|
30
33
|
- lib/httpclient/http.rb
|
31
34
|
- lib/httpclient/include_client.rb
|
35
|
+
- lib/httpclient/jruby_ssl_socket.rb
|
32
36
|
- lib/httpclient/session.rb
|
33
37
|
- lib/httpclient/ssl_config.rb
|
38
|
+
- lib/httpclient/ssl_socket.rb
|
34
39
|
- lib/httpclient/timeout.rb
|
35
40
|
- lib/httpclient/util.rb
|
36
41
|
- lib/httpclient/version.rb
|
37
42
|
- lib/httpclient/webagent-cookie.rb
|
38
|
-
- lib/httpclient.rb
|
39
43
|
- lib/jsonclient.rb
|
40
44
|
- lib/oauthclient.rb
|
41
45
|
- sample/async.rb
|
@@ -57,7 +61,7 @@ files:
|
|
57
61
|
- sample/stream.rb
|
58
62
|
- sample/thread.rb
|
59
63
|
- sample/wcat.rb
|
60
|
-
- test/ca-chain.
|
64
|
+
- test/ca-chain.pem
|
61
65
|
- test/ca.cert
|
62
66
|
- test/client-pass.key
|
63
67
|
- test/client.cert
|
@@ -65,6 +69,7 @@ files:
|
|
65
69
|
- test/helper.rb
|
66
70
|
- test/htdigest
|
67
71
|
- test/htpasswd
|
72
|
+
- test/jruby_ssl_socket/test_pemutils.rb
|
68
73
|
- test/runner.rb
|
69
74
|
- test/server.cert
|
70
75
|
- test/server.key
|
@@ -79,7 +84,6 @@ files:
|
|
79
84
|
- test/test_jsonclient.rb
|
80
85
|
- test/test_ssl.rb
|
81
86
|
- test/test_webagent-cookie.rb
|
82
|
-
- README.md
|
83
87
|
homepage: https://github.com/nahi/httpclient
|
84
88
|
licenses:
|
85
89
|
- ruby
|
@@ -90,17 +94,17 @@ require_paths:
|
|
90
94
|
- lib
|
91
95
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
96
|
requirements:
|
93
|
-
- -
|
97
|
+
- - ">="
|
94
98
|
- !ruby/object:Gem::Version
|
95
99
|
version: '0'
|
96
100
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
97
101
|
requirements:
|
98
|
-
- -
|
102
|
+
- - ">="
|
99
103
|
- !ruby/object:Gem::Version
|
100
104
|
version: '0'
|
101
105
|
requirements: []
|
102
106
|
rubyforge_project:
|
103
|
-
rubygems_version: 2.
|
107
|
+
rubygems_version: 2.6.8
|
104
108
|
signing_key:
|
105
109
|
specification_version: 4
|
106
110
|
summary: gives something like the functionality of libwww-perl (LWP) in Ruby
|
File without changes
|
File without changes
|