mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* lib/net/http/header.rb (Net::HTTPHeader#range): fix broken parser of
HTTP Range request. Old one can't parse invalid specs and multiple specs correctly. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35764 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
b0dd250dc9
commit
3ba0abdb15
3 changed files with 61 additions and 12 deletions
|
@ -1,3 +1,9 @@
|
|||
Wed May 23 22:06:14 2012 NARUSE, Yui <naruse@ruby-lang.org>
|
||||
|
||||
* lib/net/http/header.rb (Net::HTTPHeader#range): fix broken parser of
|
||||
HTTP Range request. Old one can't parse invalid specs and multiple
|
||||
specs correctly.
|
||||
|
||||
Wed May 23 10:18:54 2012 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||
|
||||
* win32/win32.c (finish_overlapped_socket, overlapped_socket_io):
|
||||
|
|
|
@ -177,18 +177,44 @@ module Net::HTTPHeader
|
|||
# HTTP header field, or +nil+ if there is no such header.
|
||||
def range
|
||||
return nil unless @header['range']
|
||||
self['Range'].split(/,/).map {|spec|
|
||||
m = /bytes\s*=\s*(\d+)?\s*-\s*(\d+)?/i.match(spec) or
|
||||
raise HTTPHeaderSyntaxError, "wrong Range: #{spec}"
|
||||
|
||||
value = self['Range']
|
||||
# byte-range-set = *( "," OWS ) ( byte-range-spec / suffix-byte-range-spec )
|
||||
# *( OWS "," [ OWS ( byte-range-spec / suffix-byte-range-spec ) ] )
|
||||
# corrected collected ABNF
|
||||
# http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#section-5.4.1
|
||||
# http://tools.ietf.org/html/draft-ietf-httpbis-p5-range-19#appendix-C
|
||||
# http://tools.ietf.org/html/draft-ietf-httpbis-p1-messaging-19#section-3.2.5
|
||||
unless /\Abytes=((?:,[ \t]*)*(?:\d+-\d*|-\d+)(?:[ \t]*,(?:[ \t]*\d+-\d*|-\d+)?)*)\z/ =~ value
|
||||
raise Net::HTTPHeaderSyntaxError, "invalid syntax for byte-ranges-specifier: '#{value}'"
|
||||
end
|
||||
|
||||
byte_range_set = $1
|
||||
result = byte_range_set.split(/,/).map {|spec|
|
||||
m = /(\d+)?\s*-\s*(\d+)?/i.match(spec) or
|
||||
raise Net::HTTPHeaderSyntaxError, "invalid byte-range-spec: '#{spec}'"
|
||||
d1 = m[1].to_i
|
||||
d2 = m[2].to_i
|
||||
if m[1] and m[2] then d1..d2
|
||||
elsif m[1] then d1..-1
|
||||
elsif m[2] then -d2..-1
|
||||
if m[1] and m[2]
|
||||
if d1 > d2
|
||||
raise Net::HTTPHeaderSyntaxError, "last-byte-pos MUST greater than or equal to first-byte-pos but '#{spec}'"
|
||||
end
|
||||
d1..d2
|
||||
elsif m[1]
|
||||
d1..-1
|
||||
elsif m[2]
|
||||
-d2..-1
|
||||
else
|
||||
raise HTTPHeaderSyntaxError, 'range is not specified'
|
||||
raise Net::HTTPHeaderSyntaxError, 'range is not specified'
|
||||
end
|
||||
}
|
||||
# if result.empty?
|
||||
# byte-range-set must include at least one byte-range-spec or suffix-byte-range-spec
|
||||
# but above regexp already denies it.
|
||||
if result.size == 1 && result[0].begin == 0 && result[0].end == -1
|
||||
raise Net::HTTPHeaderSyntaxError, 'only one suffix-byte-range-spec with zero suffix-length'
|
||||
end
|
||||
result
|
||||
end
|
||||
|
||||
# Sets the HTTP Range: header.
|
||||
|
|
|
@ -156,15 +156,32 @@ class HTTPHeaderTest < Test::Unit::TestCase
|
|||
end
|
||||
|
||||
def test_range
|
||||
try_range(1..5, '1-5')
|
||||
try_range(234..567, '234-567')
|
||||
try_range(-5..-1, '-5')
|
||||
try_range(1..-1, '1-')
|
||||
try_range([1..5], '1-5')
|
||||
try_invalid_range('5-1')
|
||||
try_range([234..567], '234-567')
|
||||
try_range([-5..-1], '-5')
|
||||
try_invalid_range('-0')
|
||||
try_range([1..-1], '1-')
|
||||
try_range([0..0,-1..-1], '0-0,-1')
|
||||
try_range([1..2, 3..4], '1-2,3-4')
|
||||
try_range([1..2, 3..4], '1-2 , 3-4')
|
||||
try_range([1..2, 1..4], '1-2,1-4')
|
||||
|
||||
try_invalid_range('invalid')
|
||||
try_invalid_range(' 12-')
|
||||
try_invalid_range('12- ')
|
||||
try_invalid_range('123-abc')
|
||||
try_invalid_range('abc-123')
|
||||
end
|
||||
|
||||
def try_range(r, s)
|
||||
@c['range'] = "bytes=#{s}"
|
||||
assert_equal r, Array(@c.range)[0]
|
||||
assert_equal r, @c.range
|
||||
end
|
||||
|
||||
def try_invalid_range(s)
|
||||
@c['range'] = "bytes=#{s}"
|
||||
assert_raise(Net::HTTPHeaderSyntaxError, s){ @c.range }
|
||||
end
|
||||
|
||||
def test_range=
|
||||
|
|
Loading…
Reference in a new issue