class Goliath::RackProxy::RackInput
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.
Public Class Methods
new(rewindable: true, &next_chunk)
click to toggle source
# 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
Public Instance Methods
close()
click to toggle source
Deletes the tempfile. The close
method is also part of the Rack specification.
# File lib/goliath/rack_proxy.rb, line 168 def close @cache.close! if @cache end
read(length = nil, outbuf = nil)
click to toggle source
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.
# 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()
click to toggle source
Rewinds the tempfile if rewindable. Otherwise raises Errno::ESPIPE exception, which is what other non-rewindable Ruby IO objects raise.
# File lib/goliath/rack_proxy.rb, line 161 def rewind raise Errno::ESPIPE if @cache.nil? @cache.rewind end
Private Instance Methods
next_chunk()
click to toggle source
Retrieves the next chunk by calling the block, and marks EOF when nil was returned.
# File lib/goliath/rack_proxy.rb, line 176 def next_chunk return if @eof chunk = @next_chunk.call @eof = true if chunk.nil? chunk end