webrick 1.3.1 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of webrick might be problematic. Click here for more details.

Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +63 -0
  5. data/Rakefile +10 -0
  6. data/bin/console +14 -0
  7. data/bin/setup +8 -0
  8. data/lib/webrick/accesslog.rb +9 -1
  9. data/lib/webrick/cgi.rb +58 -5
  10. data/lib/webrick/compat.rb +2 -1
  11. data/lib/webrick/config.rb +47 -10
  12. data/lib/webrick/cookie.rb +69 -7
  13. data/lib/webrick/htmlutils.rb +4 -2
  14. data/lib/webrick/httpauth/authenticator.rb +13 -8
  15. data/lib/webrick/httpauth/basicauth.rb +16 -8
  16. data/lib/webrick/httpauth/digestauth.rb +35 -32
  17. data/lib/webrick/httpauth/htdigest.rb +12 -8
  18. data/lib/webrick/httpauth/htgroup.rb +10 -6
  19. data/lib/webrick/httpauth/htpasswd.rb +46 -9
  20. data/lib/webrick/httpauth/userdb.rb +1 -0
  21. data/lib/webrick/httpauth.rb +6 -5
  22. data/lib/webrick/httpproxy.rb +93 -48
  23. data/lib/webrick/httprequest.rb +192 -27
  24. data/lib/webrick/httpresponse.rb +221 -70
  25. data/lib/webrick/https.rb +90 -2
  26. data/lib/webrick/httpserver.rb +45 -15
  27. data/lib/webrick/httpservlet/abstract.rb +5 -6
  28. data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
  29. data/lib/webrick/httpservlet/cgihandler.rb +22 -10
  30. data/lib/webrick/httpservlet/erbhandler.rb +4 -3
  31. data/lib/webrick/httpservlet/filehandler.rb +136 -65
  32. data/lib/webrick/httpservlet/prochandler.rb +15 -1
  33. data/lib/webrick/httpservlet.rb +6 -5
  34. data/lib/webrick/httpstatus.rb +24 -14
  35. data/lib/webrick/httputils.rb +133 -13
  36. data/lib/webrick/httpversion.rb +28 -1
  37. data/lib/webrick/log.rb +25 -5
  38. data/lib/webrick/server.rb +234 -74
  39. data/lib/webrick/ssl.rb +100 -12
  40. data/lib/webrick/utils.rb +98 -69
  41. data/lib/webrick/version.rb +6 -1
  42. data/lib/webrick.rb +7 -7
  43. data/webrick.gemspec +76 -0
  44. metadata +70 -69
  45. data/README.txt +0 -21
  46. data/sample/webrick/demo-app.rb +0 -66
  47. data/sample/webrick/demo-multipart.cgi +0 -12
  48. data/sample/webrick/demo-servlet.rb +0 -6
  49. data/sample/webrick/demo-urlencoded.cgi +0 -12
  50. data/sample/webrick/hello.cgi +0 -11
  51. data/sample/webrick/hello.rb +0 -8
  52. data/sample/webrick/httpd.rb +0 -23
  53. data/sample/webrick/httpproxy.rb +0 -25
  54. data/sample/webrick/httpsd.rb +0 -33
  55. data/test/openssl/utils.rb +0 -313
  56. data/test/ruby/envutil.rb +0 -208
  57. data/test/webrick/test_cgi.rb +0 -134
  58. data/test/webrick/test_cookie.rb +0 -131
  59. data/test/webrick/test_filehandler.rb +0 -285
  60. data/test/webrick/test_httpauth.rb +0 -167
  61. data/test/webrick/test_httpproxy.rb +0 -282
  62. data/test/webrick/test_httprequest.rb +0 -411
  63. data/test/webrick/test_httpresponse.rb +0 -49
  64. data/test/webrick/test_httpserver.rb +0 -305
  65. data/test/webrick/test_httputils.rb +0 -96
  66. data/test/webrick/test_httpversion.rb +0 -40
  67. data/test/webrick/test_server.rb +0 -67
  68. data/test/webrick/test_utils.rb +0 -64
  69. data/test/webrick/utils.rb +0 -58
  70. data/test/webrick/webrick.cgi +0 -36
  71. data/test/webrick/webrick_long_filename.cgi +0 -36
@@ -1,167 +0,0 @@
1
- require "test/unit"
2
- require "net/http"
3
- require "tempfile"
4
- require "webrick"
5
- require "webrick/httpauth/basicauth"
6
- require_relative "utils"
7
-
8
- class TestWEBrickHTTPAuth < Test::Unit::TestCase
9
- def test_basic_auth
10
- TestWEBrick.start_httpserver{|server, addr, port, log|
11
- realm = "WEBrick's realm"
12
- path = "/basic_auth"
13
-
14
- server.mount_proc(path){|req, res|
15
- WEBrick::HTTPAuth.basic_auth(req, res, realm){|user, pass|
16
- user == "webrick" && pass == "supersecretpassword"
17
- }
18
- res.body = "hoge"
19
- }
20
- http = Net::HTTP.new(addr, port)
21
- g = Net::HTTP::Get.new(path)
22
- g.basic_auth("webrick", "supersecretpassword")
23
- http.request(g){|res| assert_equal("hoge", res.body, log.call)}
24
- g.basic_auth("webrick", "not super")
25
- http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
26
- }
27
- end
28
-
29
- def test_basic_auth2
30
- TestWEBrick.start_httpserver{|server, addr, port, log|
31
- realm = "WEBrick's realm"
32
- path = "/basic_auth2"
33
-
34
- tmpfile = Tempfile.new("test_webrick_auth")
35
- tmpfile.close
36
- tmp_pass = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
37
- tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
38
- tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
39
- tmp_pass.flush
40
-
41
- htpasswd = WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
42
- users = []
43
- htpasswd.each{|user, pass| users << user }
44
- assert_equal(2, users.size, log.call)
45
- assert(users.member?("webrick"), log.call)
46
- assert(users.member?("foo"), log.call)
47
-
48
- server.mount_proc(path){|req, res|
49
- auth = WEBrick::HTTPAuth::BasicAuth.new(
50
- :Realm => realm, :UserDB => htpasswd,
51
- :Logger => server.logger
52
- )
53
- auth.authenticate(req, res)
54
- res.body = "hoge"
55
- }
56
- http = Net::HTTP.new(addr, port)
57
- g = Net::HTTP::Get.new(path)
58
- g.basic_auth("webrick", "supersecretpassword")
59
- http.request(g){|res| assert_equal("hoge", res.body, log.call)}
60
- g.basic_auth("webrick", "not super")
61
- http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
62
- }
63
- end
64
-
65
- def test_basic_auth3
66
- tmpfile = Tempfile.new("test_webrick_auth")
67
- tmpfile.puts("webrick:{SHA}GJYFRpBbdchp595jlh3Bhfmgp8k=")
68
- tmpfile.flush
69
- assert_raise(NotImplementedError){
70
- WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
71
- }
72
- tmpfile.close(true)
73
-
74
- tmpfile = Tempfile.new("test_webrick_auth")
75
- tmpfile.puts("webrick:$apr1$IOVMD/..$rmnOSPXr0.wwrLPZHBQZy0")
76
- tmpfile.flush
77
- assert_raise(NotImplementedError){
78
- WEBrick::HTTPAuth::Htpasswd.new(tmpfile.path)
79
- }
80
- tmpfile.close(true)
81
- end
82
-
83
- DIGESTRES_ = /
84
- ([a-zA-z\-]+)
85
- [\s\t]*(?:\r\n[\s\t]*)*
86
- =
87
- [\s\t]*(?:\r\n[\s\t]*)*
88
- (?:
89
- "((?:[^"]+|\\[\x00-\x7F])*)" |
90
- ([!\#$%&'*+\-.0-9A-Z^_`a-z|~]+)
91
- )/x
92
-
93
- def test_digest_auth
94
- TestWEBrick.start_httpserver{|server, addr, port, log|
95
- realm = "WEBrick's realm"
96
- path = "/digest_auth"
97
-
98
- tmpfile = Tempfile.new("test_webrick_auth")
99
- tmpfile.close
100
- tmp_pass = WEBrick::HTTPAuth::Htdigest.new(tmpfile.path)
101
- tmp_pass.set_passwd(realm, "webrick", "supersecretpassword")
102
- tmp_pass.set_passwd(realm, "foo", "supersecretpassword")
103
- tmp_pass.flush
104
-
105
- htdigest = WEBrick::HTTPAuth::Htdigest.new(tmpfile.path)
106
- users = []
107
- htdigest.each{|user, pass| users << user }
108
- assert_equal(2, users.size, log.call)
109
- assert(users.member?("webrick"), log.call)
110
- assert(users.member?("foo"), log.call)
111
-
112
- auth = WEBrick::HTTPAuth::DigestAuth.new(
113
- :Realm => realm, :UserDB => htdigest,
114
- :Algorithm => 'MD5',
115
- :Logger => server.logger
116
- )
117
- server.mount_proc(path){|req, res|
118
- auth.authenticate(req, res)
119
- res.body = "hoge"
120
- }
121
-
122
- Net::HTTP.start(addr, port) do |http|
123
- g = Net::HTTP::Get.new(path)
124
- params = {}
125
- http.request(g) do |res|
126
- assert_equal('401', res.code, log.call)
127
- res["www-authenticate"].scan(DIGESTRES_) do |key, quoted, token|
128
- params[key.downcase] = token || quoted.delete('\\')
129
- end
130
- params['uri'] = "http://#{addr}:#{port}#{path}"
131
- end
132
-
133
- g['Authorization'] = credentials_for_request('webrick', "supersecretpassword", params)
134
- http.request(g){|res| assert_equal("hoge", res.body, log.call)}
135
-
136
- params['algorithm'].downcase! #4936
137
- g['Authorization'] = credentials_for_request('webrick', "supersecretpassword", params)
138
- http.request(g){|res| assert_equal("hoge", res.body, log.call)}
139
-
140
- g['Authorization'] = credentials_for_request('webrick', "not super", params)
141
- http.request(g){|res| assert_not_equal("hoge", res.body, log.call)}
142
- end
143
- }
144
- end
145
-
146
- private
147
- def credentials_for_request(user, password, params)
148
- cnonce = "hoge"
149
- nonce_count = 1
150
- ha1 = "#{user}:#{params['realm']}:#{password}"
151
- ha2 = "GET:#{params['uri']}"
152
- request_digest =
153
- "#{Digest::MD5.hexdigest(ha1)}:" \
154
- "#{params['nonce']}:#{'%08x' % nonce_count}:#{cnonce}:#{params['qop']}:" \
155
- "#{Digest::MD5.hexdigest(ha2)}"
156
- "Digest username=\"#{user}\"" \
157
- ", realm=\"#{params['realm']}\"" \
158
- ", nonce=\"#{params['nonce']}\"" \
159
- ", uri=\"#{params['uri']}\"" \
160
- ", qop=#{params['qop']}" \
161
- ", nc=#{'%08x' % nonce_count}" \
162
- ", cnonce=\"#{cnonce}\"" \
163
- ", response=\"#{Digest::MD5.hexdigest(request_digest)}\"" \
164
- ", opaque=\"#{params['opaque']}\"" \
165
- ", algorithm=#{params['algorithm']}"
166
- end
167
- end
@@ -1,282 +0,0 @@
1
- require "test/unit"
2
- require "net/http"
3
- require "webrick"
4
- require "webrick/httpproxy"
5
- begin
6
- require "webrick/ssl"
7
- require "net/https"
8
- require File.expand_path("../openssl/utils.rb", File.dirname(__FILE__))
9
- rescue LoadError
10
- # test_connect will be skipped
11
- end
12
- require File.expand_path("utils.rb", File.dirname(__FILE__))
13
-
14
- class TestWEBrickHTTPProxy < Test::Unit::TestCase
15
- def test_fake_proxy
16
- assert_nil(WEBrick::FakeProxyURI.scheme)
17
- assert_nil(WEBrick::FakeProxyURI.host)
18
- assert_nil(WEBrick::FakeProxyURI.port)
19
- assert_nil(WEBrick::FakeProxyURI.path)
20
- assert_nil(WEBrick::FakeProxyURI.userinfo)
21
- assert_raise(NoMethodError){ WEBrick::FakeProxyURI.foo }
22
- end
23
-
24
- def test_proxy
25
- # Testing GET or POST to the proxy server
26
- # Note that the proxy server works as the origin server.
27
- # +------+
28
- # V |
29
- # client -------> proxy ---+
30
- # GET / POST GET / POST
31
- #
32
- proxy_handler_called = request_handler_called = 0
33
- config = {
34
- :ServerName => "localhost.localdomain",
35
- :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1 },
36
- :RequestCallback => Proc.new{|req, res| request_handler_called += 1 }
37
- }
38
- TestWEBrick.start_httpproxy(config){|server, addr, port, log|
39
- server.mount_proc("/"){|req, res|
40
- res.body = "#{req.request_method} #{req.path} #{req.body}"
41
- }
42
- http = Net::HTTP.new(addr, port, addr, port)
43
-
44
- req = Net::HTTP::Get.new("/")
45
- http.request(req){|res|
46
- assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
47
- assert_equal("GET / ", res.body, log.call)
48
- }
49
- assert_equal(1, proxy_handler_called, log.call)
50
- assert_equal(2, request_handler_called, log.call)
51
-
52
- req = Net::HTTP::Head.new("/")
53
- http.request(req){|res|
54
- assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
55
- assert_nil(res.body, log.call)
56
- }
57
- assert_equal(2, proxy_handler_called, log.call)
58
- assert_equal(4, request_handler_called, log.call)
59
-
60
- req = Net::HTTP::Post.new("/")
61
- req.body = "post-data"
62
- http.request(req){|res|
63
- assert_equal("1.1 localhost.localdomain:#{port}", res["via"], log.call)
64
- assert_equal("POST / post-data", res.body, log.call)
65
- }
66
- assert_equal(3, proxy_handler_called, log.call)
67
- assert_equal(6, request_handler_called, log.call)
68
- }
69
- end
70
-
71
- def test_no_proxy
72
- # Testing GET or POST to the proxy server without proxy request.
73
- #
74
- # client -------> proxy
75
- # GET / POST
76
- #
77
- proxy_handler_called = request_handler_called = 0
78
- config = {
79
- :ServerName => "localhost.localdomain",
80
- :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1 },
81
- :RequestCallback => Proc.new{|req, res| request_handler_called += 1 }
82
- }
83
- TestWEBrick.start_httpproxy(config){|server, addr, port, log|
84
- server.mount_proc("/"){|req, res|
85
- res.body = "#{req.request_method} #{req.path} #{req.body}"
86
- }
87
- http = Net::HTTP.new(addr, port)
88
-
89
- req = Net::HTTP::Get.new("/")
90
- http.request(req){|res|
91
- assert_nil(res["via"], log.call)
92
- assert_equal("GET / ", res.body, log.call)
93
- }
94
- assert_equal(0, proxy_handler_called, log.call)
95
- assert_equal(1, request_handler_called, log.call)
96
-
97
- req = Net::HTTP::Head.new("/")
98
- http.request(req){|res|
99
- assert_nil(res["via"], log.call)
100
- assert_nil(res.body, log.call)
101
- }
102
- assert_equal(0, proxy_handler_called, log.call)
103
- assert_equal(2, request_handler_called, log.call)
104
-
105
- req = Net::HTTP::Post.new("/")
106
- req.body = "post-data"
107
- http.request(req){|res|
108
- assert_nil(res["via"], log.call)
109
- assert_equal("POST / post-data", res.body, log.call)
110
- }
111
- assert_equal(0, proxy_handler_called, log.call)
112
- assert_equal(3, request_handler_called, log.call)
113
- }
114
- end
115
-
116
- def make_certificate(key, cn)
117
- subject = OpenSSL::X509::Name.parse("/DC=org/DC=ruby-lang/CN=#{cn}")
118
- exts = [
119
- ["keyUsage", "keyEncipherment,digitalSignature", true],
120
- ]
121
- cert = OpenSSL::TestUtils.issue_cert(
122
- subject, key, 1, Time.now, Time.now + 3600, exts,
123
- nil, nil, OpenSSL::Digest::SHA1.new
124
- )
125
- return cert
126
- end
127
-
128
- def test_connect
129
- # Testing CONNECT to proxy server
130
- #
131
- # client -----------> proxy -----------> https
132
- # 1. CONNECT establish TCP
133
- # 2. ---- establish SSL session --->
134
- # 3. ------- GET or POST ---------->
135
- #
136
- key = OpenSSL::TestUtils::TEST_KEY_RSA1024
137
- cert = make_certificate(key, "127.0.0.1")
138
- s_config = {
139
- :SSLEnable =>true,
140
- :ServerName => "localhost",
141
- :SSLCertificate => cert,
142
- :SSLPrivateKey => key,
143
- }
144
- config = {
145
- :ServerName => "localhost.localdomain",
146
- :RequestCallback => Proc.new{|req, res|
147
- assert_equal("CONNECT", req.request_method)
148
- },
149
- }
150
- TestWEBrick.start_httpserver(s_config){|s_server, s_addr, s_port, s_log|
151
- s_server.mount_proc("/"){|req, res|
152
- res.body = "SSL #{req.request_method} #{req.path} #{req.body}"
153
- }
154
- TestWEBrick.start_httpproxy(config){|server, addr, port, log|
155
- http = Net::HTTP.new("127.0.0.1", s_port, addr, port)
156
- http.use_ssl = true
157
- http.verify_callback = Proc.new do |preverify_ok, store_ctx|
158
- store_ctx.current_cert.to_der == cert.to_der
159
- end
160
-
161
- req = Net::HTTP::Get.new("/")
162
- http.request(req){|res|
163
- assert_equal("SSL GET / ", res.body, s_log.call + log.call)
164
- }
165
-
166
- req = Net::HTTP::Post.new("/")
167
- req.body = "post-data"
168
- http.request(req){|res|
169
- assert_equal("SSL POST / post-data", res.body, s_log.call + log.call)
170
- }
171
- }
172
- }
173
- end if defined?(OpenSSL)
174
-
175
- def test_upstream_proxy
176
- # Testing GET or POST through the upstream proxy server
177
- # Note that the upstream proxy server works as the origin server.
178
- # +------+
179
- # V |
180
- # client -------> proxy -------> proxy ---+
181
- # GET / POST GET / POST GET / POST
182
- #
183
- up_proxy_handler_called = up_request_handler_called = 0
184
- proxy_handler_called = request_handler_called = 0
185
- up_config = {
186
- :ServerName => "localhost.localdomain",
187
- :ProxyContentHandler => Proc.new{|req, res| up_proxy_handler_called += 1},
188
- :RequestCallback => Proc.new{|req, res| up_request_handler_called += 1}
189
- }
190
- TestWEBrick.start_httpproxy(up_config){|up_server, up_addr, up_port, up_log|
191
- up_server.mount_proc("/"){|req, res|
192
- res.body = "#{req.request_method} #{req.path} #{req.body}"
193
- }
194
- config = {
195
- :ServerName => "localhost.localdomain",
196
- :ProxyURI => URI.parse("http://localhost:#{up_port}"),
197
- :ProxyContentHandler => Proc.new{|req, res| proxy_handler_called += 1},
198
- :RequestCallback => Proc.new{|req, res| request_handler_called += 1},
199
- }
200
- TestWEBrick.start_httpproxy(config){|server, addr, port, log|
201
- http = Net::HTTP.new(up_addr, up_port, addr, port)
202
-
203
- req = Net::HTTP::Get.new("/")
204
- http.request(req){|res|
205
- skip res.message unless res.code == '200'
206
- via = res["via"].split(/,\s+/)
207
- assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
208
- assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
209
- assert_equal("GET / ", res.body)
210
- }
211
- assert_equal(1, up_proxy_handler_called, up_log.call + log.call)
212
- assert_equal(2, up_request_handler_called, up_log.call + log.call)
213
- assert_equal(1, proxy_handler_called, up_log.call + log.call)
214
- assert_equal(1, request_handler_called, up_log.call + log.call)
215
-
216
- req = Net::HTTP::Head.new("/")
217
- http.request(req){|res|
218
- via = res["via"].split(/,\s+/)
219
- assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
220
- assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
221
- assert_nil(res.body, up_log.call + log.call)
222
- }
223
- assert_equal(2, up_proxy_handler_called, up_log.call + log.call)
224
- assert_equal(4, up_request_handler_called, up_log.call + log.call)
225
- assert_equal(2, proxy_handler_called, up_log.call + log.call)
226
- assert_equal(2, request_handler_called, up_log.call + log.call)
227
-
228
- req = Net::HTTP::Post.new("/")
229
- req.body = "post-data"
230
- http.request(req){|res|
231
- via = res["via"].split(/,\s+/)
232
- assert(via.include?("1.1 localhost.localdomain:#{up_port}"), up_log.call + log.call)
233
- assert(via.include?("1.1 localhost.localdomain:#{port}"), up_log.call + log.call)
234
- assert_equal("POST / post-data", res.body, up_log.call + log.call)
235
- }
236
- assert_equal(3, up_proxy_handler_called, up_log.call + log.call)
237
- assert_equal(6, up_request_handler_called, up_log.call + log.call)
238
- assert_equal(3, proxy_handler_called, up_log.call + log.call)
239
- assert_equal(3, request_handler_called, up_log.call + log.call)
240
-
241
- if defined?(OpenSSL)
242
- # Testing CONNECT to the upstream proxy server
243
- #
244
- # client -------> proxy -------> proxy -------> https
245
- # 1. CONNECT CONNECT establish TCP
246
- # 2. -------- establish SSL session ------>
247
- # 3. ---------- GET or POST -------------->
248
- #
249
- key = OpenSSL::TestUtils::TEST_KEY_RSA1024
250
- cert = make_certificate(key, "127.0.0.1")
251
- s_config = {
252
- :SSLEnable =>true,
253
- :ServerName => "localhost",
254
- :SSLCertificate => cert,
255
- :SSLPrivateKey => key,
256
- }
257
- TestWEBrick.start_httpserver(s_config){|s_server, s_addr, s_port, s_log|
258
- s_server.mount_proc("/"){|req2, res|
259
- res.body = "SSL #{req2.request_method} #{req2.path} #{req2.body}"
260
- }
261
- http = Net::HTTP.new("127.0.0.1", s_port, addr, port, up_log.call + log.call + s_log.call)
262
- http.use_ssl = true
263
- http.verify_callback = Proc.new do |preverify_ok, store_ctx|
264
- store_ctx.current_cert.to_der == cert.to_der
265
- end
266
-
267
- req2 = Net::HTTP::Get.new("/")
268
- http.request(req2){|res|
269
- assert_equal("SSL GET / ", res.body, up_log.call + log.call + s_log.call)
270
- }
271
-
272
- req2 = Net::HTTP::Post.new("/")
273
- req2.body = "post-data"
274
- http.request(req2){|res|
275
- assert_equal("SSL POST / post-data", res.body, up_log.call + log.call + s_log.call)
276
- }
277
- }
278
- end
279
- }
280
- }
281
- end
282
- end