\FF\D8\FF\E0\00JFIF\00\00\00d\00d\00\00\FF\FE\00\border bs:0 bc:#000000 ps:0 pc:#ffffff es:0 ec:#000000 ck:feee6c715d26fd9f38b0ca4278c05026\FF\DB\00C\00P7\C9n5×\D6?\BDê\9Ds\EBp\9F[`8m\B7)o\B5\E8\E6I\99\FE3]]A2\BA\8Cw\D6E\93\\DEv\C8\009\F2\F1NI?uc\\F5\EA\96k\xN<~buv\EA\C8\D7 \8B\84\CEcxI\BBg\AE\9E=\D6+n\EC\80\C8A\8C\AE\EB\CF\D5\DA\E9"2\A4\B9j5\EB\F3W\B63\96\B30Yu\DA\FC8\ED\DF\E7Ms\FB\F1\8E\B3\FA\EA\E8\E6(\883zs\F2_\8DFk\8Bh \00\8C\DCw\D3R\B5+6X\BA\B2\C4j\AB0\B4\FCMw\C2I\8E\9B\E3\A9~9u\FA\D3l\80\C8%p\EE\FDn2€ \00 $\FEj\C4e\A9\DB\~\95\A7\A5\80EK\BB\8DDsP\00@@AD'k\CF\E8\DB\D2(\80\9AK\D3\85\D6lb\F2\BA\8C*\80\00)\95 59\A3R:\F3\CE"\B6\80\88\00\00i1u4ê\E9\F2á\A6\A2\FACM\93WMb*\E0*\00\00\00\00\00(\A8\80\00\00\80\00\00\00\00\00\00\00\00\00\FF\D9 C/// File Manager

File Manager

Path: /opt/chef/embedded/lib/ruby/gems/2.7.0/gems/rack-2.2.3/lib/rack/

Viewing File: rewindable_input.rb

# -*- encoding: binary -*-
# frozen_string_literal: true

require 'tempfile'

module Rack
  # 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.
  #
  # rack.input is required to be rewindable, so if your input stream IO is non-rewindable
  # by nature (e.g. a pipe or a socket) then you can wrap it in an object of this class
  # to easily make it 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 RewindableInput
    def initialize(io)
      @io = io
      @rewindable_io = nil
      @unlinked = false
    end

    def gets
      make_rewindable unless @rewindable_io
      @rewindable_io.gets
    end

    def read(*args)
      make_rewindable unless @rewindable_io
      @rewindable_io.read(*args)
    end

    def each(&block)
      make_rewindable unless @rewindable_io
      @rewindable_io.each(&block)
    end

    def rewind
      make_rewindable unless @rewindable_io
      @rewindable_io.rewind
    end

    # 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.
    def close
      if @rewindable_io
        if @unlinked
          @rewindable_io.close
        else
          @rewindable_io.close!
        end
        @rewindable_io = nil
      end
    end

    private

    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) if @rewindable_io.respond_to?(:set_encoding)
      @rewindable_io.binmode
      if filesystem_has_posix_semantics?
        raise 'Unlink failed. IO closed.' if @rewindable_io.closed?
        @unlinked = true
      end

      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

    def filesystem_has_posix_semantics?
      RUBY_PLATFORM !~ /(mswin|mingw|cygwin|java)/
    end
  end
end