Class: Rack::RewindableInput
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Inherits: | Object |
Defined in: | lib/rack/rewindable_input.rb |
Overview
Class which can make any IO object rewindable, including non-rewindable ones. It does this by buffering the data into a tempfile, which is rewindable.
Don’t forget to call #close when you’re done. This frees up temporary resources that RewindableInput
uses, though it does not close the original IO object.
Class Method Summary
- .new(io) ⇒ RewindableInput constructor
Instance Attribute Summary
- #filesystem_has_posix_semantics? ⇒ Boolean readonly private
Instance Method Summary
-
#close
Closes this
RewindableInput
object without closing the originally wrapped IO object. - #each(&block)
- #gets
- #read(*args)
- #rewind
- #size
- #make_rewindable private
Constructor Details
.new(io) ⇒ RewindableInput
# File 'lib/rack/rewindable_input.rb', line 29
def initialize(io) @io = io @rewindable_io = nil @unlinked = false end
Instance Attribute Details
#filesystem_has_posix_semantics? ⇒ Boolean
(readonly, private)
[ GitHub ]
# File 'lib/rack/rewindable_input.rb', line 109
def filesystem_has_posix_semantics? RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/ end
Instance Method Details
#close
Closes this RewindableInput
object without closing the originally wrapped IO object. Cleans up any temporary resources that this RewindableInput
has created.
This method may be called multiple times. It does nothing on subsequent calls.
# File 'lib/rack/rewindable_input.rb', line 65
def close if @rewindable_io if @unlinked @rewindable_io.close else @rewindable_io.close! end @rewindable_io = nil end end
#each(&block)
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 45
def each(&block) make_rewindable unless @rewindable_io @rewindable_io.each(&block) end
#gets
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 35
def gets make_rewindable unless @rewindable_io @rewindable_io.gets end
#make_rewindable (private)
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 78
def make_rewindable # Buffer all data into a tempfile. Since this tempfile is private to this # RewindableInput object, we chmod it so that nobody else can read or write # it. On POSIX filesystems we also unlink the file so that it doesn't # even have a file entry on the filesystem anymore, though we can still # access it because we have the file handle open. @rewindable_io = Tempfile.new('RackRewindableInput') @rewindable_io.chmod(0000) @rewindable_io.set_encoding(Encoding::BINARY) @rewindable_io.binmode # :nocov: if filesystem_has_posix_semantics? raise 'Unlink failed. IO closed.' if @rewindable_io.closed? @unlinked = true end # :nocov: buffer = "".dup while @io.read(1024 * 4, buffer) entire_buffer_written_out = false while !entire_buffer_written_out written = @rewindable_io.write(buffer) entire_buffer_written_out = written == buffer.bytesize if !entire_buffer_written_out buffer.slice!(0 .. written - 1) end end end @rewindable_io.rewind end
#read(*args)
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 40
def read(*args) make_rewindable unless @rewindable_io @rewindable_io.read(*args) end
#rewind
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 50
def rewind make_rewindable unless @rewindable_io @rewindable_io.rewind end
#size
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 55
def size make_rewindable unless @rewindable_io @rewindable_io.size end