webrick 1.8.0 → 1.8.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 32a11a2138bc27a617a7f69e300868cc4957cd208e5358d17aa5d3135c645c1c
4
- data.tar.gz: 3be4ec01ad7ae153f32db3ab01133c7f7e308e7f6bf984aed5eb08a0646622bb
3
+ metadata.gz: 963bdfcf1a0e919027a92007be283a146cd054be3a60e539e9f3cbce5c0a908f
4
+ data.tar.gz: 2ed0bd918c3c5dbb908a59350c9e3691afe88c63a4a5c0a2b5085de7c30aeab5
5
5
  SHA512:
6
- metadata.gz: d2eef98cfcc5a16f9da6b99e057ddbe5bb3bb00db407c259fc424092cdcefa94e3cec9dd82f71ab06fe9c423658ec0a4eb33a051f6bf9e3c034da19dc272449f
7
- data.tar.gz: a0c44a9d8ca6e34666dd783941b908e7c7e496593f93b3f867cec75005b6727c3c7b276ee155e8eb2a886d2b90e47dbdf2ba42f97a1287addd34a76024502896
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
@@ -122,7 +122,7 @@ module WEBrick
122
122
  @status = HTTPStatus::RC_OK
123
123
  @reason_phrase = nil
124
124
  @http_version = HTTPVersion::convert(@config[:HTTPVersion])
125
- @body = ''
125
+ @body = +""
126
126
  @keep_alive = true
127
127
  @cookies = []
128
128
  @request_method = nil
@@ -441,7 +441,7 @@ module WEBrick
441
441
  # :stopdoc:
442
442
 
443
443
  def error_body(backtrace, ex, host, port)
444
- @body = +''
444
+ @body = +""
445
445
  @body << <<-_end_of_html_
446
446
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
447
447
  <HTML>
@@ -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.0"
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.0
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: []