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.

Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/lib/webrick.rb +6 -6
  3. data/lib/webrick/accesslog.rb +9 -1
  4. data/lib/webrick/cgi.rb +58 -5
  5. data/lib/webrick/compat.rb +2 -1
  6. data/lib/webrick/config.rb +47 -10
  7. data/lib/webrick/cookie.rb +69 -7
  8. data/lib/webrick/htmlutils.rb +4 -2
  9. data/lib/webrick/httpauth.rb +6 -5
  10. data/lib/webrick/httpauth/authenticator.rb +13 -8
  11. data/lib/webrick/httpauth/basicauth.rb +16 -8
  12. data/lib/webrick/httpauth/digestauth.rb +35 -32
  13. data/lib/webrick/httpauth/htdigest.rb +12 -8
  14. data/lib/webrick/httpauth/htgroup.rb +10 -6
  15. data/lib/webrick/httpauth/htpasswd.rb +46 -9
  16. data/lib/webrick/httpauth/userdb.rb +1 -0
  17. data/lib/webrick/httpproxy.rb +93 -48
  18. data/lib/webrick/httprequest.rb +192 -27
  19. data/lib/webrick/httpresponse.rb +182 -62
  20. data/lib/webrick/https.rb +90 -2
  21. data/lib/webrick/httpserver.rb +45 -15
  22. data/lib/webrick/httpservlet.rb +6 -5
  23. data/lib/webrick/httpservlet/abstract.rb +5 -6
  24. data/lib/webrick/httpservlet/cgi_runner.rb +3 -2
  25. data/lib/webrick/httpservlet/cgihandler.rb +22 -10
  26. data/lib/webrick/httpservlet/erbhandler.rb +4 -3
  27. data/lib/webrick/httpservlet/filehandler.rb +136 -65
  28. data/lib/webrick/httpservlet/prochandler.rb +15 -1
  29. data/lib/webrick/httpstatus.rb +24 -14
  30. data/lib/webrick/httputils.rb +132 -13
  31. data/lib/webrick/httpversion.rb +28 -1
  32. data/lib/webrick/log.rb +25 -5
  33. data/lib/webrick/server.rb +234 -74
  34. data/lib/webrick/ssl.rb +100 -12
  35. data/lib/webrick/utils.rb +98 -69
  36. data/lib/webrick/version.rb +6 -1
  37. metadata +66 -72
  38. data/README.txt +0 -21
  39. data/sample/webrick/demo-app.rb +0 -66
  40. data/sample/webrick/demo-multipart.cgi +0 -12
  41. data/sample/webrick/demo-servlet.rb +0 -6
  42. data/sample/webrick/demo-urlencoded.cgi +0 -12
  43. data/sample/webrick/hello.cgi +0 -11
  44. data/sample/webrick/hello.rb +0 -8
  45. data/sample/webrick/httpd.rb +0 -23
  46. data/sample/webrick/httpproxy.rb +0 -25
  47. data/sample/webrick/httpsd.rb +0 -33
  48. data/test/openssl/utils.rb +0 -313
  49. data/test/ruby/envutil.rb +0 -208
  50. data/test/webrick/test_cgi.rb +0 -134
  51. data/test/webrick/test_cookie.rb +0 -131
  52. data/test/webrick/test_filehandler.rb +0 -285
  53. data/test/webrick/test_httpauth.rb +0 -167
  54. data/test/webrick/test_httpproxy.rb +0 -282
  55. data/test/webrick/test_httprequest.rb +0 -411
  56. data/test/webrick/test_httpresponse.rb +0 -49
  57. data/test/webrick/test_httpserver.rb +0 -305
  58. data/test/webrick/test_httputils.rb +0 -96
  59. data/test/webrick/test_httpversion.rb +0 -40
  60. data/test/webrick/test_server.rb +0 -67
  61. data/test/webrick/test_utils.rb +0 -64
  62. data/test/webrick/utils.rb +0 -58
  63. data/test/webrick/webrick.cgi +0 -36
  64. 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
- require 'webrick/httpservlet/abstract.rb'
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
@@ -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 sucess statuses
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)
@@ -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",
@@ -92,8 +104,12 @@ module WEBrick
92
104
  "zip" => "application/zip",
93
105
  }
94
106
 
95
- # Load Apache compatible mime.types file.
107
+ ##
108
+ # Loads Apache-compatible mime.types in +file+.
109
+
96
110
  def load_mime_types(file)
111
+ # note: +file+ may be a "| command" for now; some people may
112
+ # rely on this, but currently we do not use this method by default.
97
113
  open(file){ |io|
98
114
  hash = Hash.new
99
115
  io.each{ |line|
@@ -109,6 +125,10 @@ module WEBrick
109
125
  end
110
126
  module_function :load_mime_types
111
127
 
128
+ ##
129
+ # Returns the mime type of +filename+ from the list in +mime_tab+. If no
130
+ # mime type was found application/octet-stream is returned.
131
+
112
132
  def mime_type(filename, mime_tab)
113
133
  suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
114
134
  suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
@@ -116,7 +136,9 @@ module WEBrick
116
136
  end
117
137
  module_function :mime_type
118
138
 
119
- #####
139
+ ##
140
+ # Parses an HTTP header +raw+ into a hash of header fields with an Array
141
+ # of values.
120
142
 
121
143
  def parse_header(raw)
122
144
  header = Hash.new([].freeze)
@@ -148,12 +170,18 @@ module WEBrick
148
170
  end
149
171
  module_function :parse_header
150
172
 
173
+ ##
174
+ # Splits a header value +str+ according to HTTP specification.
175
+
151
176
  def split_header_value(str)
152
177
  str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
153
178
  (?:,\s*|\Z)'xn).flatten
154
179
  end
155
180
  module_function :split_header_value
156
181
 
182
+ ##
183
+ # Parses a Range header value +ranges_specifier+
184
+
157
185
  def parse_range_header(ranges_specifier)
158
186
  if /^bytes=(.*)/ =~ ranges_specifier
159
187
  byte_range_set = split_header_value($1)
@@ -169,6 +197,9 @@ module WEBrick
169
197
  end
170
198
  module_function :parse_range_header
171
199
 
200
+ ##
201
+ # Parses q values in +value+ as used in Accept headers.
202
+
172
203
  def parse_qvalues(value)
173
204
  tmp = []
174
205
  if value
@@ -187,7 +218,8 @@ module WEBrick
187
218
  end
188
219
  module_function :parse_qvalues
189
220
 
190
- #####
221
+ ##
222
+ # Removes quotes and escapes from +str+
191
223
 
192
224
  def dequote(str)
193
225
  ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
@@ -196,20 +228,43 @@ module WEBrick
196
228
  end
197
229
  module_function :dequote
198
230
 
231
+ ##
232
+ # Quotes and escapes quotes in +str+
233
+
199
234
  def quote(str)
200
235
  '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
201
236
  end
202
237
  module_function :quote
203
238
 
204
- #####
239
+ ##
240
+ # Stores multipart form data. FormData objects are created when
241
+ # WEBrick::HTTPUtils.parse_form_data is called.
205
242
 
206
243
  class FormData < String
207
- EmptyRawHeader = [].freeze
208
- EmptyHeader = {}.freeze
244
+ EmptyRawHeader = [].freeze # :nodoc:
245
+ EmptyHeader = {}.freeze # :nodoc:
246
+
247
+ ##
248
+ # The name of the form data part
249
+
250
+ attr_accessor :name
209
251
 
210
- attr_accessor :name, :filename, :next_data
252
+ ##
253
+ # The filename of the form data part
254
+
255
+ attr_accessor :filename
256
+
257
+ attr_accessor :next_data # :nodoc:
211
258
  protected :next_data
212
259
 
260
+ ##
261
+ # Creates a new FormData object.
262
+ #
263
+ # +args+ is an Array of form data entries. One FormData will be created
264
+ # for each entry.
265
+ #
266
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you
267
+
213
268
  def initialize(*args)
214
269
  @name = @filename = @next_data = nil
215
270
  if args.empty?
@@ -226,6 +281,9 @@ module WEBrick
226
281
  end
227
282
  end
228
283
 
284
+ ##
285
+ # Retrieves the header at the first entry in +key+
286
+
229
287
  def [](*key)
230
288
  begin
231
289
  @header[key[0].downcase].join(", ")
@@ -234,6 +292,12 @@ module WEBrick
234
292
  end
235
293
  end
236
294
 
295
+ ##
296
+ # Adds +str+ to this FormData which may be the body, a header or a
297
+ # header entry.
298
+ #
299
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you
300
+
237
301
  def <<(str)
238
302
  if @header
239
303
  super
@@ -249,6 +313,11 @@ module WEBrick
249
313
  self
250
314
  end
251
315
 
316
+ ##
317
+ # Adds +data+ at the end of the chain of entries
318
+ #
319
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you.
320
+
252
321
  def append_data(data)
253
322
  tmp = self
254
323
  while tmp
@@ -261,6 +330,9 @@ module WEBrick
261
330
  self
262
331
  end
263
332
 
333
+ ##
334
+ # Yields each entry in this FormData
335
+
264
336
  def each_data
265
337
  tmp = self
266
338
  while tmp
@@ -270,6 +342,9 @@ module WEBrick
270
342
  end
271
343
  end
272
344
 
345
+ ##
346
+ # Returns all the FormData as an Array
347
+
273
348
  def list
274
349
  ret = []
275
350
  each_data{|data|
@@ -278,13 +353,22 @@ module WEBrick
278
353
  ret
279
354
  end
280
355
 
356
+ ##
357
+ # A FormData will behave like an Array
358
+
281
359
  alias :to_ary :list
282
360
 
361
+ ##
362
+ # This FormData's body
363
+
283
364
  def to_s
284
365
  String.new(self)
285
366
  end
286
367
  end
287
368
 
369
+ ##
370
+ # Parses the query component of a URI in +str+
371
+
288
372
  def parse_query(str)
289
373
  query = Hash.new
290
374
  if str
@@ -306,6 +390,9 @@ module WEBrick
306
390
  end
307
391
  module_function :parse_query
308
392
 
393
+ ##
394
+ # Parses form data in +io+ with the given +boundary+
395
+
309
396
  def parse_form_data(io, boundary)
310
397
  boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/
311
398
  form_data = Hash.new
@@ -350,10 +437,22 @@ module WEBrick
350
437
 
351
438
  module_function
352
439
 
440
+ # :stopdoc:
441
+
353
442
  def _make_regex(str) /([#{Regexp.escape(str)}])/n end
354
443
  def _make_regex!(str) /([^#{Regexp.escape(str)}])/n end
355
- def _escape(str, regex) str.gsub(regex){ "%%%02X" % $1.ord } end
356
- def _unescape(str, regex) str.gsub(regex){ $1.hex.chr } end
444
+ def _escape(str, regex)
445
+ str = str.b
446
+ str.gsub!(regex) {"%%%02X" % $1.ord}
447
+ # %-escaped string should contain US-ASCII only
448
+ str.force_encoding(Encoding::US_ASCII)
449
+ end
450
+ def _unescape(str, regex)
451
+ str = str.b
452
+ str.gsub!(regex) {$1.hex.chr}
453
+ # encoding of %-unescaped string is unknown
454
+ str
455
+ end
357
456
 
358
457
  UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
359
458
  UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
@@ -361,24 +460,41 @@ module WEBrick
361
460
  ESCAPED = /%([0-9a-fA-F]{2})/
362
461
  UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
363
462
 
463
+ # :startdoc:
464
+
465
+ ##
466
+ # Escapes HTTP reserved and unwise characters in +str+
467
+
364
468
  def escape(str)
365
469
  _escape(str, UNESCAPED)
366
470
  end
367
471
 
472
+ ##
473
+ # Unescapes HTTP reserved and unwise characters in +str+
474
+
368
475
  def unescape(str)
369
476
  _unescape(str, ESCAPED)
370
477
  end
371
478
 
479
+ ##
480
+ # Escapes form reserved characters in +str+
481
+
372
482
  def escape_form(str)
373
483
  ret = _escape(str, UNESCAPED_FORM)
374
484
  ret.gsub!(/ /, "+")
375
485
  ret
376
486
  end
377
487
 
488
+ ##
489
+ # Unescapes form reserved characters in +str+
490
+
378
491
  def unescape_form(str)
379
492
  _unescape(str.gsub(/\+/, " "), ESCAPED)
380
493
  end
381
494
 
495
+ ##
496
+ # Escapes path +str+
497
+
382
498
  def escape_path(str)
383
499
  result = ""
384
500
  str.scan(%r{/([^/]*)}).each{|i|
@@ -387,6 +503,9 @@ module WEBrick
387
503
  return result
388
504
  end
389
505
 
506
+ ##
507
+ # Escapes 8 bit characters in +str+
508
+
390
509
  def escape8bit(str)
391
510
  _escape(str, NONASCII)
392
511
  end