Skip to content

Commit

Permalink
Only strip space and horizontal tab in headers
Browse files Browse the repository at this point in the history
Previously, all whitespace was stripped, but that goes against
the related RFCs.

Fixes #139
  • Loading branch information
jeremyevans committed Jul 11, 2024
1 parent e72cb69 commit 426e214
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 8 deletions.
19 changes: 11 additions & 8 deletions lib/webrick/httputils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -178,20 +178,23 @@ def parse_header(raw)
field.downcase!
header[field] = HEADER_CLASSES[field].new unless header.has_key?(field)
header[field] << value
when /^\s+([^\r\n\0]*?)\r\n/om
when /^[ \t]+([^\r\n\0]*?)\r\n/om
unless field
raise HTTPStatus::BadRequest, "bad header '#{line}'."
end
value = line
value.lstrip!
value.gsub!(/\A[ \t]+/, '')
value.slice!(-2..-1)
header[field][-1] << " " << value
else
raise HTTPStatus::BadRequest, "bad header '#{line}'."
end
}
header.each{|key, values|
values.each(&:strip!)
values.each{|value|
value.gsub!(/\A[ \t]+/, '')
value.gsub!(/[ \t]+\z/, '')
}
}
header
end
Expand All @@ -202,7 +205,7 @@ def parse_header(raw)

def split_header_value(str)
str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]++)+)
(?:,\s*|\Z)'xn).flatten
(?:,[ \t]*|\Z)'xn).flatten
end
module_function :split_header_value

Expand Down Expand Up @@ -230,9 +233,9 @@ def parse_range_header(ranges_specifier)
def parse_qvalues(value)
tmp = []
if value
parts = value.split(/,\s*/)
parts = value.split(/,[ \t]*/)
parts.each {|part|
if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
if m = %r{^([^ \t,]+?)(?:;[ \t]*q=(\d+(?:\.\d+)?))?$}.match(part)
val = m[1]
q = (m[2] or 1).to_f
tmp.push([val, q])
Expand Down Expand Up @@ -331,8 +334,8 @@ def <<(str)
elsif str == CRLF
@header = HTTPUtils::parse_header(@raw_header.join)
if cd = self['content-disposition']
if /\s+name="(.*?)"/ =~ cd then @name = $1 end
if /\s+filename="(.*?)"/ =~ cd then @filename = $1 end
if /[ \t]+name="(.*?)"/ =~ cd then @name = $1 end
if /[ \t]+filename="(.*?)"/ =~ cd then @filename = $1 end
end
else
@raw_header << str
Expand Down
21 changes: 21 additions & 0 deletions test/webrick/test_httprequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,27 @@ def test_bare_lf_header
}
end

def test_header_vt_ff_whitespace
msg = <<~HTTP
GET / HTTP/1.1\r
Foo: \x0b1\x0c\r
\r
HTTP
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
assert_equal("\x0b1\x0c", req["Foo"])

msg = <<~HTTP
GET / HTTP/1.1\r
Foo: \x0b1\x0c\r
\x0b2\x0c\r
\r
HTTP
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
assert_equal("\x0b1\x0c \x0b2\x0c", req["Foo"])
end

def test_bare_cr_request_line
msg = <<~HTTP.gsub("\n", "\r\n")
GET / HTTP/1.1\r\r
Expand Down

0 comments on commit 426e214

Please sign in to comment.