bterlson-httpclient 2.1.4
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.
- data/README.txt +368 -0
- data/VERSION.yml +4 -0
- data/lib/http-access2.rb +53 -0
- data/lib/http-access2/cookie.rb +1 -0
- data/lib/http-access2/http.rb +1 -0
- data/lib/httpclient.rb +1016 -0
- data/lib/httpclient/auth.rb +511 -0
- data/lib/httpclient/cacert.p7s +939 -0
- data/lib/httpclient/connection.rb +84 -0
- data/lib/httpclient/cookie.rb +560 -0
- data/lib/httpclient/http.rb +863 -0
- data/lib/httpclient/session.rb +855 -0
- data/lib/httpclient/ssl_config.rb +379 -0
- data/lib/httpclient/timeout.rb +136 -0
- data/lib/httpclient/util.rb +86 -0
- data/test/ca.cert +23 -0
- data/test/client.cert +19 -0
- data/test/client.key +15 -0
- data/test/htdigest +1 -0
- data/test/htpasswd +2 -0
- data/test/runner.rb +2 -0
- data/test/server.cert +19 -0
- data/test/server.key +15 -0
- data/test/sslsvr.rb +65 -0
- data/test/subca.cert +21 -0
- data/test/test_auth.rb +160 -0
- data/test/test_cookie.rb +352 -0
- data/test/test_http-access2.rb +560 -0
- data/test/test_httpclient.rb +1160 -0
- data/test/test_ssl.rb +199 -0
- metadata +86 -0
@@ -0,0 +1,86 @@
|
|
1
|
+
# HTTPClient - HTTP client library.
|
2
|
+
# Copyright (C) 2000-2009 NAKAMURA, Hiroshi <nahi@ruby-lang.org>.
|
3
|
+
#
|
4
|
+
# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
|
5
|
+
# redistribute it and/or modify it under the same terms of Ruby's license;
|
6
|
+
# either the dual license version in 2003, or any later version.
|
7
|
+
|
8
|
+
|
9
|
+
require 'uri'
|
10
|
+
|
11
|
+
|
12
|
+
class HTTPClient
|
13
|
+
|
14
|
+
|
15
|
+
# A module for common function.
|
16
|
+
module Util
|
17
|
+
# Keyword argument helper.
|
18
|
+
# args:: given arguments.
|
19
|
+
# *field:: a list of arguments to be extracted.
|
20
|
+
#
|
21
|
+
# You can extract 3 arguments (a, b, c) with:
|
22
|
+
#
|
23
|
+
# include Util
|
24
|
+
# def my_method(*args)
|
25
|
+
# a, b, c = keyword_argument(args, :a, :b, :c)
|
26
|
+
# ...
|
27
|
+
# end
|
28
|
+
# my_method(1, 2, 3)
|
29
|
+
# my_method(:b => 2, :a = 1)
|
30
|
+
#
|
31
|
+
# instead of;
|
32
|
+
#
|
33
|
+
# def my_method(a, b, c)
|
34
|
+
# ...
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
def keyword_argument(args, *field)
|
38
|
+
if args.size == 1 and args[0].is_a?(Hash)
|
39
|
+
args[0].values_at(*field)
|
40
|
+
else
|
41
|
+
args
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Gets an URI instance.
|
46
|
+
def urify(uri)
|
47
|
+
if uri.nil?
|
48
|
+
nil
|
49
|
+
elsif uri.is_a?(URI)
|
50
|
+
uri
|
51
|
+
else
|
52
|
+
URI.parse(uri.to_s)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns true if the given 2 URIs have a part_of relationship.
|
57
|
+
# * the same scheme
|
58
|
+
# * the same host String (no host resolution or IP-addr conversion)
|
59
|
+
# * the same port number
|
60
|
+
# * target URI's path starts with base URI's path.
|
61
|
+
def uri_part_of(uri, part)
|
62
|
+
((uri.scheme == part.scheme) and
|
63
|
+
(uri.host == part.host) and
|
64
|
+
(uri.port == part.port) and
|
65
|
+
uri.path.upcase.index(part.path.upcase) == 0)
|
66
|
+
end
|
67
|
+
module_function :uri_part_of
|
68
|
+
|
69
|
+
# Returns parent directory URI of the given URI.
|
70
|
+
def uri_dirname(uri)
|
71
|
+
uri = uri.clone
|
72
|
+
uri.path = uri.path.sub(/\/[^\/]*\z/, '/')
|
73
|
+
uri
|
74
|
+
end
|
75
|
+
module_function :uri_dirname
|
76
|
+
|
77
|
+
# Finds a value of a Hash.
|
78
|
+
def hash_find_value(hash, &block)
|
79
|
+
v = hash.find(&block)
|
80
|
+
v ? v[1] : nil
|
81
|
+
end
|
82
|
+
module_function :hash_find_value
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
end
|
data/test/ca.cert
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIID0DCCArigAwIBAgIBADANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
|
3
|
+
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
4
|
+
DTA0MDEzMDAwNDIzMloXDTM2MDEyMjAwNDIzMlowPDELMAkGA1UEBgwCSlAxEjAQ
|
5
|
+
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQswCQYDVQQDDAJDQTCCASIw
|
6
|
+
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANbv0x42BTKFEQOE+KJ2XmiSdZpR
|
7
|
+
wjzQLAkPLRnLB98tlzs4xo+y4RyY/rd5TT9UzBJTIhP8CJi5GbS1oXEerQXB3P0d
|
8
|
+
L5oSSMwGGyuIzgZe5+vZ1kgzQxMEKMMKlzA73rbMd4Jx3u5+jdbP0EDrPYfXSvLY
|
9
|
+
bS04n2aX7zrN3x5KdDrNBfwBio2/qeaaj4+9OxnwRvYP3WOvqdW0h329eMfHw0pi
|
10
|
+
JI0drIVdsEqClUV4pebT/F+CPUPkEh/weySgo9wANockkYu5ujw2GbLFcO5LXxxm
|
11
|
+
dEfcVr3r6t6zOA4bJwL0W/e6LBcrwiG/qPDFErhwtgTLYf6Er67SzLyA66UCAwEA
|
12
|
+
AaOB3DCB2TAPBgNVHRMBAf8EBTADAQH/MDEGCWCGSAGG+EIBDQQkFiJSdWJ5L09w
|
13
|
+
ZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1UdDgQWBBRJ7Xd380KzBV7f
|
14
|
+
USKIQ+O/vKbhDzAOBgNVHQ8BAf8EBAMCAQYwZAYDVR0jBF0wW4AUSe13d/NCswVe
|
15
|
+
31EiiEPjv7ym4Q+hQKQ+MDwxCzAJBgNVBAYMAkpQMRIwEAYDVQQKDAlKSU4uR1Iu
|
16
|
+
SlAxDDAKBgNVBAsMA1JSUjELMAkGA1UEAwwCQ0GCAQAwDQYJKoZIhvcNAQEFBQAD
|
17
|
+
ggEBAIu/mfiez5XN5tn2jScgShPgHEFJBR0BTJBZF6xCk0jyqNx/g9HMj2ELCuK+
|
18
|
+
r/Y7KFW5c5M3AQ+xWW0ZSc4kvzyTcV7yTVIwj2jZ9ddYMN3nupZFgBK1GB4Y05GY
|
19
|
+
MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
|
20
|
+
PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
|
21
|
+
PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
|
22
|
+
d/xgcK06UVQRL/HbEYGiQL056mc=
|
23
|
+
-----END CERTIFICATE-----
|
data/test/client.cert
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDKDCCAhCgAwIBAgIBAjANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
|
3
|
+
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
4
|
+
DTA0MDEzMTAzMTQ1OFoXDTM1MDEyMzAzMTQ1OFowZTELMAkGA1UEBgwCSlAxEjAQ
|
5
|
+
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRAwDgYDVQQDDAdleGFtcGxl
|
6
|
+
MSIwIAYJKoZIhvcNAQkBDBNleGFtcGxlQGV4YW1wbGUub3JnMIGfMA0GCSqGSIb3
|
7
|
+
DQEBAQUAA4GNADCBiQKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLW
|
8
|
+
jTkvsgOwbYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQ
|
9
|
+
gNS6ew7/Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2Xf
|
10
|
+
ewIDAQABo4GPMIGMMAwGA1UdEwEB/wQCMAAwMQYJYIZIAYb4QgENBCQWIlJ1Ynkv
|
11
|
+
T3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFOFvay0H7lr2
|
12
|
+
xUx6waYEV2bVDYQhMAsGA1UdDwQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYI
|
13
|
+
KwYBBQUHAwQwDQYJKoZIhvcNAQEFBQADggEBABd2dYWqbDIWf5sWFvslezxJv8gI
|
14
|
+
w64KCJBuyJAiDuf+oazr3016kMzAlt97KecLZDusGNagPrq02UX7YMoQFsWJBans
|
15
|
+
cDtHrkM0al5r6/WGexNMgtYbNTYzt/IwodISGBgZ6dsOuhznwms+IBsTNDAvWeLP
|
16
|
+
lt2tOqD8kEmjwMgn0GDRuKjs4EoboA3kMULb1p9akDV9ZESU3eOtpS5/G5J5msLI
|
17
|
+
9WXbYBjcjvkLuJH9VsJhb+R58Vl0ViemvAHhPilSl1SPWVunGhv6FcIkdBEi1k9F
|
18
|
+
e8BNMmsEjFiANiIRvpdLRbiGBt0KrKTndVfsmoKCvY48oCOvnzxtahFxfs8=
|
19
|
+
-----END CERTIFICATE-----
|
data/test/client.key
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICWwIBAAKBgQDRWssrK8Gyr+500hpLjCGR3+AHL8/hEJM5zKi/MgLWjTkvsgOw
|
3
|
+
bYwXOiNtAbR9y4/ucDq7EY+cMUMHES4uFaPTcOaAV0aZRmk8AgslN1tQgNS6ew7/
|
4
|
+
Luq3DcVeWkX8PYgR9VG0mD1MPfJ6+IFA5d3vKpdBkBgN4l46jjO0/2XfewIDAQAB
|
5
|
+
AoGAZcz8llWErtsV3QB9gNb3S/PNADGjqBFjReva8n3jG2k4sZSibpwWTwUaTNtT
|
6
|
+
ZQgjSRKRvH1hk9XwffNAvXAQZNNkuj/16gO2oO45nyLj4dO365ujLptWnVIWDHOE
|
7
|
+
uN0GeiZO+VzcCisT0WCq4tvtLeH8svrxzA8cbXIEyOK7NiECQQDwo2zPFyKAZ/Cu
|
8
|
+
lDJ6zKT+RjfWwW7DgWzirAlTrt4ViMaW+IaDH29TmQpb4V4NuR3Xi+2Xl4oicu6S
|
9
|
+
36TW9+/FAkEA3rgfOQJuLlWSnw1RTGwvnC816a/W7iYYY7B+0U4cDbfWl7IoXT4y
|
10
|
+
M8nV/HESooviZLqBwzAYSoj3fFKYBKpGPwJAUO8GN5iWWA2dW3ooiDiv/X1sZmRk
|
11
|
+
dojfMFWgRW747tEzya8Ivq0h6kH8w+5GjeMG8Gn1nRiwsulo6Ckj7dEx6QJACyui
|
12
|
+
7UIQ8qP6GZ4aYMHgVW4Mvy7Bkeo5OO7GPYs0Xv/EdJFL8vlGnVBXOjUVoS9w6Gpu
|
13
|
+
TbLg1QQvnX2rADjmEwJANxZO2GUkaWGsEif8aGW0x5g/IdaMGG27pTWk5zqix7P3
|
14
|
+
1UDrdo/JOXhptovhRi06EppIxAxYmbh9vd9VN8Itlw==
|
15
|
+
-----END RSA PRIVATE KEY-----
|
data/test/htdigest
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
admin:auth:4302fe65caa32f27721949149ccd3083
|
data/test/htpasswd
ADDED
data/test/runner.rb
ADDED
data/test/server.cert
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIC/zCCAeegAwIBAgIBATANBgkqhkiG9w0BAQUFADA/MQswCQYDVQQGDAJKUDES
|
3
|
+
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxDjAMBgNVBAMMBVN1YkNB
|
4
|
+
MB4XDTA0MDEzMTAzMTMxNloXDTMzMDEyMzAzMTMxNlowQzELMAkGA1UEBgwCSlAx
|
5
|
+
EjAQBgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMRIwEAYDVQQDDAlsb2Nh
|
6
|
+
bGhvc3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANFJTxWqup3nV9dsJAku
|
7
|
+
p+WaXnPNIzcpAA3qMGZDJTJsfa8Du7ZxTP0XJK5mETttBrn711cJxAuP3KjqnW9S
|
8
|
+
vtZ9lY2sXJ6Zj62sN5LwG3VVe25dI28yR1EsbHjJ5Zjf9tmggMC6am52dxuHbt5/
|
9
|
+
vHo4ngJuKE/U+eeGRivMn6gFAgMBAAGjgYUwgYIwDAYDVR0TAQH/BAIwADAxBglg
|
10
|
+
hkgBhvhCAQ0EJBYiUnVieS9PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAd
|
11
|
+
BgNVHQ4EFgQUpZIyygD9JxFYHHOTEuWOLbCKfckwCwYDVR0PBAQDAgWgMBMGA1Ud
|
12
|
+
JQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBBQUAA4IBAQBwAIj5SaBHaA5X31IP
|
13
|
+
CFCJiep96awfp7RANO0cuUj+ZpGoFn9d6FXY0g+Eg5wAkCNIzZU5NHN9xsdOpnUo
|
14
|
+
zIBbyTfQEPrge1CMWMvL6uGaoEXytq84VTitF/xBTky4KtTn6+es4/e7jrrzeUXQ
|
15
|
+
RC46gkHObmDT91RkOEGjHLyld2328jo3DIN/VTHIryDeVHDWjY5dENwpwdkhhm60
|
16
|
+
DR9IrNBbXWEe9emtguNXeN0iu1ux0lG1Hc6pWGQxMlRKNvGh0yZB9u5EVe38tOV0
|
17
|
+
jQaoNyL7qzcQoXD3Dmbi1p0iRmg/+HngISsz8K7k7MBNVsSclztwgCzTZOBiVtkM
|
18
|
+
rRlQ
|
19
|
+
-----END CERTIFICATE-----
|
data/test/server.key
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICXQIBAAKBgQDRSU8Vqrqd51fXbCQJLqflml5zzSM3KQAN6jBmQyUybH2vA7u2
|
3
|
+
cUz9FySuZhE7bQa5+9dXCcQLj9yo6p1vUr7WfZWNrFyemY+trDeS8Bt1VXtuXSNv
|
4
|
+
MkdRLGx4yeWY3/bZoIDAumpudncbh27ef7x6OJ4CbihP1PnnhkYrzJ+oBQIDAQAB
|
5
|
+
AoGBAIf4CstW2ltQO7+XYGoex7Hh8s9lTSW/G2vu5Hbr1LTHy3fzAvdq8MvVR12O
|
6
|
+
rk9fa+lU9vhzPc0NMB0GIDZ9GcHuhW5hD1Wg9OSCbTOkZDoH3CAFqonjh4Qfwv5W
|
7
|
+
IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ
|
8
|
+
Oynzz7/lLizJGGxp2AOvEVtqMoycA/Qk+zdKP8ufE0wbmCE3Qd6GoynavsHb6aGK
|
9
|
+
gQobb8zDZwJBANSK6MrXlrZTtEaeZuyOB4mAmRzGzOUVkUyULUjEx2GDT93ujAma
|
10
|
+
qm/2d3E+wXAkNSeRpjUmlQXy/2oSqnGvYbMCQQDRM+cYyEcGPUVpWpnj0shrF/QU
|
11
|
+
9vSot/X1G775EMTyaw6+BtbyNxVgOIu2J+rqGbn3c+b85XqTXOPL0A2RLYkFAkAm
|
12
|
+
syhSDtE9X55aoWsCNZY/vi+i4rvaFoQ/WleogVQAeGVpdo7/DK9t9YWoFBIqth0L
|
13
|
+
mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH
|
14
|
+
LjLpLLOrgUxqpzLWe++EwSLwK2//dHO+SPsQJ4xsyQJy
|
15
|
+
-----END RSA PRIVATE KEY-----
|
data/test/sslsvr.rb
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'webrick/https'
|
2
|
+
require 'logger'
|
3
|
+
require 'rbconfig'
|
4
|
+
|
5
|
+
PORT = 17171
|
6
|
+
DIR = File.dirname(File.expand_path(__FILE__))
|
7
|
+
|
8
|
+
def cert(filename)
|
9
|
+
OpenSSL::X509::Certificate.new(File.open(File.join(DIR, filename)) { |f|
|
10
|
+
f.read
|
11
|
+
})
|
12
|
+
end
|
13
|
+
|
14
|
+
def key(filename)
|
15
|
+
OpenSSL::PKey::RSA.new(File.open(File.join(DIR, filename)) { |f|
|
16
|
+
f.read
|
17
|
+
})
|
18
|
+
end
|
19
|
+
|
20
|
+
def do_hello(req, res)
|
21
|
+
res['content-type'] = 'text/html'
|
22
|
+
res.body = "hello"
|
23
|
+
end
|
24
|
+
|
25
|
+
logger = Logger.new(STDERR)
|
26
|
+
logger.level = Logger::Severity::FATAL # avoid logging SSLError (ERROR level)
|
27
|
+
|
28
|
+
server = WEBrick::HTTPServer.new(
|
29
|
+
:BindAddress => "localhost",
|
30
|
+
:Logger => logger,
|
31
|
+
:Port => PORT,
|
32
|
+
:AccessLog => [],
|
33
|
+
:DocumentRoot => DIR,
|
34
|
+
:SSLEnable => true,
|
35
|
+
:SSLCACertificateFile => File.join(DIR, 'ca.cert'),
|
36
|
+
:SSLCertificate => cert('server.cert'),
|
37
|
+
:SSLPrivateKey => key('server.key'),
|
38
|
+
:SSLVerifyClient => nil, #OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT|OpenSSL::SSL::VERIFY_PEER,
|
39
|
+
:SSLClientCA => cert('ca.cert'),
|
40
|
+
:SSLCertName => nil
|
41
|
+
)
|
42
|
+
trap(:INT) do
|
43
|
+
server.shutdown
|
44
|
+
end
|
45
|
+
[:hello].each do |sym|
|
46
|
+
server.mount(
|
47
|
+
"/#{sym}",
|
48
|
+
WEBrick::HTTPServlet::ProcHandler.new(method("do_#{sym}").to_proc)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
t = Thread.new {
|
53
|
+
Thread.current.abort_on_exception = true
|
54
|
+
server.start
|
55
|
+
}
|
56
|
+
while server.status != :Running
|
57
|
+
sleep 0.1
|
58
|
+
unless t.alive?
|
59
|
+
t.join
|
60
|
+
raise
|
61
|
+
end
|
62
|
+
end
|
63
|
+
STDOUT.sync = true
|
64
|
+
puts $$
|
65
|
+
t.join
|
data/test/subca.cert
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
|
3
|
+
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
4
|
+
DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
|
5
|
+
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
|
6
|
+
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
|
7
|
+
ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
|
8
|
+
d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
|
9
|
+
kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
|
10
|
+
3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
|
11
|
+
4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
|
12
|
+
AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
|
13
|
+
cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
|
14
|
+
LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
|
15
|
+
rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
|
16
|
+
c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
|
17
|
+
LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
|
18
|
+
ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
|
19
|
+
SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
|
20
|
+
uY/bPeOBYiVsOYVe
|
21
|
+
-----END CERTIFICATE-----
|
data/test/test_auth.rb
ADDED
@@ -0,0 +1,160 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'webrick'
|
3
|
+
require 'logger'
|
4
|
+
require 'httpclient'
|
5
|
+
|
6
|
+
|
7
|
+
class TestAuth < Test::Unit::TestCase
|
8
|
+
Port = 17171
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@logger = Logger.new(STDERR)
|
12
|
+
@logger.level = Logger::Severity::ERROR
|
13
|
+
@url = "http://localhost:#{Port}/"
|
14
|
+
@server = nil
|
15
|
+
@server_thread = nil
|
16
|
+
setup_server
|
17
|
+
end
|
18
|
+
|
19
|
+
def teardown
|
20
|
+
teardown_server
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup_server
|
24
|
+
@server = WEBrick::HTTPServer.new(
|
25
|
+
:BindAddress => "localhost",
|
26
|
+
:Logger => @logger,
|
27
|
+
:Port => Port,
|
28
|
+
:AccessLog => [],
|
29
|
+
:DocumentRoot => File.dirname(File.expand_path(__FILE__))
|
30
|
+
)
|
31
|
+
@server.mount(
|
32
|
+
'/basic_auth',
|
33
|
+
WEBrick::HTTPServlet::ProcHandler.new(method(:do_basic_auth).to_proc)
|
34
|
+
)
|
35
|
+
@server.mount(
|
36
|
+
'/digest_auth',
|
37
|
+
WEBrick::HTTPServlet::ProcHandler.new(method(:do_digest_auth).to_proc)
|
38
|
+
)
|
39
|
+
htpasswd = File.join(File.dirname(__FILE__), 'htpasswd')
|
40
|
+
htpasswd_userdb = WEBrick::HTTPAuth::Htpasswd.new(htpasswd)
|
41
|
+
htdigest = File.join(File.dirname(__FILE__), 'htdigest')
|
42
|
+
htdigest_userdb = WEBrick::HTTPAuth::Htdigest.new(htdigest)
|
43
|
+
@basic_auth = WEBrick::HTTPAuth::BasicAuth.new(
|
44
|
+
:Realm => 'auth',
|
45
|
+
:UserDB => htpasswd_userdb
|
46
|
+
)
|
47
|
+
@digest_auth = WEBrick::HTTPAuth::DigestAuth.new(
|
48
|
+
:Algorithm => 'MD5',
|
49
|
+
:Realm => 'auth',
|
50
|
+
:UserDB => htdigest_userdb
|
51
|
+
)
|
52
|
+
@server_thread = start_server_thread(@server)
|
53
|
+
end
|
54
|
+
|
55
|
+
def start_server_thread(server)
|
56
|
+
t = Thread.new {
|
57
|
+
Thread.current.abort_on_exception = true
|
58
|
+
server.start
|
59
|
+
}
|
60
|
+
while server.status != :Running
|
61
|
+
sleep 0.1
|
62
|
+
unless t.alive?
|
63
|
+
t.join
|
64
|
+
raise
|
65
|
+
end
|
66
|
+
end
|
67
|
+
t
|
68
|
+
end
|
69
|
+
|
70
|
+
def teardown_server
|
71
|
+
@server.shutdown
|
72
|
+
@server_thread.kill
|
73
|
+
@server_thread.join
|
74
|
+
end
|
75
|
+
|
76
|
+
def do_basic_auth(req, res)
|
77
|
+
@basic_auth.authenticate(req, res)
|
78
|
+
res['content-type'] = 'text/plain'
|
79
|
+
res.body = 'basic_auth OK'
|
80
|
+
end
|
81
|
+
|
82
|
+
def do_digest_auth(req, res)
|
83
|
+
@digest_auth.authenticate(req, res)
|
84
|
+
res['content-type'] = 'text/plain'
|
85
|
+
res['x-query'] = req.body
|
86
|
+
res.body = 'digest_auth OK'
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_basic_auth
|
90
|
+
c = HTTPClient.new
|
91
|
+
c.set_auth("http://localhost:#{Port}/", 'admin', 'admin')
|
92
|
+
assert_equal('basic_auth OK', c.get_content("http://localhost:#{Port}/basic_auth"))
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_basic_auth_compat
|
96
|
+
c = HTTPClient.new
|
97
|
+
c.set_basic_auth("http://localhost:#{Port}/", 'admin', 'admin')
|
98
|
+
assert_equal('basic_auth OK', c.get_content("http://localhost:#{Port}/basic_auth"))
|
99
|
+
end
|
100
|
+
|
101
|
+
def test_BASIC_auth
|
102
|
+
c = HTTPClient.new
|
103
|
+
webrick_backup = @basic_auth.instance_eval { @auth_scheme }
|
104
|
+
#httpaccess2_backup = c.www_auth.basic_auth.instance_eval { @scheme }
|
105
|
+
begin
|
106
|
+
@basic_auth.instance_eval { @auth_scheme = "BASIC" }
|
107
|
+
c.www_auth.basic_auth.instance_eval { @scheme = "BASIC" }
|
108
|
+
c.set_auth("http://localhost:#{Port}/", 'admin', 'admin')
|
109
|
+
assert_equal('basic_auth OK', c.get_content("http://localhost:#{Port}/basic_auth"))
|
110
|
+
ensure
|
111
|
+
@basic_auth.instance_eval { @auth_scheme = webrick_backup }
|
112
|
+
#c.www_auth.basic_auth.instance_eval { @scheme = httpaccess2_backup }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_digest_auth
|
117
|
+
c = HTTPClient.new
|
118
|
+
c.set_auth("http://localhost:#{Port}/", 'admin', 'admin')
|
119
|
+
assert_equal('digest_auth OK', c.get_content("http://localhost:#{Port}/digest_auth"))
|
120
|
+
end
|
121
|
+
|
122
|
+
def test_digest_auth_with_block
|
123
|
+
c = HTTPClient.new
|
124
|
+
c.set_auth("http://localhost:#{Port}/", 'admin', 'admin')
|
125
|
+
called = false
|
126
|
+
c.get_content("http://localhost:#{Port}/digest_auth") do |str|
|
127
|
+
assert_equal('digest_auth OK', str)
|
128
|
+
called = true
|
129
|
+
end
|
130
|
+
assert(called)
|
131
|
+
#
|
132
|
+
called = false
|
133
|
+
c.get("http://localhost:#{Port}/digest_auth") do |str|
|
134
|
+
assert_equal('digest_auth OK', str)
|
135
|
+
called = true
|
136
|
+
end
|
137
|
+
assert(called)
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_digest_auth_with_post_io
|
141
|
+
c = HTTPClient.new
|
142
|
+
c.set_auth("http://localhost:#{Port}/", 'admin', 'admin')
|
143
|
+
post_body = StringIO.new("1234567890")
|
144
|
+
assert_equal('1234567890', c.post("http://localhost:#{Port}/digest_auth", post_body).header['x-query'][0])
|
145
|
+
#
|
146
|
+
post_body = StringIO.new("1234567890")
|
147
|
+
post_body.read(5)
|
148
|
+
assert_equal('67890', c.post("http://localhost:#{Port}/digest_auth", post_body).header['x-query'][0])
|
149
|
+
end
|
150
|
+
|
151
|
+
def test_proxy_auth
|
152
|
+
c = HTTPClient.new
|
153
|
+
c.set_proxy_auth('admin', 'admin')
|
154
|
+
c.test_loopback_http_response << "HTTP/1.0 407 Unauthorized\nProxy-Authenticate: Basic realm=\"foo\"\nContent-Length: 2\n\nNG"
|
155
|
+
c.test_loopback_http_response << "HTTP/1.0 200 OK\nContent-Length: 2\n\nOK"
|
156
|
+
c.debug_dev = str = ''
|
157
|
+
c.get_content('http://example.com/')
|
158
|
+
assert_match(/Proxy-Authorization: Basic YWRtaW46YWRtaW4=/, str)
|
159
|
+
end
|
160
|
+
end
|