Skip to content

Commit 426e214

Browse files
committed
Only strip space and horizontal tab in headers
Previously, all whitespace was stripped, but that goes against the related RFCs. Fixes #139
1 parent e72cb69 commit 426e214

File tree

2 files changed

+32
-8
lines changed

2 files changed

+32
-8
lines changed

lib/webrick/httputils.rb

+11-8
Original file line numberDiff line numberDiff line change
@@ -178,20 +178,23 @@ def parse_header(raw)
178178
field.downcase!
179179
header[field] = HEADER_CLASSES[field].new unless header.has_key?(field)
180180
header[field] << value
181-
when /^\s+([^\r\n\0]*?)\r\n/om
181+
when /^[ \t]+([^\r\n\0]*?)\r\n/om
182182
unless field
183183
raise HTTPStatus::BadRequest, "bad header '#{line}'."
184184
end
185185
value = line
186-
value.lstrip!
186+
value.gsub!(/\A[ \t]+/, '')
187187
value.slice!(-2..-1)
188188
header[field][-1] << " " << value
189189
else
190190
raise HTTPStatus::BadRequest, "bad header '#{line}'."
191191
end
192192
}
193193
header.each{|key, values|
194-
values.each(&:strip!)
194+
values.each{|value|
195+
value.gsub!(/\A[ \t]+/, '')
196+
value.gsub!(/[ \t]+\z/, '')
197+
}
195198
}
196199
header
197200
end
@@ -202,7 +205,7 @@ def parse_header(raw)
202205

203206
def split_header_value(str)
204207
str.scan(%r'\G((?:"(?:\\.|[^"])+?"|[^",]++)+)
205-
(?:,\s*|\Z)'xn).flatten
208+
(?:,[ \t]*|\Z)'xn).flatten
206209
end
207210
module_function :split_header_value
208211

@@ -230,9 +233,9 @@ def parse_range_header(ranges_specifier)
230233
def parse_qvalues(value)
231234
tmp = []
232235
if value
233-
parts = value.split(/,\s*/)
236+
parts = value.split(/,[ \t]*/)
234237
parts.each {|part|
235-
if m = %r{^([^\s,]+?)(?:;\s*q=(\d+(?:\.\d+)?))?$}.match(part)
238+
if m = %r{^([^ \t,]+?)(?:;[ \t]*q=(\d+(?:\.\d+)?))?$}.match(part)
236239
val = m[1]
237240
q = (m[2] or 1).to_f
238241
tmp.push([val, q])
@@ -331,8 +334,8 @@ def <<(str)
331334
elsif str == CRLF
332335
@header = HTTPUtils::parse_header(@raw_header.join)
333336
if cd = self['content-disposition']
334-
if /\s+name="(.*?)"/ =~ cd then @name = $1 end
335-
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
336339
end
337340
else
338341
@raw_header << str

test/webrick/test_httprequest.rb

+21
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,27 @@ def test_bare_lf_header
118118
}
119119
end
120120

121+
def test_header_vt_ff_whitespace
122+
msg = <<~HTTP
123+
GET / HTTP/1.1\r
124+
Foo: \x0b1\x0c\r
125+
\r
126+
HTTP
127+
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
128+
req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
129+
assert_equal("\x0b1\x0c", req["Foo"])
130+
131+
msg = <<~HTTP
132+
GET / HTTP/1.1\r
133+
Foo: \x0b1\x0c\r
134+
\x0b2\x0c\r
135+
\r
136+
HTTP
137+
req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
138+
req.parse(StringIO.new(msg.gsub(/^ {6}/, "")))
139+
assert_equal("\x0b1\x0c \x0b2\x0c", req["Foo"])
140+
end
141+
121142
def test_bare_cr_request_line
122143
msg = <<~HTTP.gsub("\n", "\r\n")
123144
GET / HTTP/1.1\r\r

0 commit comments

Comments
 (0)