1 # -*- encoding: binary -*-
4 # This is only used for chunked request bodies, which are rare
5 class Rainbows::MaxBody::Wrapper
6 def initialize(rack_input, limit)
7 @input, @limit, @rbuf = rack_input, limit, ''
16 # chunked encoding means this method behaves more like readpartial,
17 # since Rack does not support a method named "readpartial"
18 def read(length = nil, rv = '')
20 if length <= @rbuf.size
21 length < 0 and raise ArgumentError, "negative length #{length} given"
22 rv.replace(@rbuf.slice!(0, length))
24 checked_read(length, rv) or return
26 rv.replace(@rbuf.slice!(0, @rbuf.size))
28 rv.empty? && length != 0 ? nil : rv
38 return rv.empty? ? nil : rv
40 re = /\A(.*?#{Regexp.escape(sep)})/
43 @rbuf.sub!(re, '') and return $1
45 if tmp = checked_read(16384)
47 elsif @rbuf.empty? # EOF
49 else # EOF, return whatever is left
50 return @rbuf.slice!(0, @rbuf.size)
55 def checked_read(length = 16384, buf = '')
56 if @input.read(length, buf)
57 throw :rainbows_EFBIG if ((@limit -= buf.size) < 0)
63 rv = @rbuf.slice!(0, @rbuf.size)
65 while checked_read(16384, tmp)