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 32
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 112
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 68
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 48
def each(&block) make_rewindable unless @rewindable_io @rewindable_io.each(&block) end
#gets
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 38
def gets make_rewindable unless @rewindable_io @rewindable_io.gets end
#make_rewindable (private)
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 81
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 43
def read(*args) make_rewindable unless @rewindable_io @rewindable_io.read(*args) end
#rewind
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 53
def rewind make_rewindable unless @rewindable_io @rewindable_io.rewind end
#size
[ GitHub ]# File 'lib/rack/rewindable_input.rb', line 58
def size make_rewindable unless @rewindable_io @rewindable_io.size end