class Shrine::Plugins::RackResponse::FileBody

Implements the interface of a Rack response body object.

Attributes

file[R]
range[R]

Public Class Methods

new(file, range: nil) click to toggle source
# File lib/shrine/plugins/rack_response.rb, line 127
def initialize(file, range: nil)
  @file  = file
  @range = range
end

Public Instance Methods

bytesize() click to toggle source
# File lib/shrine/plugins/rack_response.rb, line 146
def bytesize
  each.inject(0) { |sum, chunk| sum += chunk.length }
end
close() click to toggle source

Closes the file when response body is closed by the web server.

# File lib/shrine/plugins/rack_response.rb, line 142
def close
  file.close
end
each(&block) click to toggle source

Streams the uploaded file directly from the storage.

# File lib/shrine/plugins/rack_response.rb, line 133
def each(&block)
  if range
    read_partial_chunks(&block)
  else
    read_chunks(&block)
  end
end
method_missing(name, *args, &block) click to toggle source

Rack::Sendfile is activated when response body responds to to_path.

Calls superclass method
# File lib/shrine/plugins/rack_response.rb, line 156
def method_missing(name, *args, &block)
  name == :to_path && path or super
end
respond_to_missing?(name, include_private = false) click to toggle source

Rack::Sendfile is activated when response body responds to to_path.

# File lib/shrine/plugins/rack_response.rb, line 151
def respond_to_missing?(name, include_private = false)
  name == :to_path && path
end

Private Instance Methods

path() click to toggle source

Returns actual path on disk when FileSystem storage is used.

# File lib/shrine/plugins/rack_response.rb, line 198
def path
  if defined?(Storage::FileSystem) && file.storage.is_a?(Storage::FileSystem)
    file.storage.path(file.id)
  end
end
read_chunks() { |chunk| ... } click to toggle source

Yields reasonably sized chunks of uploaded file’s content.

# File lib/shrine/plugins/rack_response.rb, line 189
def read_chunks
  if file.to_io.respond_to?(:each_chunk) # Down::ChunkedIO
    file.to_io.each_chunk { |chunk| yield chunk }
  else
    yield file.read(16*1024) until file.eof?
  end
end
read_partial_chunks() { |chunk| ... } click to toggle source

Yields reasonably sized chunks of uploaded file’s partial content specified by the given index range.

# File lib/shrine/plugins/rack_response.rb, line 164
def read_partial_chunks
  bytes_read = 0

  read_chunks do |chunk|
    chunk_range = bytes_read..(bytes_read + chunk.bytesize - 1)

    if chunk_range.begin > range.end
      # no more chunks will match
      return
    elsif chunk_range.begin >= range.begin && chunk_range.end <= range.end
      yield chunk
    elsif chunk_range.end >= range.begin && chunk_range.begin <= range.end
      requested_range_begin = [chunk_range.begin, range.begin].max - bytes_read
      requested_range_end   = [chunk_range.end, range.end].min - bytes_read

      yield chunk.byteslice(requested_range_begin..requested_range_end)
    else
      # skip chunk
    end

    bytes_read += chunk.bytesize
  end
end