webrick 1.3.1 → 1.4.3
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.
- checksums.yaml +7 -0
- data/lib/webrick.rb +6 -6
- data/lib/webrick/accesslog.rb +9 -1
- data/lib/webrick/cgi.rb +58 -5
- data/lib/webrick/compat.rb +2 -1
- data/lib/webrick/config.rb +47 -10
- data/lib/webrick/cookie.rb +69 -7
- data/lib/webrick/htmlutils.rb +4 -2
- data/lib/webrick/httpauth.rb +6 -5
- data/lib/webrick/httpauth/authenticator.rb +13 -8
- data/lib/webrick/httpauth/basicauth.rb +16 -8
- data/lib/webrick/httpauth/digestauth.rb +35 -32
- data/lib/webrick/httpauth/htdigest.rb +12 -8
- data/lib/webrick/httpauth/htgroup.rb +10 -6
- data/lib/webrick/httpauth/htpasswd.rb +46 -9
- data/lib/webrick/httpauth/userdb.rb +1 -0
- data/lib/webrick/httpproxy.rb +93 -48
- data/lib/webrick/httprequest.rb +192 -27
- data/lib/webrick/httpresponse.rb +182 -62
- data/lib/webrick/https.rb +90 -2
- data/lib/webrick/httpserver.rb +45 -15
- data/lib/webrick/httpservlet.rb +6 -5
- data/lib/webrick/httpservlet/abstract.rb +5 -6
- data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
- data/lib/webrick/httpservlet/cgihandler.rb +22 -10
- data/lib/webrick/httpservlet/erbhandler.rb +4 -3
- data/lib/webrick/httpservlet/filehandler.rb +136 -65
- data/lib/webrick/httpservlet/prochandler.rb +15 -1
- data/lib/webrick/httpstatus.rb +24 -14
- data/lib/webrick/httputils.rb +132 -13
- data/lib/webrick/httpversion.rb +28 -1
- data/lib/webrick/log.rb +25 -5
- data/lib/webrick/server.rb +234 -74
- data/lib/webrick/ssl.rb +100 -12
- data/lib/webrick/utils.rb +98 -69
- data/lib/webrick/version.rb +6 -1
- metadata +66 -72
- data/README.txt +0 -21
- data/sample/webrick/demo-app.rb +0 -66
- data/sample/webrick/demo-multipart.cgi +0 -12
- data/sample/webrick/demo-servlet.rb +0 -6
- data/sample/webrick/demo-urlencoded.cgi +0 -12
- data/sample/webrick/hello.cgi +0 -11
- data/sample/webrick/hello.rb +0 -8
- data/sample/webrick/httpd.rb +0 -23
- data/sample/webrick/httpproxy.rb +0 -25
- data/sample/webrick/httpsd.rb +0 -33
- data/test/openssl/utils.rb +0 -313
- data/test/ruby/envutil.rb +0 -208
- data/test/webrick/test_cgi.rb +0 -134
- data/test/webrick/test_cookie.rb +0 -131
- data/test/webrick/test_filehandler.rb +0 -285
- data/test/webrick/test_httpauth.rb +0 -167
- data/test/webrick/test_httpproxy.rb +0 -282
- data/test/webrick/test_httprequest.rb +0 -411
- data/test/webrick/test_httpresponse.rb +0 -49
- data/test/webrick/test_httpserver.rb +0 -305
- data/test/webrick/test_httputils.rb +0 -96
- data/test/webrick/test_httpversion.rb +0 -40
- data/test/webrick/test_server.rb +0 -67
- data/test/webrick/test_utils.rb +0 -64
- data/test/webrick/utils.rb +0 -58
- data/test/webrick/webrick.cgi +0 -36
- data/test/webrick/webrick_long_filename.cgi +0 -36
data/lib/webrick/httpserver.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpserver.rb -- HTTPServer Class
|
3
4
|
#
|
@@ -8,13 +9,14 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: httpserver.rb,v 1.63 2002/10/01 17:16:32 gotoyuzo Exp $
|
10
11
|
|
11
|
-
require '
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
12
|
+
require 'io/wait'
|
13
|
+
require_relative 'server'
|
14
|
+
require_relative 'httputils'
|
15
|
+
require_relative 'httpstatus'
|
16
|
+
require_relative 'httprequest'
|
17
|
+
require_relative 'httpresponse'
|
18
|
+
require_relative 'httpservlet'
|
19
|
+
require_relative 'accesslog'
|
18
20
|
|
19
21
|
module WEBrick
|
20
22
|
class HTTPServerError < ServerError; end
|
@@ -66,17 +68,17 @@ module WEBrick
|
|
66
68
|
|
67
69
|
def run(sock)
|
68
70
|
while true
|
69
|
-
|
70
|
-
|
71
|
+
req = create_request(@config)
|
72
|
+
res = create_response(@config)
|
71
73
|
server = self
|
72
74
|
begin
|
73
75
|
timeout = @config[:RequestTimeout]
|
74
76
|
while timeout > 0
|
75
|
-
break if
|
76
|
-
|
77
|
+
break if sock.to_io.wait_readable(0.5)
|
78
|
+
break if @status != :Running
|
77
79
|
timeout -= 0.5
|
78
80
|
end
|
79
|
-
raise HTTPStatus::EOFError if timeout <= 0
|
81
|
+
raise HTTPStatus::EOFError if timeout <= 0 || @status != :Running
|
80
82
|
raise HTTPStatus::EOFError if sock.eof?
|
81
83
|
req.parse(sock)
|
82
84
|
res.request_method = req.request_method
|
@@ -138,6 +140,10 @@ module WEBrick
|
|
138
140
|
si.service(req, res)
|
139
141
|
end
|
140
142
|
|
143
|
+
##
|
144
|
+
# The default OPTIONS request handler says GET, HEAD, POST and OPTIONS
|
145
|
+
# requests are allowed.
|
146
|
+
|
141
147
|
def do_OPTIONS(req, res)
|
142
148
|
res["allow"] = "GET,HEAD,POST,OPTIONS"
|
143
149
|
end
|
@@ -207,6 +213,10 @@ module WEBrick
|
|
207
213
|
}
|
208
214
|
end
|
209
215
|
|
216
|
+
##
|
217
|
+
# Logs +req+ and +res+ in the access logs. +config+ is used for the
|
218
|
+
# server name.
|
219
|
+
|
210
220
|
def access_log(config, req, res)
|
211
221
|
param = AccessLog::setup_params(config, req, res)
|
212
222
|
@config[:AccessLog].each{|logger, fmt|
|
@@ -214,7 +224,27 @@ module WEBrick
|
|
214
224
|
}
|
215
225
|
end
|
216
226
|
|
217
|
-
|
227
|
+
##
|
228
|
+
# Creates the HTTPRequest used when handling the HTTP
|
229
|
+
# request. Can be overridden by subclasses.
|
230
|
+
def create_request(with_webrick_config)
|
231
|
+
HTTPRequest.new(with_webrick_config)
|
232
|
+
end
|
233
|
+
|
234
|
+
##
|
235
|
+
# Creates the HTTPResponse used when handling the HTTP
|
236
|
+
# request. Can be overridden by subclasses.
|
237
|
+
def create_response(with_webrick_config)
|
238
|
+
HTTPResponse.new(with_webrick_config)
|
239
|
+
end
|
240
|
+
|
241
|
+
##
|
242
|
+
# Mount table for the path a servlet is mounted on in the directory space
|
243
|
+
# of the server. Users of WEBrick can only access this indirectly via
|
244
|
+
# WEBrick::HTTPServer#mount, WEBrick::HTTPServer#unmount and
|
245
|
+
# WEBrick::HTTPServer#search_servlet
|
246
|
+
|
247
|
+
class MountTable # :nodoc:
|
218
248
|
def initialize
|
219
249
|
@tab = Hash.new
|
220
250
|
compile
|
@@ -251,12 +281,12 @@ module WEBrick
|
|
251
281
|
k.sort!
|
252
282
|
k.reverse!
|
253
283
|
k.collect!{|path| Regexp.escape(path) }
|
254
|
-
@scanner = Regexp.new("
|
284
|
+
@scanner = Regexp.new("\\A(" + k.join("|") +")(?=/|\\z)")
|
255
285
|
end
|
256
286
|
|
257
287
|
def normalize(dir)
|
258
288
|
ret = dir ? dir.dup : ""
|
259
|
-
ret.sub!(%r
|
289
|
+
ret.sub!(%r|/+\z|, "")
|
260
290
|
ret
|
261
291
|
end
|
262
292
|
end
|
data/lib/webrick/httpservlet.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpservlet.rb -- HTTPServlet Utility File
|
3
4
|
#
|
@@ -8,11 +9,11 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: httpservlet.rb,v 1.21 2003/02/23 12:24:46 gotoyuzo Exp $
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
require_relative 'httpservlet/abstract'
|
13
|
+
require_relative 'httpservlet/filehandler'
|
14
|
+
require_relative 'httpservlet/cgihandler'
|
15
|
+
require_relative 'httpservlet/erbhandler'
|
16
|
+
require_relative 'httpservlet/prochandler'
|
16
17
|
|
17
18
|
module WEBrick
|
18
19
|
module HTTPServlet
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httpservlet.rb -- HTTPServlet Module
|
3
4
|
#
|
@@ -8,11 +9,9 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: abstract.rb,v 1.24 2003/07/11 11:16:46 gotoyuzo Exp $
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
require 'webrick/httputils'
|
15
|
-
require 'webrick/httpstatus'
|
12
|
+
require_relative '../htmlutils'
|
13
|
+
require_relative '../httputils'
|
14
|
+
require_relative '../httpstatus'
|
16
15
|
|
17
16
|
module WEBrick
|
18
17
|
module HTTPServlet
|
@@ -54,7 +53,7 @@ module WEBrick
|
|
54
53
|
# Servlets can be configured via initialize. The first argument is the
|
55
54
|
# HTTP server the servlet is being initialized for.
|
56
55
|
#
|
57
|
-
# class
|
56
|
+
# class Configurable < Simple
|
58
57
|
# def initialize server, color, size
|
59
58
|
# super server
|
60
59
|
# @color = color
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# cgi_runner.rb -- CGI launcher.
|
3
4
|
#
|
@@ -22,11 +23,11 @@ STDIN.binmode
|
|
22
23
|
|
23
24
|
len = sysread(STDIN, 8).to_i
|
24
25
|
out = sysread(STDIN, len)
|
25
|
-
STDOUT.reopen(open(out, "w"))
|
26
|
+
STDOUT.reopen(File.open(out, "w"))
|
26
27
|
|
27
28
|
len = sysread(STDIN, 8).to_i
|
28
29
|
err = sysread(STDIN, len)
|
29
|
-
STDERR.reopen(open(err, "w"))
|
30
|
+
STDERR.reopen(File.open(err, "w"))
|
30
31
|
|
31
32
|
len = sysread(STDIN, 8).to_i
|
32
33
|
dump = sysread(STDIN, len)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# cgihandler.rb -- CGIHandler Class
|
3
4
|
#
|
@@ -10,15 +11,26 @@
|
|
10
11
|
|
11
12
|
require 'rbconfig'
|
12
13
|
require 'tempfile'
|
13
|
-
|
14
|
-
|
14
|
+
require_relative '../config'
|
15
|
+
require_relative 'abstract'
|
15
16
|
|
16
17
|
module WEBrick
|
17
18
|
module HTTPServlet
|
18
19
|
|
20
|
+
##
|
21
|
+
# Servlet for handling CGI scripts
|
22
|
+
#
|
23
|
+
# Example:
|
24
|
+
#
|
25
|
+
# server.mount('/cgi/my_script', WEBrick::HTTPServlet::CGIHandler,
|
26
|
+
# '/path/to/my_script')
|
27
|
+
|
19
28
|
class CGIHandler < AbstractServlet
|
20
|
-
Ruby = RbConfig.ruby
|
21
|
-
CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\""
|
29
|
+
Ruby = RbConfig.ruby # :nodoc:
|
30
|
+
CGIRunner = "\"#{Ruby}\" \"#{WEBrick::Config::LIBDIR}/httpservlet/cgi_runner.rb\"" # :nodoc:
|
31
|
+
|
32
|
+
##
|
33
|
+
# Creates a new CGI script servlet for the script at +name+
|
22
34
|
|
23
35
|
def initialize(server, name)
|
24
36
|
super(server, name)
|
@@ -27,10 +39,9 @@ module WEBrick
|
|
27
39
|
@cgicmd = "#{CGIRunner} #{server[:CGIInterpreter]}"
|
28
40
|
end
|
29
41
|
|
30
|
-
|
31
|
-
data = nil
|
32
|
-
status = -1
|
42
|
+
# :stopdoc:
|
33
43
|
|
44
|
+
def do_GET(req, res)
|
34
45
|
cgi_in = IO::popen(@cgicmd, "wb")
|
35
46
|
cgi_out = Tempfile.new("webrick.cgiout.", @tempdir, mode: IO::BINARY)
|
36
47
|
cgi_out.set_encoding("ASCII-8BIT")
|
@@ -41,6 +52,7 @@ module WEBrick
|
|
41
52
|
meta = req.meta_vars
|
42
53
|
meta["SCRIPT_FILENAME"] = @script_filename
|
43
54
|
meta["PATH"] = @config[:CGIPathEnv]
|
55
|
+
meta.delete("HTTP_PROXY")
|
44
56
|
if /mswin|bccwin|mingw/ =~ RUBY_PLATFORM
|
45
57
|
meta["SystemRoot"] = ENV["SystemRoot"]
|
46
58
|
end
|
@@ -53,9 +65,7 @@ module WEBrick
|
|
53
65
|
cgi_in.write("%8d" % dump.bytesize)
|
54
66
|
cgi_in.write(dump)
|
55
67
|
|
56
|
-
|
57
|
-
cgi_in.write(req.body)
|
58
|
-
end
|
68
|
+
req.body { |chunk| cgi_in.write(chunk) }
|
59
69
|
ensure
|
60
70
|
cgi_in.close
|
61
71
|
status = $?.exitstatus
|
@@ -102,6 +112,8 @@ module WEBrick
|
|
102
112
|
res.body = body
|
103
113
|
end
|
104
114
|
alias do_POST do_GET
|
115
|
+
|
116
|
+
# :startdoc:
|
105
117
|
end
|
106
118
|
|
107
119
|
end
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# erbhandler.rb -- ERBHandler Class
|
3
4
|
#
|
@@ -8,7 +9,7 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: erbhandler.rb,v 1.25 2003/02/24 19:25:31 gotoyuzo Exp $
|
10
11
|
|
11
|
-
|
12
|
+
require_relative 'abstract'
|
12
13
|
|
13
14
|
require 'erb'
|
14
15
|
|
@@ -52,11 +53,11 @@ module WEBrick
|
|
52
53
|
raise HTTPStatus::Forbidden, "ERBHandler cannot work."
|
53
54
|
end
|
54
55
|
begin
|
55
|
-
data = open(@script_filename
|
56
|
+
data = File.open(@script_filename, &:read)
|
56
57
|
res.body = evaluate(ERB.new(data), req, res)
|
57
58
|
res['content-type'] ||=
|
58
59
|
HTTPUtils::mime_type(@script_filename, @config[:MimeTypes])
|
59
|
-
rescue StandardError
|
60
|
+
rescue StandardError
|
60
61
|
raise
|
61
62
|
rescue Exception => ex
|
62
63
|
@logger.error(ex)
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# filehandler.rb -- FileHandler Module
|
3
4
|
#
|
@@ -8,22 +9,38 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: filehandler.rb,v 1.44 2003/06/07 01:34:51 gotoyuzo Exp $
|
10
11
|
|
11
|
-
require 'thread'
|
12
12
|
require 'time'
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
require_relative '../htmlutils'
|
15
|
+
require_relative '../httputils'
|
16
|
+
require_relative '../httpstatus'
|
17
17
|
|
18
18
|
module WEBrick
|
19
19
|
module HTTPServlet
|
20
20
|
|
21
|
+
##
|
22
|
+
# Servlet for serving a single file. You probably want to use the
|
23
|
+
# FileHandler servlet instead as it handles directories and fancy indexes.
|
24
|
+
#
|
25
|
+
# Example:
|
26
|
+
#
|
27
|
+
# server.mount('/my_page.txt', WEBrick::HTTPServlet::DefaultFileHandler,
|
28
|
+
# '/path/to/my_page.txt')
|
29
|
+
#
|
30
|
+
# This servlet handles If-Modified-Since and Range requests.
|
31
|
+
|
21
32
|
class DefaultFileHandler < AbstractServlet
|
33
|
+
|
34
|
+
##
|
35
|
+
# Creates a DefaultFileHandler instance for the file at +local_path+.
|
36
|
+
|
22
37
|
def initialize(server, local_path)
|
23
38
|
super(server, local_path)
|
24
39
|
@local_path = local_path
|
25
40
|
end
|
26
41
|
|
42
|
+
# :stopdoc:
|
43
|
+
|
27
44
|
def do_GET(req, res)
|
28
45
|
st = File::stat(@local_path)
|
29
46
|
mtime = st.mtime
|
@@ -38,9 +55,9 @@ module WEBrick
|
|
38
55
|
else
|
39
56
|
mtype = HTTPUtils::mime_type(@local_path, @config[:MimeTypes])
|
40
57
|
res['content-type'] = mtype
|
41
|
-
res['content-length'] = st.size
|
58
|
+
res['content-length'] = st.size.to_s
|
42
59
|
res['last-modified'] = mtime.httpdate
|
43
|
-
res.body = open(@local_path, "rb")
|
60
|
+
res.body = File.open(@local_path, "rb")
|
44
61
|
end
|
45
62
|
end
|
46
63
|
|
@@ -69,47 +86,66 @@ module WEBrick
|
|
69
86
|
return false
|
70
87
|
end
|
71
88
|
|
89
|
+
# returns a lambda for webrick/httpresponse.rb send_body_proc
|
90
|
+
def multipart_body(body, parts, boundary, mtype, filesize)
|
91
|
+
lambda do |socket|
|
92
|
+
begin
|
93
|
+
begin
|
94
|
+
first = parts.shift
|
95
|
+
last = parts.shift
|
96
|
+
socket.write(
|
97
|
+
"--#{boundary}#{CRLF}" \
|
98
|
+
"Content-Type: #{mtype}#{CRLF}" \
|
99
|
+
"Content-Range: bytes #{first}-#{last}/#{filesize}#{CRLF}" \
|
100
|
+
"#{CRLF}"
|
101
|
+
)
|
102
|
+
|
103
|
+
begin
|
104
|
+
IO.copy_stream(body, socket, last - first + 1, first)
|
105
|
+
rescue NotImplementedError
|
106
|
+
body.seek(first, IO::SEEK_SET)
|
107
|
+
IO.copy_stream(body, socket, last - first + 1)
|
108
|
+
end
|
109
|
+
socket.write(CRLF)
|
110
|
+
end while parts[0]
|
111
|
+
socket.write("--#{boundary}--#{CRLF}")
|
112
|
+
ensure
|
113
|
+
body.close
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
72
118
|
def make_partial_content(req, res, filename, filesize)
|
73
119
|
mtype = HTTPUtils::mime_type(filename, @config[:MimeTypes])
|
74
120
|
unless ranges = HTTPUtils::parse_range_header(req['range'])
|
75
121
|
raise HTTPStatus::BadRequest,
|
76
122
|
"Unrecognized range-spec: \"#{req['range']}\""
|
77
123
|
end
|
78
|
-
open(filename, "rb"){|io|
|
124
|
+
File.open(filename, "rb"){|io|
|
79
125
|
if ranges.size > 1
|
80
126
|
time = Time.now
|
81
127
|
boundary = "#{time.sec}_#{time.usec}_#{Process::pid}"
|
82
|
-
|
83
|
-
ranges.each{|range|
|
84
|
-
|
85
|
-
next if
|
86
|
-
|
87
|
-
content = io.read(last-first+1)
|
88
|
-
body << "--" << boundary << CRLF
|
89
|
-
body << "Content-Type: #{mtype}" << CRLF
|
90
|
-
body << "Content-Range: bytes #{first}-#{last}/#{filesize}" << CRLF
|
91
|
-
body << CRLF
|
92
|
-
body << content
|
93
|
-
body << CRLF
|
128
|
+
parts = []
|
129
|
+
ranges.each {|range|
|
130
|
+
prange = prepare_range(range, filesize)
|
131
|
+
next if prange[0] < 0
|
132
|
+
parts.concat(prange)
|
94
133
|
}
|
95
|
-
raise HTTPStatus::RequestRangeNotSatisfiable if
|
96
|
-
body << "--" << boundary << "--" << CRLF
|
134
|
+
raise HTTPStatus::RequestRangeNotSatisfiable if parts.empty?
|
97
135
|
res["content-type"] = "multipart/byteranges; boundary=#{boundary}"
|
98
|
-
|
136
|
+
if req.http_version < '1.1'
|
137
|
+
res['connection'] = 'close'
|
138
|
+
else
|
139
|
+
res.chunked = true
|
140
|
+
end
|
141
|
+
res.body = multipart_body(io.dup, parts, boundary, mtype, filesize)
|
99
142
|
elsif range = ranges[0]
|
100
143
|
first, last = prepare_range(range, filesize)
|
101
144
|
raise HTTPStatus::RequestRangeNotSatisfiable if first < 0
|
102
|
-
if last == filesize - 1
|
103
|
-
content = io.dup
|
104
|
-
content.pos = first
|
105
|
-
else
|
106
|
-
io.pos = first
|
107
|
-
content = io.read(last-first+1)
|
108
|
-
end
|
109
145
|
res['content-type'] = mtype
|
110
146
|
res['content-range'] = "bytes #{first}-#{last}/#{filesize}"
|
111
|
-
res['content-length'] = last - first + 1
|
112
|
-
res.body =
|
147
|
+
res['content-length'] = (last - first + 1).to_s
|
148
|
+
res.body = io.dup
|
113
149
|
else
|
114
150
|
raise HTTPStatus::BadRequest
|
115
151
|
end
|
@@ -123,13 +159,21 @@ module WEBrick
|
|
123
159
|
last = filesize - 1 if last >= filesize
|
124
160
|
return first, last
|
125
161
|
end
|
162
|
+
|
163
|
+
# :startdoc:
|
126
164
|
end
|
127
165
|
|
128
166
|
##
|
129
|
-
# Serves
|
167
|
+
# Serves a directory including fancy indexing and a variety of other
|
168
|
+
# options.
|
169
|
+
#
|
170
|
+
# Example:
|
171
|
+
#
|
172
|
+
# server.mount('/assets', WEBrick::HTTPServlet::FileHandler,
|
173
|
+
# '/path/to/assets')
|
130
174
|
|
131
175
|
class FileHandler < AbstractServlet
|
132
|
-
HandlerTable = Hash.new
|
176
|
+
HandlerTable = Hash.new # :nodoc:
|
133
177
|
|
134
178
|
##
|
135
179
|
# Allow custom handling of requests for files with +suffix+ by class
|
@@ -150,19 +194,8 @@ module WEBrick
|
|
150
194
|
# Creates a FileHandler servlet on +server+ that serves files starting
|
151
195
|
# at directory +root+
|
152
196
|
#
|
153
|
-
#
|
154
|
-
#
|
155
|
-
# :AcceptableLanguages:: Array of languages allowed for accept-language
|
156
|
-
# :DirectoryCallback:: Allows preprocessing of directory requests
|
157
|
-
# :FancyIndexing:: If true, show an index for directories
|
158
|
-
# :FileCallback:: Allows preprocessing of file requests
|
159
|
-
# :HandlerCallback:: Allows preprocessing of requests
|
160
|
-
# :HandlerTable:: Maps file suffixes to file handlers.
|
161
|
-
# DefaultFileHandler is used by default but any servlet
|
162
|
-
# can be used.
|
163
|
-
# :NondisclosureName:: Do not show files matching this array of globs
|
164
|
-
# :UserDir:: Directory inside ~user to serve content from for /~user
|
165
|
-
# requests. Only works if mounted on /
|
197
|
+
# +options+ may be a Hash containing keys from
|
198
|
+
# WEBrick::Config::FileHandler or +true+ or +false+.
|
166
199
|
#
|
167
200
|
# If +options+ is true or false then +:FancyIndexing+ is enabled or
|
168
201
|
# disabled respectively.
|
@@ -177,6 +210,8 @@ module WEBrick
|
|
177
210
|
@options = default.dup.update(options)
|
178
211
|
end
|
179
212
|
|
213
|
+
# :stopdoc:
|
214
|
+
|
180
215
|
def service(req, res)
|
181
216
|
# if this class is mounted on "/" and /~username is requested.
|
182
217
|
# we're going to override path informations before invoking service.
|
@@ -409,11 +444,18 @@ module WEBrick
|
|
409
444
|
}
|
410
445
|
list.compact!
|
411
446
|
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
447
|
+
query = req.query
|
448
|
+
|
449
|
+
d0 = nil
|
450
|
+
idx = nil
|
451
|
+
%w[N M S].each_with_index do |q, i|
|
452
|
+
if d = query.delete(q)
|
453
|
+
idx ||= i
|
454
|
+
d0 ||= d
|
455
|
+
end
|
416
456
|
end
|
457
|
+
d0 ||= "A"
|
458
|
+
idx ||= 0
|
417
459
|
d1 = (d0 == "A") ? "D" : "A"
|
418
460
|
|
419
461
|
if d0 == "A"
|
@@ -422,38 +464,66 @@ module WEBrick
|
|
422
464
|
list.sort!{|a,b| b[idx] <=> a[idx] }
|
423
465
|
end
|
424
466
|
|
425
|
-
|
467
|
+
namewidth = query["NameWidth"]
|
468
|
+
if namewidth == "*"
|
469
|
+
namewidth = nil
|
470
|
+
elsif !namewidth or (namewidth = namewidth.to_i) < 2
|
471
|
+
namewidth = 25
|
472
|
+
end
|
473
|
+
query = query.inject('') {|s, (k, v)| s << '&' << HTMLUtils::escape("#{k}=#{v}")}
|
474
|
+
|
475
|
+
type = "text/html"
|
476
|
+
case enc = Encoding.find('filesystem')
|
477
|
+
when Encoding::US_ASCII, Encoding::ASCII_8BIT
|
478
|
+
else
|
479
|
+
type << "; charset=\"#{enc.name}\""
|
480
|
+
end
|
481
|
+
res['content-type'] = type
|
426
482
|
|
483
|
+
title = "Index of #{HTMLUtils::escape(req.path)}"
|
427
484
|
res.body = <<-_end_of_html_
|
428
485
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
429
486
|
<HTML>
|
430
|
-
<HEAD
|
487
|
+
<HEAD>
|
488
|
+
<TITLE>#{title}</TITLE>
|
489
|
+
<style type="text/css">
|
490
|
+
<!--
|
491
|
+
.name, .mtime { text-align: left; }
|
492
|
+
.size { text-align: right; }
|
493
|
+
td { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; }
|
494
|
+
table { border-collapse: collapse; }
|
495
|
+
tr th { border-bottom: 2px groove; }
|
496
|
+
//-->
|
497
|
+
</style>
|
498
|
+
</HEAD>
|
431
499
|
<BODY>
|
432
|
-
<H1
|
500
|
+
<H1>#{title}</H1>
|
433
501
|
_end_of_html_
|
434
502
|
|
435
|
-
res.body << "<
|
436
|
-
res.body << "
|
437
|
-
res.body << "<A HREF=\"?M=#{d1}\">Last modified</A>
|
438
|
-
res.body << "<A HREF=\"?S=#{d1}\">Size</A>\n"
|
439
|
-
res.body << "
|
503
|
+
res.body << "<TABLE width=\"100%\"><THEAD><TR>\n"
|
504
|
+
res.body << "<TH class=\"name\"><A HREF=\"?N=#{d1}#{query}\">Name</A></TH>"
|
505
|
+
res.body << "<TH class=\"mtime\"><A HREF=\"?M=#{d1}#{query}\">Last modified</A></TH>"
|
506
|
+
res.body << "<TH class=\"size\"><A HREF=\"?S=#{d1}#{query}\">Size</A></TH>\n"
|
507
|
+
res.body << "</TR></THEAD>\n"
|
508
|
+
res.body << "<TBODY>\n"
|
440
509
|
|
510
|
+
query.sub!(/\A&/, '?')
|
441
511
|
list.unshift [ "..", File::mtime(local_path+"/.."), -1 ]
|
442
512
|
list.each{ |name, time, size|
|
443
513
|
if name == ".."
|
444
514
|
dname = "Parent Directory"
|
445
|
-
elsif name.
|
446
|
-
dname = name
|
515
|
+
elsif namewidth and name.size > namewidth
|
516
|
+
dname = name[0...(namewidth - 2)] << '..'
|
447
517
|
else
|
448
518
|
dname = name
|
449
519
|
end
|
450
|
-
s = "
|
451
|
-
s << " "
|
452
|
-
s << (
|
453
|
-
s << (size >= 0 ? size.to_s : "-") << "\n"
|
520
|
+
s = "<TR><TD class=\"name\"><A HREF=\"#{HTTPUtils::escape(name)}#{query if name.end_with?('/')}\">#{HTMLUtils::escape(dname)}</A></TD>"
|
521
|
+
s << "<TD class=\"mtime\">" << (time ? time.strftime("%Y/%m/%d %H:%M") : "") << "</TD>"
|
522
|
+
s << "<TD class=\"size\">" << (size >= 0 ? size.to_s : "-") << "</TD></TR>\n"
|
454
523
|
res.body << s
|
455
524
|
}
|
456
|
-
res.body << "</
|
525
|
+
res.body << "</TBODY></TABLE>"
|
526
|
+
res.body << "<HR>"
|
457
527
|
|
458
528
|
res.body << <<-_end_of_html_
|
459
529
|
<ADDRESS>
|
@@ -465,6 +535,7 @@ module WEBrick
|
|
465
535
|
_end_of_html_
|
466
536
|
end
|
467
537
|
|
538
|
+
# :startdoc:
|
468
539
|
end
|
469
540
|
end
|
470
541
|
end
|