Class: Yahns::MaxBody::Wrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/yahns/max_body/wrapper.rb

Overview

Copyright © 2013-2016 all contributors <[email protected]> License: GPLv2 or later (www.gnu.org/licenses/gpl-2.0.txt) frozen_string_literal: true

This is only used for chunked request bodies, which are rare

Direct Known Subclasses

RewindableWrapper

Instance Method Summary collapse

Constructor Details

#initialize(rack_input, limit) ⇒ Wrapper

:nodoc:



8
9
10
11
12
# File 'lib/yahns/max_body/wrapper.rb', line 8

def initialize(rack_input, limit)
  @input = rack_input
  @limit = limit
  @rbuf = ''.dup
end

Instance Method Details

#checked_read(length = 16384, buf = ''.dup) ⇒ Object



60
61
62
63
64
65
# File 'lib/yahns/max_body/wrapper.rb', line 60

def checked_read(length = 16384, buf = ''.dup)
  if @input.read(length, buf)
    throw :yahns_EFBIG if ((@limit -= buf.size) < 0)
    return buf
  end
end

#eachObject



14
15
16
17
18
# File 'lib/yahns/max_body/wrapper.rb', line 14

def each
  while line = gets
    yield line
  end
end

#getsObject



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/yahns/max_body/wrapper.rb', line 38

def gets
  sep = $/
  if sep.nil?
    rv = read_all
    return rv.empty? ? nil : rv
  end
  re = /\A(.*?#{Regexp.escape(sep)})/

  begin
    @rbuf.sub!(re, '') and return $1

    if tmp = checked_read(16384)
      @rbuf << tmp
      tmp.clear
    elsif @rbuf.empty? # EOF
      return nil
    else # EOF, return whatever is left
      return @rbuf.slice!(0, @rbuf.size)
    end
  end while true
end

#read(length = nil, rv = ''.dup) ⇒ Object

chunked encoding means this method behaves more like readpartial, since Rack does not support a method named “readpartial”



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/yahns/max_body/wrapper.rb', line 22

def read(length = nil, rv = ''.dup)
  if length
    if length <= @rbuf.size
      length < 0 and raise ArgumentError, "negative length #{length} given"
      rv.replace(@rbuf.slice!(0, length))
    elsif @rbuf.empty?
      checked_read(length, rv) or return
    else
      rv.replace(@rbuf.slice!(0, @rbuf.size))
    end
    rv.empty? && length != 0 ? nil : rv
  else
    rv.replace(read_all)
  end
end

#read_allObject



67
68
69
70
71
72
73
74
75
# File 'lib/yahns/max_body/wrapper.rb', line 67

def read_all
  rv = @rbuf.slice!(0, @rbuf.size)
  tmp = ''.dup
  while checked_read(16384, tmp)
    rv << tmp
  end
  tmp.clear
  rv
end