webrick 1.3.1 → 1.6.1
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.
Potentially problematic release.
This version of webrick might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +63 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/webrick.rb +7 -7
- data/lib/webrick/accesslog.rb +12 -6
- 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 +201 -31
- data/lib/webrick/httpresponse.rb +235 -70
- 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 +29 -11
- 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 +134 -17
- 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
- data/webrick.gemspec +76 -0
- metadata +73 -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
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# prochandler.rb -- ProcHandler Class
|
3
4
|
#
|
@@ -8,12 +9,24 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: prochandler.rb,v 1.7 2002/09/21 12:23:42 gotoyuzo Exp $
|
10
11
|
|
11
|
-
|
12
|
+
require_relative 'abstract'
|
12
13
|
|
13
14
|
module WEBrick
|
14
15
|
module HTTPServlet
|
15
16
|
|
17
|
+
##
|
18
|
+
# Mounts a proc at a path that accepts a request and response.
|
19
|
+
#
|
20
|
+
# Instead of mounting this servlet with WEBrick::HTTPServer#mount use
|
21
|
+
# WEBrick::HTTPServer#mount_proc:
|
22
|
+
#
|
23
|
+
# server.mount_proc '/' do |req, res|
|
24
|
+
# res.body = 'it worked!'
|
25
|
+
# res.status = 200
|
26
|
+
# end
|
27
|
+
|
16
28
|
class ProcHandler < AbstractServlet
|
29
|
+
# :stopdoc:
|
17
30
|
def get_instance(server, *options)
|
18
31
|
self
|
19
32
|
end
|
@@ -27,6 +40,7 @@ module WEBrick
|
|
27
40
|
end
|
28
41
|
|
29
42
|
alias do_POST do_GET
|
43
|
+
# :startdoc:
|
30
44
|
end
|
31
45
|
|
32
46
|
end
|
data/lib/webrick/httpstatus.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#--
|
2
3
|
# httpstatus.rb -- HTTPStatus Class
|
3
4
|
#
|
@@ -8,6 +9,8 @@
|
|
8
9
|
#
|
9
10
|
# $IPR: httpstatus.rb,v 1.11 2003/03/24 20:18:55 gotoyuzo Exp $
|
10
11
|
|
12
|
+
require_relative 'accesslog'
|
13
|
+
|
11
14
|
module WEBrick
|
12
15
|
|
13
16
|
##
|
@@ -20,26 +23,22 @@ module WEBrick
|
|
20
23
|
##
|
21
24
|
# Root of the HTTP status class hierarchy
|
22
25
|
class Status < StandardError
|
23
|
-
def initialize(*args) # :nodoc:
|
24
|
-
args[0] = AccessLog.escape(args[0]) unless args.empty?
|
25
|
-
super(*args)
|
26
|
-
end
|
27
26
|
class << self
|
28
27
|
attr_reader :code, :reason_phrase # :nodoc:
|
29
28
|
end
|
30
|
-
|
29
|
+
|
31
30
|
# Returns the HTTP status code
|
32
31
|
def code() self::class::code end
|
33
|
-
|
32
|
+
|
34
33
|
# Returns the HTTP status description
|
35
34
|
def reason_phrase() self::class::reason_phrase end
|
36
|
-
|
35
|
+
|
37
36
|
alias to_i code # :nodoc:
|
38
37
|
end
|
39
38
|
|
40
39
|
# Root of the HTTP info statuses
|
41
40
|
class Info < Status; end
|
42
|
-
# Root of the HTTP
|
41
|
+
# Root of the HTTP success statuses
|
43
42
|
class Success < Status; end
|
44
43
|
# Root of the HTTP redirect statuses
|
45
44
|
class Redirect < Status; end
|
@@ -63,6 +62,7 @@ module WEBrick
|
|
63
62
|
204 => 'No Content',
|
64
63
|
205 => 'Reset Content',
|
65
64
|
206 => 'Partial Content',
|
65
|
+
207 => 'Multi-Status',
|
66
66
|
300 => 'Multiple Choices',
|
67
67
|
301 => 'Moved Permanently',
|
68
68
|
302 => 'Found',
|
@@ -88,12 +88,22 @@ module WEBrick
|
|
88
88
|
415 => 'Unsupported Media Type',
|
89
89
|
416 => 'Request Range Not Satisfiable',
|
90
90
|
417 => 'Expectation Failed',
|
91
|
+
422 => 'Unprocessable Entity',
|
92
|
+
423 => 'Locked',
|
93
|
+
424 => 'Failed Dependency',
|
94
|
+
426 => 'Upgrade Required',
|
95
|
+
428 => 'Precondition Required',
|
96
|
+
429 => 'Too Many Requests',
|
97
|
+
431 => 'Request Header Fields Too Large',
|
98
|
+
451 => 'Unavailable For Legal Reasons',
|
91
99
|
500 => 'Internal Server Error',
|
92
100
|
501 => 'Not Implemented',
|
93
101
|
502 => 'Bad Gateway',
|
94
102
|
503 => 'Service Unavailable',
|
95
103
|
504 => 'Gateway Timeout',
|
96
|
-
505 => 'HTTP Version Not Supported'
|
104
|
+
505 => 'HTTP Version Not Supported',
|
105
|
+
507 => 'Insufficient Storage',
|
106
|
+
511 => 'Network Authentication Required',
|
97
107
|
}
|
98
108
|
|
99
109
|
# Maps a status code to the corresponding Status class
|
@@ -136,31 +146,31 @@ module WEBrick
|
|
136
146
|
def info?(code)
|
137
147
|
code.to_i >= 100 and code.to_i < 200
|
138
148
|
end
|
139
|
-
|
149
|
+
|
140
150
|
##
|
141
151
|
# Is +code+ a successful status?
|
142
152
|
def success?(code)
|
143
153
|
code.to_i >= 200 and code.to_i < 300
|
144
154
|
end
|
145
|
-
|
155
|
+
|
146
156
|
##
|
147
157
|
# Is +code+ a redirection status?
|
148
158
|
def redirect?(code)
|
149
159
|
code.to_i >= 300 and code.to_i < 400
|
150
160
|
end
|
151
|
-
|
161
|
+
|
152
162
|
##
|
153
163
|
# Is +code+ an error status?
|
154
164
|
def error?(code)
|
155
165
|
code.to_i >= 400 and code.to_i < 600
|
156
166
|
end
|
157
|
-
|
167
|
+
|
158
168
|
##
|
159
169
|
# Is +code+ a client error status?
|
160
170
|
def client_error?(code)
|
161
171
|
code.to_i >= 400 and code.to_i < 500
|
162
172
|
end
|
163
|
-
|
173
|
+
|
164
174
|
##
|
165
175
|
# Is +code+ a server error status?
|
166
176
|
def server_error?(code)
|
data/lib/webrick/httputils.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: false
|
1
2
|
#
|
2
3
|
# httputils.rb -- HTTPUtils Module
|
3
4
|
#
|
@@ -12,12 +13,21 @@ require 'socket'
|
|
12
13
|
require 'tempfile'
|
13
14
|
|
14
15
|
module WEBrick
|
15
|
-
CR = "\x0d"
|
16
|
-
LF = "\x0a"
|
17
|
-
CRLF = "\x0d\x0a"
|
16
|
+
CR = "\x0d" # :nodoc:
|
17
|
+
LF = "\x0a" # :nodoc:
|
18
|
+
CRLF = "\x0d\x0a" # :nodoc:
|
19
|
+
|
20
|
+
##
|
21
|
+
# HTTPUtils provides utility methods for working with the HTTP protocol.
|
22
|
+
#
|
23
|
+
# This module is generally used internally by WEBrick
|
18
24
|
|
19
25
|
module HTTPUtils
|
20
26
|
|
27
|
+
##
|
28
|
+
# Normalizes a request path. Raises an exception if the path cannot be
|
29
|
+
# normalized.
|
30
|
+
|
21
31
|
def normalize_path(path)
|
22
32
|
raise "abnormal path `#{path}'" if path[0] != ?/
|
23
33
|
ret = path.dup
|
@@ -31,7 +41,8 @@ module WEBrick
|
|
31
41
|
end
|
32
42
|
module_function :normalize_path
|
33
43
|
|
34
|
-
|
44
|
+
##
|
45
|
+
# Default mime types
|
35
46
|
|
36
47
|
DefaultMimeTypes = {
|
37
48
|
"ai" => "application/postscript",
|
@@ -58,6 +69,7 @@ module WEBrick
|
|
58
69
|
"jpeg" => "image/jpeg",
|
59
70
|
"jpg" => "image/jpeg",
|
60
71
|
"js" => "application/javascript",
|
72
|
+
"json" => "application/json",
|
61
73
|
"lha" => "application/octet-stream",
|
62
74
|
"lzh" => "application/octet-stream",
|
63
75
|
"mov" => "video/quicktime",
|
@@ -83,6 +95,7 @@ module WEBrick
|
|
83
95
|
"tif" => "image/tiff",
|
84
96
|
"tiff" => "image/tiff",
|
85
97
|
"txt" => "text/plain",
|
98
|
+
"wasm" => "application/wasm",
|
86
99
|
"xbm" => "image/x-xbitmap",
|
87
100
|
"xhtml" => "text/html",
|
88
101
|
"xls" => "application/vnd.ms-excel",
|
@@ -92,8 +105,12 @@ module WEBrick
|
|
92
105
|
"zip" => "application/zip",
|
93
106
|
}
|
94
107
|
|
95
|
-
|
108
|
+
##
|
109
|
+
# Loads Apache-compatible mime.types in +file+.
|
110
|
+
|
96
111
|
def load_mime_types(file)
|
112
|
+
# note: +file+ may be a "| command" for now; some people may
|
113
|
+
# rely on this, but currently we do not use this method by default.
|
97
114
|
open(file){ |io|
|
98
115
|
hash = Hash.new
|
99
116
|
io.each{ |line|
|
@@ -109,6 +126,10 @@ module WEBrick
|
|
109
126
|
end
|
110
127
|
module_function :load_mime_types
|
111
128
|
|
129
|
+
##
|
130
|
+
# Returns the mime type of +filename+ from the list in +mime_tab+. If no
|
131
|
+
# mime type was found application/octet-stream is returned.
|
132
|
+
|
112
133
|
def mime_type(filename, mime_tab)
|
113
134
|
suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
|
114
135
|
suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
|
@@ -116,7 +137,9 @@ module WEBrick
|
|
116
137
|
end
|
117
138
|
module_function :mime_type
|
118
139
|
|
119
|
-
|
140
|
+
##
|
141
|
+
# Parses an HTTP header +raw+ into a hash of header fields with an Array
|
142
|
+
# of values.
|
120
143
|
|
121
144
|
def parse_header(raw)
|
122
145
|
header = Hash.new([].freeze)
|
@@ -139,21 +162,24 @@ module WEBrick
|
|
139
162
|
end
|
140
163
|
}
|
141
164
|
header.each{|key, values|
|
142
|
-
values.each
|
143
|
-
value.strip!
|
144
|
-
value.gsub!(/\s+/, " ")
|
145
|
-
}
|
165
|
+
values.each(&:strip!)
|
146
166
|
}
|
147
167
|
header
|
148
168
|
end
|
149
169
|
module_function :parse_header
|
150
170
|
|
171
|
+
##
|
172
|
+
# Splits a header value +str+ according to HTTP specification.
|
173
|
+
|
151
174
|
def split_header_value(str)
|
152
175
|
str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
|
153
176
|
(?:,\s*|\Z)'xn).flatten
|
154
177
|
end
|
155
178
|
module_function :split_header_value
|
156
179
|
|
180
|
+
##
|
181
|
+
# Parses a Range header value +ranges_specifier+
|
182
|
+
|
157
183
|
def parse_range_header(ranges_specifier)
|
158
184
|
if /^bytes=(.*)/ =~ ranges_specifier
|
159
185
|
byte_range_set = split_header_value($1)
|
@@ -169,6 +195,9 @@ module WEBrick
|
|
169
195
|
end
|
170
196
|
module_function :parse_range_header
|
171
197
|
|
198
|
+
##
|
199
|
+
# Parses q values in +value+ as used in Accept headers.
|
200
|
+
|
172
201
|
def parse_qvalues(value)
|
173
202
|
tmp = []
|
174
203
|
if value
|
@@ -187,7 +216,8 @@ module WEBrick
|
|
187
216
|
end
|
188
217
|
module_function :parse_qvalues
|
189
218
|
|
190
|
-
|
219
|
+
##
|
220
|
+
# Removes quotes and escapes from +str+
|
191
221
|
|
192
222
|
def dequote(str)
|
193
223
|
ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
|
@@ -196,20 +226,43 @@ module WEBrick
|
|
196
226
|
end
|
197
227
|
module_function :dequote
|
198
228
|
|
229
|
+
##
|
230
|
+
# Quotes and escapes quotes in +str+
|
231
|
+
|
199
232
|
def quote(str)
|
200
233
|
'"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
|
201
234
|
end
|
202
235
|
module_function :quote
|
203
236
|
|
204
|
-
|
237
|
+
##
|
238
|
+
# Stores multipart form data. FormData objects are created when
|
239
|
+
# WEBrick::HTTPUtils.parse_form_data is called.
|
205
240
|
|
206
241
|
class FormData < String
|
207
|
-
EmptyRawHeader = [].freeze
|
208
|
-
EmptyHeader = {}.freeze
|
242
|
+
EmptyRawHeader = [].freeze # :nodoc:
|
243
|
+
EmptyHeader = {}.freeze # :nodoc:
|
244
|
+
|
245
|
+
##
|
246
|
+
# The name of the form data part
|
247
|
+
|
248
|
+
attr_accessor :name
|
209
249
|
|
210
|
-
|
250
|
+
##
|
251
|
+
# The filename of the form data part
|
252
|
+
|
253
|
+
attr_accessor :filename
|
254
|
+
|
255
|
+
attr_accessor :next_data # :nodoc:
|
211
256
|
protected :next_data
|
212
257
|
|
258
|
+
##
|
259
|
+
# Creates a new FormData object.
|
260
|
+
#
|
261
|
+
# +args+ is an Array of form data entries. One FormData will be created
|
262
|
+
# for each entry.
|
263
|
+
#
|
264
|
+
# This is called by WEBrick::HTTPUtils.parse_form_data for you
|
265
|
+
|
213
266
|
def initialize(*args)
|
214
267
|
@name = @filename = @next_data = nil
|
215
268
|
if args.empty?
|
@@ -226,6 +279,9 @@ module WEBrick
|
|
226
279
|
end
|
227
280
|
end
|
228
281
|
|
282
|
+
##
|
283
|
+
# Retrieves the header at the first entry in +key+
|
284
|
+
|
229
285
|
def [](*key)
|
230
286
|
begin
|
231
287
|
@header[key[0].downcase].join(", ")
|
@@ -234,6 +290,12 @@ module WEBrick
|
|
234
290
|
end
|
235
291
|
end
|
236
292
|
|
293
|
+
##
|
294
|
+
# Adds +str+ to this FormData which may be the body, a header or a
|
295
|
+
# header entry.
|
296
|
+
#
|
297
|
+
# This is called by WEBrick::HTTPUtils.parse_form_data for you
|
298
|
+
|
237
299
|
def <<(str)
|
238
300
|
if @header
|
239
301
|
super
|
@@ -249,6 +311,11 @@ module WEBrick
|
|
249
311
|
self
|
250
312
|
end
|
251
313
|
|
314
|
+
##
|
315
|
+
# Adds +data+ at the end of the chain of entries
|
316
|
+
#
|
317
|
+
# This is called by WEBrick::HTTPUtils.parse_form_data for you.
|
318
|
+
|
252
319
|
def append_data(data)
|
253
320
|
tmp = self
|
254
321
|
while tmp
|
@@ -261,6 +328,9 @@ module WEBrick
|
|
261
328
|
self
|
262
329
|
end
|
263
330
|
|
331
|
+
##
|
332
|
+
# Yields each entry in this FormData
|
333
|
+
|
264
334
|
def each_data
|
265
335
|
tmp = self
|
266
336
|
while tmp
|
@@ -270,6 +340,9 @@ module WEBrick
|
|
270
340
|
end
|
271
341
|
end
|
272
342
|
|
343
|
+
##
|
344
|
+
# Returns all the FormData as an Array
|
345
|
+
|
273
346
|
def list
|
274
347
|
ret = []
|
275
348
|
each_data{|data|
|
@@ -278,13 +351,22 @@ module WEBrick
|
|
278
351
|
ret
|
279
352
|
end
|
280
353
|
|
354
|
+
##
|
355
|
+
# A FormData will behave like an Array
|
356
|
+
|
281
357
|
alias :to_ary :list
|
282
358
|
|
359
|
+
##
|
360
|
+
# This FormData's body
|
361
|
+
|
283
362
|
def to_s
|
284
363
|
String.new(self)
|
285
364
|
end
|
286
365
|
end
|
287
366
|
|
367
|
+
##
|
368
|
+
# Parses the query component of a URI in +str+
|
369
|
+
|
288
370
|
def parse_query(str)
|
289
371
|
query = Hash.new
|
290
372
|
if str
|
@@ -306,6 +388,9 @@ module WEBrick
|
|
306
388
|
end
|
307
389
|
module_function :parse_query
|
308
390
|
|
391
|
+
##
|
392
|
+
# Parses form data in +io+ with the given +boundary+
|
393
|
+
|
309
394
|
def parse_form_data(io, boundary)
|
310
395
|
boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/
|
311
396
|
form_data = Hash.new
|
@@ -350,10 +435,22 @@ module WEBrick
|
|
350
435
|
|
351
436
|
module_function
|
352
437
|
|
438
|
+
# :stopdoc:
|
439
|
+
|
353
440
|
def _make_regex(str) /([#{Regexp.escape(str)}])/n end
|
354
441
|
def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
|
355
|
-
def _escape(str, regex)
|
356
|
-
|
442
|
+
def _escape(str, regex)
|
443
|
+
str = str.b
|
444
|
+
str.gsub!(regex) {"%%%02X" % $1.ord}
|
445
|
+
# %-escaped string should contain US-ASCII only
|
446
|
+
str.force_encoding(Encoding::US_ASCII)
|
447
|
+
end
|
448
|
+
def _unescape(str, regex)
|
449
|
+
str = str.b
|
450
|
+
str.gsub!(regex) {$1.hex.chr}
|
451
|
+
# encoding of %-unescaped string is unknown
|
452
|
+
str
|
453
|
+
end
|
357
454
|
|
358
455
|
UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
|
359
456
|
UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
|
@@ -361,24 +458,41 @@ module WEBrick
|
|
361
458
|
ESCAPED = /%([0-9a-fA-F]{2})/
|
362
459
|
UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
|
363
460
|
|
461
|
+
# :startdoc:
|
462
|
+
|
463
|
+
##
|
464
|
+
# Escapes HTTP reserved and unwise characters in +str+
|
465
|
+
|
364
466
|
def escape(str)
|
365
467
|
_escape(str, UNESCAPED)
|
366
468
|
end
|
367
469
|
|
470
|
+
##
|
471
|
+
# Unescapes HTTP reserved and unwise characters in +str+
|
472
|
+
|
368
473
|
def unescape(str)
|
369
474
|
_unescape(str, ESCAPED)
|
370
475
|
end
|
371
476
|
|
477
|
+
##
|
478
|
+
# Escapes form reserved characters in +str+
|
479
|
+
|
372
480
|
def escape_form(str)
|
373
481
|
ret = _escape(str, UNESCAPED_FORM)
|
374
482
|
ret.gsub!(/ /, "+")
|
375
483
|
ret
|
376
484
|
end
|
377
485
|
|
486
|
+
##
|
487
|
+
# Unescapes form reserved characters in +str+
|
488
|
+
|
378
489
|
def unescape_form(str)
|
379
490
|
_unescape(str.gsub(/\+/, " "), ESCAPED)
|
380
491
|
end
|
381
492
|
|
493
|
+
##
|
494
|
+
# Escapes path +str+
|
495
|
+
|
382
496
|
def escape_path(str)
|
383
497
|
result = ""
|
384
498
|
str.scan(%r{/([^/]*)}).each{|i|
|
@@ -387,6 +501,9 @@ module WEBrick
|
|
387
501
|
return result
|
388
502
|
end
|
389
503
|
|
504
|
+
##
|
505
|
+
# Escapes 8 bit characters in +str+
|
506
|
+
|
390
507
|
def escape8bit(str)
|
391
508
|
_escape(str, NONASCII)
|
392
509
|
end
|