thehack-atom-tools 2.0.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.
- data/COPYING +18 -0
- data/README +65 -0
- data/Rakefile +87 -0
- data/bin/atom-cp +159 -0
- data/bin/atom-grep +78 -0
- data/bin/atom-post +72 -0
- data/bin/atom-purge +82 -0
- data/lib/atom/cache.rb +178 -0
- data/lib/atom/collection.rb +125 -0
- data/lib/atom/element.rb +640 -0
- data/lib/atom/entry.rb +134 -0
- data/lib/atom/feed.rb +223 -0
- data/lib/atom/http.rb +417 -0
- data/lib/atom/service.rb +106 -0
- data/lib/atom/text.rb +231 -0
- data/lib/atom/tools.rb +163 -0
- data/setup.rb +1585 -0
- data/test/conformance/order.rb +118 -0
- data/test/conformance/title.rb +108 -0
- data/test/conformance/updated.rb +34 -0
- data/test/conformance/xhtmlcontentdiv.rb +18 -0
- data/test/conformance/xmlnamespace.rb +54 -0
- data/test/runtests.rb +14 -0
- data/test/test_constructs.rb +161 -0
- data/test/test_feed.rb +134 -0
- data/test/test_general.rb +72 -0
- data/test/test_http.rb +323 -0
- data/test/test_protocol.rb +168 -0
- data/test/test_xml.rb +445 -0
- metadata +83 -0
data/test/test_feed.rb
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
require "test/unit"
|
|
2
|
+
|
|
3
|
+
require "atom/feed"
|
|
4
|
+
require "webrick"
|
|
5
|
+
|
|
6
|
+
class AtomFeedTest < Test::Unit::TestCase
|
|
7
|
+
def setup
|
|
8
|
+
@http = Atom::HTTP.new
|
|
9
|
+
@port = rand(1024) + 1024
|
|
10
|
+
@s = WEBrick::HTTPServer.new :Port => @port,
|
|
11
|
+
:Logger => WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
|
|
12
|
+
:AccessLog => []
|
|
13
|
+
|
|
14
|
+
@test_feed =<<END
|
|
15
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
16
|
+
<feed xmlns="http://www.w3.org/2005/Atom">
|
|
17
|
+
<title>Example Feed</title>
|
|
18
|
+
<link href="http://example.org/"/>
|
|
19
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
|
20
|
+
<author>
|
|
21
|
+
<name>John Doe</name>
|
|
22
|
+
</author>
|
|
23
|
+
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
|
|
24
|
+
|
|
25
|
+
<entry>
|
|
26
|
+
<title>Atom-Powered Robots Run Amok</title>
|
|
27
|
+
<link href="http://example.org/2003/12/13/atom03"/>
|
|
28
|
+
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
|
|
29
|
+
<updated>2003-12-13T18:30:02Z</updated>
|
|
30
|
+
<summary>Some text.</summary>
|
|
31
|
+
</entry>
|
|
32
|
+
</feed>
|
|
33
|
+
END
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_merge
|
|
37
|
+
feed1 = Atom::Feed.new
|
|
38
|
+
|
|
39
|
+
feed1.title = "title"
|
|
40
|
+
|
|
41
|
+
feed1.subtitle = "<br>"
|
|
42
|
+
feed1.subtitle["type"] = "html"
|
|
43
|
+
|
|
44
|
+
a = feed1.authors.new
|
|
45
|
+
a.name = "test"
|
|
46
|
+
|
|
47
|
+
feed2 = Atom::Feed.new
|
|
48
|
+
|
|
49
|
+
feed = feed1.merge(feed2)
|
|
50
|
+
|
|
51
|
+
assert_equal "text", feed.title["type"]
|
|
52
|
+
assert_equal "title", feed.title.to_s
|
|
53
|
+
|
|
54
|
+
assert_equal "html", feed.subtitle["type"]
|
|
55
|
+
assert_equal "<br>", feed.subtitle.to_s
|
|
56
|
+
|
|
57
|
+
assert_equal 1, feed.authors.length
|
|
58
|
+
assert_equal "test", feed.authors.first.name
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def test_update
|
|
62
|
+
@s.mount_proc("/") do |req,res|
|
|
63
|
+
assert_equal "application/atom+xml", req["Accept"]
|
|
64
|
+
|
|
65
|
+
res.content_type = "application/atom+xml"
|
|
66
|
+
res.body = @test_feed
|
|
67
|
+
|
|
68
|
+
@s.stop
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
feed = Atom::Feed.new "http://localhost:#{@port}/"
|
|
72
|
+
|
|
73
|
+
assert_equal nil, feed.title
|
|
74
|
+
assert_equal nil, feed.id
|
|
75
|
+
assert_equal [], feed.entries
|
|
76
|
+
|
|
77
|
+
one_shot
|
|
78
|
+
|
|
79
|
+
feed.update!
|
|
80
|
+
|
|
81
|
+
assert_equal "Example Feed", feed.title.to_s
|
|
82
|
+
assert_equal "urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6", feed.id
|
|
83
|
+
assert_equal 1, feed.entries.length
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_media_types
|
|
87
|
+
c = proc do |c_t|
|
|
88
|
+
@s.mount_proc("/") do |req,res|
|
|
89
|
+
res.content_type = c_t
|
|
90
|
+
res.body = @test_feed
|
|
91
|
+
|
|
92
|
+
@s.stop
|
|
93
|
+
end
|
|
94
|
+
# there's some kind of race condition here that will result in a
|
|
95
|
+
# timeout sometimes. this is a dirty fix.
|
|
96
|
+
sleep 0.5
|
|
97
|
+
one_shot
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
feed = Atom::Feed.new "http://localhost:#{@port}/"
|
|
101
|
+
|
|
102
|
+
# even if it looks like a feed, the server's word is law
|
|
103
|
+
c.call("text/plain")
|
|
104
|
+
assert_raise(Atom::WrongMimetype) { feed.update! }
|
|
105
|
+
|
|
106
|
+
# a parameter shouldn't change the type
|
|
107
|
+
c.call("application/atom+xml;type=feed")
|
|
108
|
+
assert_nothing_raised { feed.update! }
|
|
109
|
+
|
|
110
|
+
# type and subtype are case insensitive (param. attribute names too)
|
|
111
|
+
c.call("ApPliCatIon/ATOM+XML")
|
|
112
|
+
assert_nothing_raised { feed.update! }
|
|
113
|
+
|
|
114
|
+
# text/xml isn't the preferred mimetype, but we'll accept it
|
|
115
|
+
c.call("text/xml")
|
|
116
|
+
assert_nothing_raised { feed.update! }
|
|
117
|
+
|
|
118
|
+
# same goes for application/xml
|
|
119
|
+
c.call("application/xml")
|
|
120
|
+
assert_nothing_raised { feed.update! }
|
|
121
|
+
|
|
122
|
+
# nil content type
|
|
123
|
+
@s.mount_proc("/") do |req,res|
|
|
124
|
+
res.body = @test_feed
|
|
125
|
+
|
|
126
|
+
@s.stop
|
|
127
|
+
end
|
|
128
|
+
one_shot
|
|
129
|
+
assert_raises(Atom::HTTPException) { feed.update! }
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# prepares the server for a single request
|
|
133
|
+
def one_shot; Thread.new { @s.start }; end
|
|
134
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
|
|
3
|
+
require "test/unit"
|
|
4
|
+
|
|
5
|
+
require "atom/feed"
|
|
6
|
+
|
|
7
|
+
class AtomTest < Test::Unit::TestCase
|
|
8
|
+
def test_feed_duplicate_id
|
|
9
|
+
feed = Atom::Feed.new
|
|
10
|
+
|
|
11
|
+
entry1 = get_entry
|
|
12
|
+
entry1.id = "http://example.org/test"
|
|
13
|
+
entry1.content = "an original entry"
|
|
14
|
+
entry1.updated!
|
|
15
|
+
|
|
16
|
+
feed << entry1
|
|
17
|
+
|
|
18
|
+
assert_equal(1, feed.entries.length)
|
|
19
|
+
assert_equal("an original entry", feed.entries.first.content.to_s)
|
|
20
|
+
|
|
21
|
+
feed << entry1.dup
|
|
22
|
+
|
|
23
|
+
assert_equal(1, feed.entries.length)
|
|
24
|
+
assert_equal("an original entry", feed.entries.first.content.to_s)
|
|
25
|
+
|
|
26
|
+
entry2 = entry1.dup
|
|
27
|
+
entry2.content = "a changed entry"
|
|
28
|
+
entry2.updated!
|
|
29
|
+
|
|
30
|
+
feed << entry2
|
|
31
|
+
|
|
32
|
+
assert_equal(1, feed.entries.length)
|
|
33
|
+
assert_equal("a changed entry", feed.entries.last.content.to_s)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_tags
|
|
37
|
+
entry = get_entry
|
|
38
|
+
entry.tag_with "test tags"
|
|
39
|
+
|
|
40
|
+
xml = get_elements entry
|
|
41
|
+
|
|
42
|
+
assert_has_category(xml, "test")
|
|
43
|
+
assert_has_category(xml, "tags")
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def assert_has_category xml, term
|
|
47
|
+
assert_not_nil(REXML::XPath.match(xml, "/entry/category[@term = #{term}]"))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def assert_has_content_type xml, type
|
|
51
|
+
assert_equal(type, xml.elements["/entry/content"].attributes["type"])
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def get_entry
|
|
55
|
+
Atom::Entry.new
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def get_elements entry
|
|
59
|
+
xml = entry.to_xml
|
|
60
|
+
|
|
61
|
+
assert_equal(entry.to_s, Atom::Entry.parse(xml).to_s)
|
|
62
|
+
|
|
63
|
+
base_check xml
|
|
64
|
+
|
|
65
|
+
xml
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def base_check xml
|
|
69
|
+
assert_equal("entry", xml.root.name)
|
|
70
|
+
assert_equal("http://www.w3.org/2005/Atom", xml.root.namespace)
|
|
71
|
+
end
|
|
72
|
+
end
|
data/test/test_http.rb
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
require "test/unit"
|
|
2
|
+
|
|
3
|
+
require "atom/http"
|
|
4
|
+
require "webrick"
|
|
5
|
+
|
|
6
|
+
class AtomHTTPTest < Test::Unit::TestCase
|
|
7
|
+
REALM = "test authentication"
|
|
8
|
+
USER = "test_user"
|
|
9
|
+
PASS = "aoeuaoeu"
|
|
10
|
+
|
|
11
|
+
# for Google AuthSub authentication
|
|
12
|
+
TOKEN = "pq7266382__838"
|
|
13
|
+
|
|
14
|
+
SECRET_DATA = "I kissed a boy once"
|
|
15
|
+
|
|
16
|
+
def setup
|
|
17
|
+
@http = Atom::HTTP.new
|
|
18
|
+
@port = rand(1024) + 1024
|
|
19
|
+
@s = WEBrick::HTTPServer.new :Port => @port,
|
|
20
|
+
:Logger => WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
|
|
21
|
+
:AccessLog => []
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_parse_wwwauth
|
|
25
|
+
# a Basic WWW-Authenticate
|
|
26
|
+
header = 'realm="SokEvo"'
|
|
27
|
+
|
|
28
|
+
params = @http.send :parse_quoted_wwwauth, header
|
|
29
|
+
assert_equal "SokEvo", params[:realm]
|
|
30
|
+
|
|
31
|
+
# Digest is parsed a bit differently
|
|
32
|
+
header = 'opaque="07UrfUiCYac5BbWJ", algorithm=MD5-sess, qop="auth", stale=TRUE, nonce="MDAx0Mzk", realm="test authentication"'
|
|
33
|
+
|
|
34
|
+
params = @http.send :parse_wwwauth_digest, header
|
|
35
|
+
|
|
36
|
+
assert_equal "test authentication", params[:realm]
|
|
37
|
+
assert_equal "MDAx0Mzk", params[:nonce]
|
|
38
|
+
assert_equal true, params[:stale]
|
|
39
|
+
assert_equal "auth", params[:qop]
|
|
40
|
+
assert_equal "MD5-sess", params[:algorithm]
|
|
41
|
+
assert_equal "07UrfUiCYac5BbWJ", params[:opaque]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_GET
|
|
45
|
+
mount_one_shot do |req,res|
|
|
46
|
+
assert_equal("/", req.path)
|
|
47
|
+
|
|
48
|
+
res.content_type = "text/plain"
|
|
49
|
+
res.body = "Success!"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
get_root
|
|
53
|
+
|
|
54
|
+
assert_equal "200", @res.code
|
|
55
|
+
assert_equal "text/plain", @res.content_type
|
|
56
|
+
assert_equal "Success!", @res.body
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_GET_headers
|
|
60
|
+
mount_one_shot do |req,res|
|
|
61
|
+
assert_equal("tester agent", req["User-Agent"])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
get_root("User-Agent" => "tester agent")
|
|
65
|
+
|
|
66
|
+
assert_equal "200", @res.code
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_redirect
|
|
70
|
+
@s.mount_proc("/") do |req,res|
|
|
71
|
+
res.status = 302
|
|
72
|
+
res["Location"] = "http://localhost:#{@port}/redirected"
|
|
73
|
+
|
|
74
|
+
res.body = "ignore me."
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
@s.mount_proc("/redirected") do |req,res|
|
|
78
|
+
res.content_type = "text/plain"
|
|
79
|
+
res.body = "Success!"
|
|
80
|
+
|
|
81
|
+
@s.stop
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
one_shot; get_root
|
|
85
|
+
|
|
86
|
+
# the redirect should be transparent (to whatever extent it can be)
|
|
87
|
+
assert_equal "200", @res.code
|
|
88
|
+
assert_equal "Success!", @res.body
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def test_redirect_loop
|
|
92
|
+
@s.mount_proc("/") do |req,res|
|
|
93
|
+
res.status = 302
|
|
94
|
+
res["Location"] = "http://localhost:#{@port}/redirected"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
@s.mount_proc("/redirected") do |req,res|
|
|
98
|
+
res.status = 302
|
|
99
|
+
res["Location"] = "http://localhost:#{@port}/"
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
one_shot
|
|
103
|
+
|
|
104
|
+
assert_raises(Atom::HTTPException) { get_root }
|
|
105
|
+
|
|
106
|
+
@s.stop
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_redirect_non_GET_non_HEAD
|
|
110
|
+
@s.mount_proc("/") do |req,res|
|
|
111
|
+
assert_equal "POST", req.request_method
|
|
112
|
+
res.status = 302
|
|
113
|
+
res["Location"] = "http://localhost:#{@port}/redirected"
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
@s.mount_proc("/redirected") do |req,res|
|
|
117
|
+
assert_equal "POST", req.request_method
|
|
118
|
+
assert_equal "important message", req.body
|
|
119
|
+
res.content_type = "text/plain"
|
|
120
|
+
res.body = "Success!"
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
one_shot
|
|
124
|
+
|
|
125
|
+
@res = @http.post "http://localhost:#{@port}/", "important message"
|
|
126
|
+
|
|
127
|
+
assert_equal "302", @res.code
|
|
128
|
+
|
|
129
|
+
@http.allow_all_redirects = true
|
|
130
|
+
|
|
131
|
+
one_shot
|
|
132
|
+
|
|
133
|
+
@res = @http.post "http://localhost:#{@port}/", "important message"
|
|
134
|
+
|
|
135
|
+
assert_equal "200", @res.code
|
|
136
|
+
assert_equal "Success!", @res.body
|
|
137
|
+
|
|
138
|
+
@s.stop
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def test_basic_auth
|
|
142
|
+
mount_one_shot do |req,res|
|
|
143
|
+
WEBrick::HTTPAuth.basic_auth(req, res, REALM) do |u,p|
|
|
144
|
+
u == USER and p == PASS
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
res.body = SECRET_DATA
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# no credentials
|
|
151
|
+
assert_raises(Atom::Unauthorized) { get_root }
|
|
152
|
+
|
|
153
|
+
# incorrect credentials
|
|
154
|
+
@http.user = USER
|
|
155
|
+
@http.pass = "incorrect_password"
|
|
156
|
+
|
|
157
|
+
one_shot
|
|
158
|
+
|
|
159
|
+
assert_raises(Atom::Unauthorized) { get_root }
|
|
160
|
+
|
|
161
|
+
# no credentials, fancy block
|
|
162
|
+
@http.when_auth do nil end
|
|
163
|
+
|
|
164
|
+
one_shot
|
|
165
|
+
|
|
166
|
+
assert_raises(Atom::Unauthorized) { get_root }
|
|
167
|
+
|
|
168
|
+
# correct credentials, fancy block
|
|
169
|
+
@http.when_auth do |abs_url,realm|
|
|
170
|
+
assert_equal "http://localhost:#{@port}/", abs_url
|
|
171
|
+
assert_equal REALM, realm
|
|
172
|
+
|
|
173
|
+
[USER, PASS]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
one_shot
|
|
177
|
+
|
|
178
|
+
assert_authenticates
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_digest_auth
|
|
182
|
+
# a dummy userdb (saves me creating a file)
|
|
183
|
+
userdb = {}
|
|
184
|
+
# with a single entry
|
|
185
|
+
userdb[USER] = PASS
|
|
186
|
+
|
|
187
|
+
# HTTPAuth::DigestAuth#authenticate uses this
|
|
188
|
+
def userdb.get_passwd(realm, user, reload)
|
|
189
|
+
Digest::MD5::hexdigest([user, realm, self[user]].join(":"))
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
authenticator = WEBrick::HTTPAuth::DigestAuth.new(
|
|
193
|
+
:UserDB => userdb,
|
|
194
|
+
:Realm => REALM,
|
|
195
|
+
:Algorithm => "MD5"
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
@s.mount_proc("/") do |req,res|
|
|
199
|
+
authenticator.authenticate(req, res)
|
|
200
|
+
res.body = SECRET_DATA
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
one_shot
|
|
204
|
+
|
|
205
|
+
# no credentials
|
|
206
|
+
assert_raises(Atom::Unauthorized) { get_root }
|
|
207
|
+
|
|
208
|
+
@http.user = USER
|
|
209
|
+
@http.pass = PASS
|
|
210
|
+
|
|
211
|
+
# correct credentials
|
|
212
|
+
assert_authenticates
|
|
213
|
+
|
|
214
|
+
@s.stop
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def test_wsse_auth
|
|
218
|
+
mount_one_shot do |req,res|
|
|
219
|
+
assert_equal 'WSSE profile="UsernameToken"', req["Authorization"]
|
|
220
|
+
|
|
221
|
+
xwsse = req["X-WSSE"]
|
|
222
|
+
|
|
223
|
+
p = @http.send :parse_quoted_wwwauth, xwsse
|
|
224
|
+
|
|
225
|
+
assert_equal USER, p[:Username]
|
|
226
|
+
assert_match /^UsernameToken /, xwsse
|
|
227
|
+
|
|
228
|
+
# Base64( SHA1( Nonce + CreationTimestamp + Password ) )
|
|
229
|
+
pd_string = p[:Nonce].unpack("m").first + p[:Created] + PASS
|
|
230
|
+
password_digest = [Digest::SHA1.digest(pd_string)].pack("m").chomp
|
|
231
|
+
|
|
232
|
+
assert_equal password_digest, p[:PasswordDigest]
|
|
233
|
+
|
|
234
|
+
res.body = SECRET_DATA
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
@http.always_auth = :wsse
|
|
238
|
+
@http.user = USER
|
|
239
|
+
@http.pass = PASS
|
|
240
|
+
|
|
241
|
+
assert_authenticates
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def test_authsub_auth
|
|
245
|
+
mount_one_shot do |req,res|
|
|
246
|
+
assert_equal %{AuthSub token="#{TOKEN}"}, req["Authorization"]
|
|
247
|
+
|
|
248
|
+
res.body = SECRET_DATA
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
@http.always_auth = :authsub
|
|
252
|
+
@http.token = TOKEN
|
|
253
|
+
|
|
254
|
+
assert_authenticates
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def test_multiple_auth
|
|
258
|
+
mount_one_shot do |req,res|
|
|
259
|
+
# WEBrick doesn't seem to support sending multiple headers, so this is the best we can do
|
|
260
|
+
res["WWW-Authenticate"] = %{NonexistantAuth parameter="yes", qop="auth", Basic realm="#{REALM}", something="true"}
|
|
261
|
+
|
|
262
|
+
if req["Authorization"]
|
|
263
|
+
res.body = SECRET_DATA
|
|
264
|
+
else
|
|
265
|
+
res.status = 401
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
@http.user = USER
|
|
270
|
+
@http.pass = PASS
|
|
271
|
+
|
|
272
|
+
assert_authenticates
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
def test_https
|
|
276
|
+
require 'webrick/https'
|
|
277
|
+
|
|
278
|
+
@s = WEBrick::HTTPServer.new(
|
|
279
|
+
:Port => (@port + 1),
|
|
280
|
+
:DocumentRoot => Dir::pwd + "/htdocs",
|
|
281
|
+
:Logger => WEBrick::Log.new($stderr, WEBrick::Log::FATAL),
|
|
282
|
+
:AccessLog => [],
|
|
283
|
+
:SSLEnable => true,
|
|
284
|
+
:SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE,
|
|
285
|
+
:SSLCertName => [ ["C","CA"], ["O","localhost"], ["CN", "WWW"] ]
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
mount_one_shot do |req,res|
|
|
289
|
+
res.body = SECRET_DATA
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
res = @http.get("https://localhost:#{@port + 1}/")
|
|
293
|
+
|
|
294
|
+
assert_equal "200", res.code
|
|
295
|
+
assert_equal SECRET_DATA, res.body
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# mount a block on the test server, shutting the server down after a
|
|
299
|
+
# single request
|
|
300
|
+
def mount_one_shot &block
|
|
301
|
+
@s.mount_proc("/") do |req,res|
|
|
302
|
+
block.call req, res
|
|
303
|
+
@s.stop
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
one_shot
|
|
307
|
+
end
|
|
308
|
+
|
|
309
|
+
# test that we authenticated properly
|
|
310
|
+
def assert_authenticates
|
|
311
|
+
get_root
|
|
312
|
+
assert_equal "200", @res.code
|
|
313
|
+
assert_equal SECRET_DATA, @res.body
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
# performs a GET on the test server
|
|
317
|
+
def get_root(*args)
|
|
318
|
+
@res = @http.get("http://localhost:#{@port}/", *args)
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
# sets up the server for a single request
|
|
322
|
+
def one_shot; Thread.new { @s.start }; end
|
|
323
|
+
end
|