webrick 1.3.1 → 1.5.0

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 (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,3 +1,4 @@
1
+ # frozen_string_literal: false
1
2
  #
2
3
  # httprequest.rb -- HTTPRequest Class
3
4
  #
@@ -9,39 +10,145 @@
9
10
  # $IPR: httprequest.rb,v 1.64 2003/07/13 17:18:22 gotoyuzo Exp $
10
11
 
11
12
  require 'uri'
12
- require 'webrick/httpversion'
13
- require 'webrick/httpstatus'
14
- require 'webrick/httputils'
15
- require 'webrick/cookie'
13
+ require_relative 'httpversion'
14
+ require_relative 'httpstatus'
15
+ require_relative 'httputils'
16
+ require_relative 'cookie'
16
17
 
17
18
  module WEBrick
18
19
 
19
20
  ##
20
- # An HTTP request.
21
+ # An HTTP request. This is consumed by service and do_* methods in
22
+ # WEBrick servlets
23
+
21
24
  class HTTPRequest
22
25
 
23
- BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ]
26
+ BODY_CONTAINABLE_METHODS = [ "POST", "PUT" ] # :nodoc:
24
27
 
25
28
  # :section: Request line
29
+
30
+ ##
31
+ # The complete request line such as:
32
+ #
33
+ # GET / HTTP/1.1
34
+
26
35
  attr_reader :request_line
27
- attr_reader :request_method, :unparsed_uri, :http_version
36
+
37
+ ##
38
+ # The request method, GET, POST, PUT, etc.
39
+
40
+ attr_reader :request_method
41
+
42
+ ##
43
+ # The unparsed URI of the request
44
+
45
+ attr_reader :unparsed_uri
46
+
47
+ ##
48
+ # The HTTP version of the request
49
+
50
+ attr_reader :http_version
28
51
 
29
52
  # :section: Request-URI
30
- attr_reader :request_uri, :path
31
- attr_accessor :script_name, :path_info, :query_string
53
+
54
+ ##
55
+ # The parsed URI of the request
56
+
57
+ attr_reader :request_uri
58
+
59
+ ##
60
+ # The request path
61
+
62
+ attr_reader :path
63
+
64
+ ##
65
+ # The script name (CGI variable)
66
+
67
+ attr_accessor :script_name
68
+
69
+ ##
70
+ # The path info (CGI variable)
71
+
72
+ attr_accessor :path_info
73
+
74
+ ##
75
+ # The query from the URI of the request
76
+
77
+ attr_accessor :query_string
32
78
 
33
79
  # :section: Header and entity body
34
- attr_reader :raw_header, :header, :cookies
35
- attr_reader :accept, :accept_charset
36
- attr_reader :accept_encoding, :accept_language
80
+
81
+ ##
82
+ # The raw header of the request
83
+
84
+ attr_reader :raw_header
85
+
86
+ ##
87
+ # The parsed header of the request
88
+
89
+ attr_reader :header
90
+
91
+ ##
92
+ # The parsed request cookies
93
+
94
+ attr_reader :cookies
95
+
96
+ ##
97
+ # The Accept header value
98
+
99
+ attr_reader :accept
100
+
101
+ ##
102
+ # The Accept-Charset header value
103
+
104
+ attr_reader :accept_charset
105
+
106
+ ##
107
+ # The Accept-Encoding header value
108
+
109
+ attr_reader :accept_encoding
110
+
111
+ ##
112
+ # The Accept-Language header value
113
+
114
+ attr_reader :accept_language
37
115
 
38
116
  # :section:
117
+
118
+ ##
119
+ # The remote user (CGI variable)
120
+
39
121
  attr_accessor :user
40
- attr_reader :addr, :peeraddr
122
+
123
+ ##
124
+ # The socket address of the server
125
+
126
+ attr_reader :addr
127
+
128
+ ##
129
+ # The socket address of the client
130
+
131
+ attr_reader :peeraddr
132
+
133
+ ##
134
+ # Hash of request attributes
135
+
41
136
  attr_reader :attributes
137
+
138
+ ##
139
+ # Is this a keep-alive connection?
140
+
42
141
  attr_reader :keep_alive
142
+
143
+ ##
144
+ # The local time this request was received
145
+
43
146
  attr_reader :request_time
44
147
 
148
+ ##
149
+ # Creates a new HTTP request. WEBrick::Config::HTTP is the default
150
+ # configuration.
151
+
45
152
  def initialize(config)
46
153
  @config = config
47
154
  @buffer_size = @config[:InputBufferSize]
@@ -78,6 +185,10 @@ module WEBrick
78
185
  @forwarded_server = @forwarded_for = nil
79
186
  end
80
187
 
188
+ ##
189
+ # Parses a request from +socket+. This is called internally by
190
+ # WEBrick::HTTPServer.
191
+
81
192
  def parse(socket=nil)
82
193
  @socket = socket
83
194
  begin
@@ -126,21 +237,52 @@ module WEBrick
126
237
  end
127
238
  end
128
239
 
240
+ ##
129
241
  # Generate HTTP/1.1 100 continue response if the client expects it,
130
242
  # otherwise does nothing.
131
- def continue
243
+
244
+ def continue # :nodoc:
132
245
  if self['expect'] == '100-continue' && @config[:HTTPVersion] >= "1.1"
133
246
  @socket << "HTTP/#{@config[:HTTPVersion]} 100 continue#{CRLF}#{CRLF}"
134
247
  @header.delete('expect')
135
248
  end
136
249
  end
137
250
 
138
- def body(&block)
251
+ ##
252
+ # Returns the request body.
253
+
254
+ def body(&block) # :yields: body_chunk
139
255
  block ||= Proc.new{|chunk| @body << chunk }
140
256
  read_body(@socket, block)
141
257
  @body.empty? ? nil : @body
142
258
  end
143
259
 
260
+ ##
261
+ # Prepares the HTTPRequest object for use as the
262
+ # source for IO.copy_stream
263
+
264
+ def body_reader
265
+ @body_tmp = []
266
+ @body_rd = Fiber.new do
267
+ body do |buf|
268
+ @body_tmp << buf
269
+ Fiber.yield
270
+ end
271
+ end
272
+ @body_rd.resume # grab the first chunk and yield
273
+ self
274
+ end
275
+
276
+ # for IO.copy_stream. Note: we may return a larger string than +size+
277
+ # here; but IO.copy_stream does not care.
278
+ def readpartial(size, buf = ''.b) # :nodoc
279
+ res = @body_tmp.shift or raise EOFError, 'end of file reached'
280
+ buf.replace(res)
281
+ res.clear
282
+ @body_rd.resume # get more chunks
283
+ buf
284
+ end
285
+
144
286
  ##
145
287
  # Request query as a Hash
146
288
 
@@ -237,11 +379,14 @@ module WEBrick
237
379
  ret
238
380
  end
239
381
 
240
- def fixup()
382
+ ##
383
+ # Consumes any remaining body and updates keep-alive status
384
+
385
+ def fixup() # :nodoc:
241
386
  begin
242
387
  body{|chunk| } # read remaining body
243
388
  rescue HTTPStatus::Error => ex
244
- @logger.error("HTTPRequest#fixup: #{ex.class} occured.")
389
+ @logger.error("HTTPRequest#fixup: #{ex.class} occurred.")
245
390
  @keep_alive = false
246
391
  rescue => ex
247
392
  @logger.error(ex)
@@ -251,7 +396,8 @@ module WEBrick
251
396
 
252
397
  # This method provides the metavariables defined by the revision 3
253
398
  # of "The WWW Common Gateway Interface Version 1.1"
254
- # http://Web.Golux.Com/coar/cgi/
399
+ # To browse the current document of CGI Version 1.1, see below:
400
+ # http://tools.ietf.org/html/rfc3875
255
401
 
256
402
  def meta_vars
257
403
  meta = Hash.new
@@ -290,15 +436,23 @@ module WEBrick
290
436
 
291
437
  private
292
438
 
439
+ # :stopdoc:
440
+
293
441
  MAX_URI_LENGTH = 2083 # :nodoc:
294
442
 
443
+ # same as Mongrel, Thin and Puma
444
+ MAX_HEADER_LENGTH = (112 * 1024) # :nodoc:
445
+
295
446
  def read_request_line(socket)
296
447
  @request_line = read_line(socket, MAX_URI_LENGTH) if socket
297
- if @request_line.bytesize >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
448
+ raise HTTPStatus::EOFError unless @request_line
449
+
450
+ @request_bytes = @request_line.bytesize
451
+ if @request_bytes >= MAX_URI_LENGTH and @request_line[-1, 1] != LF
298
452
  raise HTTPStatus::RequestURITooLarge
299
453
  end
454
+
300
455
  @request_time = Time.now
301
- raise HTTPStatus::EOFError unless @request_line
302
456
  if /^(\S+)\s+(\S++)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
303
457
  @request_method = $1
304
458
  @unparsed_uri = $2
@@ -313,6 +467,9 @@ module WEBrick
313
467
  if socket
314
468
  while line = read_line(socket)
315
469
  break if /\A(#{CRLF}|#{LF})\z/om =~ line
470
+ if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH
471
+ raise HTTPStatus::RequestEntityTooLarge, 'headers too large'
472
+ end
316
473
  @raw_header << line
317
474
  end
318
475
  end
@@ -380,12 +537,16 @@ module WEBrick
380
537
  def read_chunked(socket, block)
381
538
  chunk_size, = read_chunk_size(socket)
382
539
  while chunk_size > 0
383
- data = read_data(socket, chunk_size) # read chunk-data
384
- if data.nil? || data.bytesize != chunk_size
385
- raise BadRequest, "bad chunk data size."
386
- end
540
+ begin
541
+ sz = [ chunk_size, @buffer_size ].min
542
+ data = read_data(socket, sz) # read chunk-data
543
+ if data.nil? || data.bytesize != sz
544
+ raise HTTPStatus::BadRequest, "bad chunk data size."
545
+ end
546
+ block.call(data)
547
+ end while (chunk_size -= sz) > 0
548
+
387
549
  read_line(socket) # skip CRLF
388
- block.call(data)
389
550
  chunk_size, = read_chunk_size(socket)
390
551
  end
391
552
  read_header(socket) # trailer + CRLF
@@ -400,7 +561,7 @@ module WEBrick
400
561
  }
401
562
  rescue Errno::ECONNRESET
402
563
  return nil
403
- rescue TimeoutError
564
+ rescue Timeout::Error
404
565
  raise HTTPStatus::RequestTimeout
405
566
  end
406
567
  end
@@ -445,7 +606,9 @@ module WEBrick
445
606
  if @forwarded_server = self["x-forwarded-server"]
446
607
  @forwarded_server = @forwarded_server.split(",", 2).first
447
608
  end
448
- @forwarded_proto = self["x-forwarded-proto"]
609
+ if @forwarded_proto = self["x-forwarded-proto"]
610
+ @forwarded_proto = @forwarded_proto.split(",", 2).first
611
+ end
449
612
  if host_port = self["x-forwarded-host"]
450
613
  host_port = host_port.split(",", 2).first
451
614
  @forwarded_host, tmp = host_port.split(":", 2)
@@ -457,5 +620,7 @@ module WEBrick
457
620
  @forwarded_for = addrs.first
458
621
  end
459
622
  end
623
+
624
+ # :startdoc:
460
625
  end
461
626
  end