Class: Goliath::RackProxy::RackInput
- Inherits:
-
Object
- Object
- Goliath::RackProxy::RackInput
- Defined in:
- lib/goliath/rack_proxy.rb
Overview
IO-like object that conforms to the Rack specification for the request body (“rack input”). It takes a block which produces chunks of data, and makes this data retrievable through the IO#read interface. When rewindable caches the retrieved content onto disk.
Instance Method Summary collapse
-
#close ⇒ Object
Deletes the tempfile.
-
#initialize(rewindable: true, &next_chunk) ⇒ RackInput
constructor
A new instance of RackInput.
-
#read(length = nil, outbuf = nil) ⇒ Object
Retrieves data using the IO#read semantics.
-
#rewind ⇒ Object
Rewinds the tempfile if rewindable.
Constructor Details
#initialize(rewindable: true, &next_chunk) ⇒ RackInput
Returns a new instance of RackInput.
112 113 114 115 116 117 |
# File 'lib/goliath/rack_proxy.rb', line 112 def initialize(rewindable: true, &next_chunk) @next_chunk = next_chunk @cache = Tempfile.new("goliath-rack_input", binmode: true) if rewindable @buffer = nil @eof = false end |
Instance Method Details
#close ⇒ Object
Deletes the tempfile. The #close method is also part of the Rack specification.
168 169 170 |
# File 'lib/goliath/rack_proxy.rb', line 168 def close @cache.close! if @cache end |
#read(length = nil, outbuf = nil) ⇒ Object
Retrieves data using the IO#read semantics. If rack input is declared rewindable, writes retrieved content into a Tempfile object so that it can later be re-read.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/goliath/rack_proxy.rb', line 122 def read(length = nil, outbuf = nil) data = outbuf.clear if outbuf data = @cache.read(length, outbuf) if @cache && !@cache.eof? loop do remaining_length = length - data.bytesize if data && length break if remaining_length == 0 @buffer = next_chunk or break if @buffer.nil? buffered_data = if remaining_length && remaining_length < @buffer.bytesize @buffer.byteslice(0, remaining_length) else @buffer end if data data << buffered_data else data = buffered_data end @cache.write(buffered_data) if @cache if buffered_data.bytesize < @buffer.bytesize @buffer = @buffer.byteslice(buffered_data.bytesize..-1) else @buffer = nil end buffered_data.clear unless data.equal?(buffered_data) end data.to_s unless length && (data.nil? || data.empty?) end |
#rewind ⇒ Object
Rewinds the tempfile if rewindable. Otherwise raises Errno::ESPIPE exception, which is what other non-rewindable Ruby IO objects raise.
161 162 163 164 |
# File 'lib/goliath/rack_proxy.rb', line 161 def rewind raise Errno::ESPIPE if @cache.nil? @cache.rewind end |