webrick 1.3.1 → 1.4.0.beta1

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.

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 +51 -2
  5. data/lib/webrick/compat.rb +2 -1
  6. data/lib/webrick/config.rb +42 -5
  7. data/lib/webrick/cookie.rb +68 -6
  8. data/lib/webrick/htmlutils.rb +4 -2
  9. data/lib/webrick/httpauth.rb +1 -0
  10. data/lib/webrick/httpauth/authenticator.rb +13 -8
  11. data/lib/webrick/httpauth/basicauth.rb +3 -3
  12. data/lib/webrick/httpauth/digestauth.rb +25 -9
  13. data/lib/webrick/httpauth/htdigest.rb +8 -4
  14. data/lib/webrick/httpauth/htgroup.rb +1 -0
  15. data/lib/webrick/httpauth/htpasswd.rb +7 -3
  16. data/lib/webrick/httpauth/userdb.rb +1 -0
  17. data/lib/webrick/httpproxy.rb +47 -14
  18. data/lib/webrick/httprequest.rb +142 -16
  19. data/lib/webrick/httpresponse.rb +96 -24
  20. data/lib/webrick/https.rb +24 -1
  21. data/lib/webrick/httpserver.rb +20 -4
  22. data/lib/webrick/httpservlet.rb +1 -0
  23. data/lib/webrick/httpservlet/abstract.rb +2 -1
  24. data/lib/webrick/httpservlet/cgi_runner.rb +1 -0
  25. data/lib/webrick/httpservlet/cgihandler.rb +19 -5
  26. data/lib/webrick/httpservlet/erbhandler.rb +2 -1
  27. data/lib/webrick/httpservlet/filehandler.rb +87 -34
  28. data/lib/webrick/httpservlet/prochandler.rb +14 -0
  29. data/lib/webrick/httpstatus.rb +24 -10
  30. data/lib/webrick/httputils.rb +129 -13
  31. data/lib/webrick/httpversion.rb +28 -1
  32. data/lib/webrick/log.rb +22 -2
  33. data/lib/webrick/server.rb +203 -60
  34. data/lib/webrick/ssl.rb +80 -5
  35. data/lib/webrick/utils.rb +97 -67
  36. data/lib/webrick/version.rb +6 -1
  37. metadata +59 -69
  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
  #
@@ -13,7 +14,19 @@ require 'webrick/httpservlet/abstract.rb'
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 'webrick/accesslog'
13
+
11
14
  module WEBrick
12
15
 
13
16
  ##
@@ -27,19 +30,19 @@ module WEBrick
27
30
  class << self
28
31
  attr_reader :code, :reason_phrase # :nodoc:
29
32
  end
30
-
33
+
31
34
  # Returns the HTTP status code
32
35
  def code() self::class::code end
33
-
36
+
34
37
  # Returns the HTTP status description
35
38
  def reason_phrase() self::class::reason_phrase end
36
-
39
+
37
40
  alias to_i code # :nodoc:
38
41
  end
39
42
 
40
43
  # Root of the HTTP info statuses
41
44
  class Info < Status; end
42
- # Root of the HTTP sucess statuses
45
+ # Root of the HTTP success statuses
43
46
  class Success < Status; end
44
47
  # Root of the HTTP redirect statuses
45
48
  class Redirect < Status; end
@@ -63,6 +66,7 @@ module WEBrick
63
66
  204 => 'No Content',
64
67
  205 => 'Reset Content',
65
68
  206 => 'Partial Content',
69
+ 207 => 'Multi-Status',
66
70
  300 => 'Multiple Choices',
67
71
  301 => 'Moved Permanently',
68
72
  302 => 'Found',
@@ -88,12 +92,22 @@ module WEBrick
88
92
  415 => 'Unsupported Media Type',
89
93
  416 => 'Request Range Not Satisfiable',
90
94
  417 => 'Expectation Failed',
95
+ 422 => 'Unprocessable Entity',
96
+ 423 => 'Locked',
97
+ 424 => 'Failed Dependency',
98
+ 426 => 'Upgrade Required',
99
+ 428 => 'Precondition Required',
100
+ 429 => 'Too Many Requests',
101
+ 431 => 'Request Header Fields Too Large',
102
+ 451 => 'Unavailable For Legal Reasons',
91
103
  500 => 'Internal Server Error',
92
104
  501 => 'Not Implemented',
93
105
  502 => 'Bad Gateway',
94
106
  503 => 'Service Unavailable',
95
107
  504 => 'Gateway Timeout',
96
- 505 => 'HTTP Version Not Supported'
108
+ 505 => 'HTTP Version Not Supported',
109
+ 507 => 'Insufficient Storage',
110
+ 511 => 'Network Authentication Required',
97
111
  }
98
112
 
99
113
  # Maps a status code to the corresponding Status class
@@ -136,31 +150,31 @@ module WEBrick
136
150
  def info?(code)
137
151
  code.to_i >= 100 and code.to_i < 200
138
152
  end
139
-
153
+
140
154
  ##
141
155
  # Is +code+ a successful status?
142
156
  def success?(code)
143
157
  code.to_i >= 200 and code.to_i < 300
144
158
  end
145
-
159
+
146
160
  ##
147
161
  # Is +code+ a redirection status?
148
162
  def redirect?(code)
149
163
  code.to_i >= 300 and code.to_i < 400
150
164
  end
151
-
165
+
152
166
  ##
153
167
  # Is +code+ an error status?
154
168
  def error?(code)
155
169
  code.to_i >= 400 and code.to_i < 600
156
170
  end
157
-
171
+
158
172
  ##
159
173
  # Is +code+ a client error status?
160
174
  def client_error?(code)
161
175
  code.to_i >= 400 and code.to_i < 500
162
176
  end
163
-
177
+
164
178
  ##
165
179
  # Is +code+ a server error status?
166
180
  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",
@@ -92,7 +103,9 @@ module WEBrick
92
103
  "zip" => "application/zip",
93
104
  }
94
105
 
95
- # Load Apache compatible mime.types file.
106
+ ##
107
+ # Loads Apache-compatible mime.types in +file+.
108
+
96
109
  def load_mime_types(file)
97
110
  open(file){ |io|
98
111
  hash = Hash.new
@@ -109,6 +122,10 @@ module WEBrick
109
122
  end
110
123
  module_function :load_mime_types
111
124
 
125
+ ##
126
+ # Returns the mime type of +filename+ from the list in +mime_tab+. If no
127
+ # mime type was found application/octet-stream is returned.
128
+
112
129
  def mime_type(filename, mime_tab)
113
130
  suffix1 = (/\.(\w+)$/ =~ filename && $1.downcase)
114
131
  suffix2 = (/\.(\w+)\.[\w\-]+$/ =~ filename && $1.downcase)
@@ -116,7 +133,9 @@ module WEBrick
116
133
  end
117
134
  module_function :mime_type
118
135
 
119
- #####
136
+ ##
137
+ # Parses an HTTP header +raw+ into a hash of header fields with an Array
138
+ # of values.
120
139
 
121
140
  def parse_header(raw)
122
141
  header = Hash.new([].freeze)
@@ -148,12 +167,18 @@ module WEBrick
148
167
  end
149
168
  module_function :parse_header
150
169
 
170
+ ##
171
+ # Splits a header value +str+ according to HTTP specification.
172
+
151
173
  def split_header_value(str)
152
174
  str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
153
175
  (?:,\s*|\Z)'xn).flatten
154
176
  end
155
177
  module_function :split_header_value
156
178
 
179
+ ##
180
+ # Parses a Range header value +ranges_specifier+
181
+
157
182
  def parse_range_header(ranges_specifier)
158
183
  if /^bytes=(.*)/ =~ ranges_specifier
159
184
  byte_range_set = split_header_value($1)
@@ -169,6 +194,9 @@ module WEBrick
169
194
  end
170
195
  module_function :parse_range_header
171
196
 
197
+ ##
198
+ # Parses q values in +value+ as used in Accept headers.
199
+
172
200
  def parse_qvalues(value)
173
201
  tmp = []
174
202
  if value
@@ -187,7 +215,8 @@ module WEBrick
187
215
  end
188
216
  module_function :parse_qvalues
189
217
 
190
- #####
218
+ ##
219
+ # Removes quotes and escapes from +str+
191
220
 
192
221
  def dequote(str)
193
222
  ret = (/\A"(.*)"\Z/ =~ str) ? $1 : str.dup
@@ -196,20 +225,43 @@ module WEBrick
196
225
  end
197
226
  module_function :dequote
198
227
 
228
+ ##
229
+ # Quotes and escapes quotes in +str+
230
+
199
231
  def quote(str)
200
232
  '"' << str.gsub(/[\\\"]/o, "\\\1") << '"'
201
233
  end
202
234
  module_function :quote
203
235
 
204
- #####
236
+ ##
237
+ # Stores multipart form data. FormData objects are created when
238
+ # WEBrick::HTTPUtils.parse_form_data is called.
205
239
 
206
240
  class FormData < String
207
- EmptyRawHeader = [].freeze
208
- EmptyHeader = {}.freeze
241
+ EmptyRawHeader = [].freeze # :nodoc:
242
+ EmptyHeader = {}.freeze # :nodoc:
243
+
244
+ ##
245
+ # The name of the form data part
246
+
247
+ attr_accessor :name
209
248
 
210
- attr_accessor :name, :filename, :next_data
249
+ ##
250
+ # The filename of the form data part
251
+
252
+ attr_accessor :filename
253
+
254
+ attr_accessor :next_data # :nodoc:
211
255
  protected :next_data
212
256
 
257
+ ##
258
+ # Creates a new FormData object.
259
+ #
260
+ # +args+ is an Array of form data entries. One FormData will be created
261
+ # for each entry.
262
+ #
263
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you
264
+
213
265
  def initialize(*args)
214
266
  @name = @filename = @next_data = nil
215
267
  if args.empty?
@@ -226,6 +278,9 @@ module WEBrick
226
278
  end
227
279
  end
228
280
 
281
+ ##
282
+ # Retrieves the header at the first entry in +key+
283
+
229
284
  def [](*key)
230
285
  begin
231
286
  @header[key[0].downcase].join(", ")
@@ -234,6 +289,12 @@ module WEBrick
234
289
  end
235
290
  end
236
291
 
292
+ ##
293
+ # Adds +str+ to this FormData which may be the body, a header or a
294
+ # header entry.
295
+ #
296
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you
297
+
237
298
  def <<(str)
238
299
  if @header
239
300
  super
@@ -249,6 +310,11 @@ module WEBrick
249
310
  self
250
311
  end
251
312
 
313
+ ##
314
+ # Adds +data+ at the end of the chain of entries
315
+ #
316
+ # This is called by WEBrick::HTTPUtils.parse_form_data for you.
317
+
252
318
  def append_data(data)
253
319
  tmp = self
254
320
  while tmp
@@ -261,6 +327,9 @@ module WEBrick
261
327
  self
262
328
  end
263
329
 
330
+ ##
331
+ # Yields each entry in this FormData
332
+
264
333
  def each_data
265
334
  tmp = self
266
335
  while tmp
@@ -270,6 +339,9 @@ module WEBrick
270
339
  end
271
340
  end
272
341
 
342
+ ##
343
+ # Returns all the FormData as an Array
344
+
273
345
  def list
274
346
  ret = []
275
347
  each_data{|data|
@@ -278,13 +350,22 @@ module WEBrick
278
350
  ret
279
351
  end
280
352
 
353
+ ##
354
+ # A FormData will behave like an Array
355
+
281
356
  alias :to_ary :list
282
357
 
358
+ ##
359
+ # This FormData's body
360
+
283
361
  def to_s
284
362
  String.new(self)
285
363
  end
286
364
  end
287
365
 
366
+ ##
367
+ # Parses the query component of a URI in +str+
368
+
288
369
  def parse_query(str)
289
370
  query = Hash.new
290
371
  if str
@@ -306,6 +387,9 @@ module WEBrick
306
387
  end
307
388
  module_function :parse_query
308
389
 
390
+ ##
391
+ # Parses form data in +io+ with the given +boundary+
392
+
309
393
  def parse_form_data(io, boundary)
310
394
  boundary_regexp = /\A--#{Regexp.quote(boundary)}(--)?#{CRLF}\z/
311
395
  form_data = Hash.new
@@ -350,10 +434,22 @@ module WEBrick
350
434
 
351
435
  module_function
352
436
 
437
+ # :stopdoc:
438
+
353
439
  def _make_regex(str) /([#{Regexp.escape(str)}])/n end
354
440
  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
441
+ def _escape(str, regex)
442
+ str = str.b
443
+ str.gsub!(regex) {"%%%02X" % $1.ord}
444
+ # %-escaped string should contain US-ASCII only
445
+ str.force_encoding(Encoding::US_ASCII)
446
+ end
447
+ def _unescape(str, regex)
448
+ str = str.b
449
+ str.gsub!(regex) {$1.hex.chr}
450
+ # encoding of %-unescaped string is unknown
451
+ str
452
+ end
357
453
 
358
454
  UNESCAPED = _make_regex(control+space+delims+unwise+nonascii)
359
455
  UNESCAPED_FORM = _make_regex(reserved+control+delims+unwise+nonascii)
@@ -361,24 +457,41 @@ module WEBrick
361
457
  ESCAPED = /%([0-9a-fA-F]{2})/
362
458
  UNESCAPED_PCHAR = _make_regex!(unreserved+":@&=+$,")
363
459
 
460
+ # :startdoc:
461
+
462
+ ##
463
+ # Escapes HTTP reserved and unwise characters in +str+
464
+
364
465
  def escape(str)
365
466
  _escape(str, UNESCAPED)
366
467
  end
367
468
 
469
+ ##
470
+ # Unescapes HTTP reserved and unwise characters in +str+
471
+
368
472
  def unescape(str)
369
473
  _unescape(str, ESCAPED)
370
474
  end
371
475
 
476
+ ##
477
+ # Escapes form reserved characters in +str+
478
+
372
479
  def escape_form(str)
373
480
  ret = _escape(str, UNESCAPED_FORM)
374
481
  ret.gsub!(/ /, "+")
375
482
  ret
376
483
  end
377
484
 
485
+ ##
486
+ # Unescapes form reserved characters in +str+
487
+
378
488
  def unescape_form(str)
379
489
  _unescape(str.gsub(/\+/, " "), ESCAPED)
380
490
  end
381
491
 
492
+ ##
493
+ # Escapes path +str+
494
+
382
495
  def escape_path(str)
383
496
  result = ""
384
497
  str.scan(%r{/([^/]*)}).each{|i|
@@ -387,6 +500,9 @@ module WEBrick
387
500
  return result
388
501
  end
389
502
 
503
+ ##
504
+ # Escapes 8 bit characters in +str+
505
+
390
506
  def escape8bit(str)
391
507
  _escape(str, NONASCII)
392
508
  end