webrick 1.8.1 → 1.8.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a401983074ecea6a30f8227ed888b735b3cdceadde14a7030b391cc45f948c2c
4
- data.tar.gz: d40f18576cb9c335439796b1cdd92c7faf515ef944deb53c517fdf8c8390a79a
3
+ metadata.gz: 963bdfcf1a0e919027a92007be283a146cd054be3a60e539e9f3cbce5c0a908f
4
+ data.tar.gz: 2ed0bd918c3c5dbb908a59350c9e3691afe88c63a4a5c0a2b5085de7c30aeab5
5
5
  SHA512:
6
- metadata.gz: 1e5edb6d6798b75aafd9d16787f910e7a4beaf5cb7762af1c9f5add5725b037547bd875e9df8bc1f9ca18bcd3fa5839d25a566891f64cd55b9f145e8735e02b2
7
- data.tar.gz: 7d3ffd0d2db521ca3ee6cdb3d8a7e448037d9694ceae62737b71d887e8089902ee71a2b334970dabad2767085b771c315a968993f6df83429f8f957d40ae72a8
6
+ metadata.gz: 2433fb9da7e7e7f10495059ac90de49238758fc0581fb8d0dfed28f08d47c9b21329fc4a03a7ade064cea71097f86e29a74003ca6369d3d9e58c401979871a0e
7
+ data.tar.gz: b0bd6929f6d49967215825cce3c7ad5c7e6b1b45fcda8fd97c898f377df2453934d62ff0cc0a941b2d4a374487b901a207674f76229d45a899938d40516c9271
data/Gemfile CHANGED
@@ -4,3 +4,4 @@ gemspec
4
4
 
5
5
  gem "rake"
6
6
  gem "test-unit"
7
+ gem "test-unit-ruby-core"
data/Rakefile CHANGED
@@ -7,11 +7,4 @@ Rake::TestTask.new(:test) do |t|
7
7
  t.test_files = FileList["test/**/test_*.rb"]
8
8
  end
9
9
 
10
- task :sync_tool do
11
- require 'fileutils'
12
- FileUtils.cp "../ruby/tool/lib/core_assertions.rb", "./test/lib"
13
- FileUtils.cp "../ruby/tool/lib/envutil.rb", "./test/lib"
14
- FileUtils.cp "../ruby/tool/lib/find_executable.rb", "./test/lib"
15
- end
16
-
17
10
  task :default => :test
@@ -318,7 +318,7 @@ module WEBrick
318
318
  def [](header_name)
319
319
  if @header
320
320
  value = @header[header_name.downcase]
321
- value.empty? ? nil : value.join(", ")
321
+ value.empty? ? nil : value.join
322
322
  end
323
323
  end
324
324
 
@@ -329,7 +329,7 @@ module WEBrick
329
329
  if @header
330
330
  @header.each{|k, v|
331
331
  value = @header[k]
332
- yield(k, value.empty? ? nil : value.join(", "))
332
+ yield(k, value.empty? ? nil : value.join)
333
333
  }
334
334
  end
335
335
  end
@@ -402,7 +402,7 @@ module WEBrick
402
402
  # This method provides the metavariables defined by the revision 3
403
403
  # of "The WWW Common Gateway Interface Version 1.1"
404
404
  # To browse the current document of CGI Version 1.1, see below:
405
- # http://tools.ietf.org/html/rfc3875
405
+ # https://www.rfc-editor.org/rfc/rfc3875
406
406
 
407
407
  def meta_vars
408
408
  meta = Hash.new
@@ -458,7 +458,7 @@ module WEBrick
458
458
  end
459
459
 
460
460
  @request_time = Time.now
461
- if /^(\S+)\s+(\S++)(?:\s+HTTP\/(\d+\.\d+))?\r?\n/mo =~ @request_line
461
+ if /^(\S+) (\S++)(?: HTTP\/(\d+\.\d+))?\r\n/mo =~ @request_line
462
462
  @request_method = $1
463
463
  @unparsed_uri = $2
464
464
  @http_version = HTTPVersion.new($3 ? $3 : "0.9")
@@ -470,15 +470,34 @@ module WEBrick
470
470
 
471
471
  def read_header(socket)
472
472
  if socket
473
+ end_of_headers = false
474
+
473
475
  while line = read_line(socket)
474
- break if /\A(#{CRLF}|#{LF})\z/om =~ line
476
+ if line == CRLF
477
+ end_of_headers = true
478
+ break
479
+ end
475
480
  if (@request_bytes += line.bytesize) > MAX_HEADER_LENGTH
476
481
  raise HTTPStatus::RequestEntityTooLarge, 'headers too large'
477
482
  end
483
+ if line.include?("\x00")
484
+ raise HTTPStatus::BadRequest, 'null byte in header'
485
+ end
478
486
  @raw_header << line
479
487
  end
488
+
489
+ # Allow if @header already set to support chunked trailers
490
+ raise HTTPStatus::EOFError unless end_of_headers || @header
480
491
  end
481
492
  @header = HTTPUtils::parse_header(@raw_header.join)
493
+
494
+ if (content_length = @header['content-length']) && content_length.length != 0
495
+ if content_length.length > 1
496
+ raise HTTPStatus::BadRequest, "multiple content-length request headers"
497
+ elsif !/\A\d+\z/.match?(content_length[0])
498
+ raise HTTPStatus::BadRequest, "invalid content-length request header"
499
+ end
500
+ end
482
501
  end
483
502
 
484
503
  def parse_uri(str, scheme="http")
@@ -503,14 +522,19 @@ module WEBrick
503
522
  return URI::parse(uri.to_s)
504
523
  end
505
524
 
525
+ host_pattern = URI::RFC2396_Parser.new.pattern.fetch(:HOST)
526
+ HOST_PATTERN = /\A(#{host_pattern})(?::(\d+))?\z/n
506
527
  def parse_host_request_line(host)
507
- pattern = /\A(#{URI::REGEXP::PATTERN::HOST})(?::(\d+))?\z/no
508
- host.scan(pattern)[0]
528
+ host.scan(HOST_PATTERN)[0]
509
529
  end
510
530
 
511
531
  def read_body(socket, block)
512
532
  return unless socket
513
533
  if tc = self['transfer-encoding']
534
+ if self['content-length']
535
+ raise HTTPStatus::BadRequest, "request with both transfer-encoding and content-length, possible request smuggling"
536
+ end
537
+
514
538
  case tc
515
539
  when /\Achunked\z/io then read_chunked(socket, block)
516
540
  else raise HTTPStatus::NotImplemented, "Transfer-Encoding: #{tc}."
@@ -534,7 +558,7 @@ module WEBrick
534
558
 
535
559
  def read_chunk_size(socket)
536
560
  line = read_line(socket)
537
- if /^([0-9a-fA-F]+)(?:;(\S+))?/ =~ line
561
+ if /\A([0-9a-fA-F]+)(?:;(\S+(?:=\S+)?))?\r\n\z/ =~ line
538
562
  chunk_size = $1.hex
539
563
  chunk_ext = $2
540
564
  [ chunk_size, chunk_ext ]
@@ -555,7 +579,11 @@ module WEBrick
555
579
  block.call(data)
556
580
  end while (chunk_size -= sz) > 0
557
581
 
558
- read_line(socket) # skip CRLF
582
+ line = read_line(socket) # skip CRLF
583
+ unless line == "\r\n"
584
+ raise HTTPStatus::BadRequest, "extra data after chunk `#{line}'."
585
+ end
586
+
559
587
  chunk_size, = read_chunk_size(socket)
560
588
  end
561
589
  read_header(socket) # trailer + CRLF
@@ -55,7 +55,6 @@ module WEBrick
55
55
  "cer" => "application/pkix-cert",
56
56
  "crl" => "application/pkix-crl",
57
57
  "crt" => "application/x-x509-ca-cert",
58
- #"crl" => "application/x-pkcs7-crl",
59
58
  "css" => "text/css",
60
59
  "dms" => "application/octet-stream",
61
60
  "doc" => "application/msword",
@@ -153,28 +152,49 @@ module WEBrick
153
152
  # Parses an HTTP header +raw+ into a hash of header fields with an Array
154
153
  # of values.
155
154
 
155
+ class SplitHeader < Array
156
+ def join(separator = ", ")
157
+ super
158
+ end
159
+ end
160
+
161
+ class CookieHeader < Array
162
+ def join(separator = "; ")
163
+ super
164
+ end
165
+ end
166
+
167
+ HEADER_CLASSES = Hash.new(SplitHeader).update({
168
+ "cookie" => CookieHeader,
169
+ })
170
+
156
171
  def parse_header(raw)
157
172
  header = Hash.new([].freeze)
158
173
  field = nil
159
174
  raw.each_line{|line|
160
175
  case line
161
- when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):\s*(.*?)\s*\z/om
176
+ when /^([A-Za-z0-9!\#$%&'*+\-.^_`|~]+):([^\r\n\0]*?)\r\n\z/om
162
177
  field, value = $1, $2
163
178
  field.downcase!
164
- header[field] = [] unless header.has_key?(field)
179
+ header[field] = HEADER_CLASSES[field].new unless header.has_key?(field)
165
180
  header[field] << value
166
- when /^\s+(.*?)\s*\z/om
167
- value = $1
181
+ when /^[ \t]+([^\r\n\0]*?)\r\n/om
168
182
  unless field
169
183
  raise HTTPStatus::BadRequest, "bad header '#{line}'."
170
184
  end
185
+ value = line
186
+ value.gsub!(/\A[ \t]+/, '')
187
+ value.slice!(-2..-1)
171
188
  header[field][-1] << " " << value
172
189
  else
173
190
  raise HTTPStatus::BadRequest, "bad header '#{line}'."
174
191
  end
175
192
  }
176
193
  header.each{|key, values|
177
- values.each(&:strip!)
194
+ values.each{|value|
195
+ value.gsub!(/\A[ \t]+/, '')
196
+ value.gsub!(/[ \t]+\z/, '')
197
+ }
178
198
  }
179
199
  header
180
200
  end
@@ -184,8 +204,8 @@ module WEBrick
184
204
  # Splits a header value +str+ according to HTTP specification.
185
205
 
186
206
  def split_header_value(str)
187
- str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]+)+)
188
- (?:,\s*|\Z)'xn).flatten
207
+ str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]++)+)
208
+ (?:,[ \t]*|\Z)'xn).flatten
189
209
  end
190
210
  module_function :split_header_value
191
211
 
@@ -213,9 +233,9 @@ module WEBrick
213
233
  def parse_qvalues(value)
214
234
  tmp = []
215
235
  if value
216
- parts = value.split(/,\s*/)
236
+ parts = value.split(/,[ \t]*/)
217
237
  parts.each {|part|
218
- if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
238
+ if m = %r{^([^ \t,]+?)(?:;[ \t]*q=(\d+(?:\.\d+)?))?$}.match(part)
219
239
  val = m[1]
220
240
  q = (m[2] or 1).to_f
221
241
  tmp.push([val, q])
@@ -314,8 +334,8 @@ module WEBrick
314
334
  elsif str == CRLF
315
335
  @header = HTTPUtils::parse_header(@raw_header.join)
316
336
  if cd = self['content-disposition']
317
- if /\s+name="(.*?)"/ =~ cd then @name = $1 end
318
- if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
337
+ if /[ \t]+name="(.*?)"/ =~ cd then @name = $1 end
338
+ if /[ \t]+filename="(.*?)"/ =~ cd then @filename = $1 end
319
339
  end
320
340
  else
321
341
  @raw_header << str
@@ -14,5 +14,5 @@ module WEBrick
14
14
  ##
15
15
  # The WEBrick version
16
16
 
17
- VERSION = "1.8.1"
17
+ VERSION = "1.8.2"
18
18
  end
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webrick
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - TAKAHASHI Masayoshi
8
8
  - GOTOU YUUZOU
9
9
  - Eric Wong
10
- autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2023-01-27 00:00:00.000000000 Z
12
+ date: 2024-09-24 00:00:00.000000000 Z
14
13
  dependencies: []
15
14
  description: WEBrick is an HTTP server toolkit that can be configured as an HTTPS
16
15
  server, a proxy server, and a virtual-host server.
@@ -68,7 +67,6 @@ licenses:
68
67
  - BSD-2-Clause
69
68
  metadata:
70
69
  bug_tracker_uri: https://github.com/ruby/webrick/issues
71
- post_install_message:
72
70
  rdoc_options: []
73
71
  require_paths:
74
72
  - lib
@@ -83,8 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
81
  - !ruby/object:Gem::Version
84
82
  version: '0'
85
83
  requirements: []
86
- rubygems_version: 3.5.0.dev
87
- signing_key:
84
+ rubygems_version: 3.6.0.dev
88
85
  specification_version: 4
89
86
  summary: HTTP server toolkit
90
87
  test_files: []