class Shrine::Plugins::RackResponse::FileResponse
Attributes
file[R]
Public Class Methods
new(file)
click to toggle source
# File lib/shrine/plugins/rack_response.rb, line 21 def initialize(file) @file = file end
Public Instance Methods
call(**options)
click to toggle source
Returns a Rack response triple for the uploaded file.
# File lib/shrine/plugins/rack_response.rb, line 26 def call(**options) file.open unless file.opened? options[:range] = parse_content_range(options[:range]) if options[:range] status = rack_status(**options) headers = rack_headers(**options) body = rack_body(**options) headers = Rack::Headers[headers] if Rack.release >= "3" [status, headers, body] end
Private Instance Methods
accept_ranges(range)
click to toggle source
Value for the “Accept-Ranges” header.
# File lib/shrine/plugins/rack_response.rb, line 87 def accept_ranges(range) "bytes" unless range == false end
content_disposition(disposition, filename)
click to toggle source
Value for the “Content-Disposition” header.
# File lib/shrine/plugins/rack_response.rb, line 75 def content_disposition(disposition, filename) filename ||= file.original_filename || file.id.split("/").last ContentDisposition.format(disposition: disposition, filename: filename) end
content_length(range)
click to toggle source
Value for the “Content-Length” header.
# File lib/shrine/plugins/rack_response.rb, line 64 def content_length(range) length = range ? range.size : file.size length.to_s if length end
content_range(range)
click to toggle source
Value for the “Content-Range” header.
# File lib/shrine/plugins/rack_response.rb, line 82 def content_range(range) "bytes #{range.begin}-#{range.end}/#{file.size}" if range end
content_type(type)
click to toggle source
Value for the “Content-Type” header.
# File lib/shrine/plugins/rack_response.rb, line 70 def content_type(type) type || file.mime_type || Rack::Mime.mime_type(".#{file.extension}", nil) end
etag()
click to toggle source
Value for the “ETag” header.
# File lib/shrine/plugins/rack_response.rb, line 92 def etag digest = Digest::SHA256.hexdigest("#{file.shrine_class}-#{file.storage_key}-#{file.id}") %(W/"#{digest.byteslice(0, 32)}") end
get_byte_ranges(range_header)
click to toggle source
# File lib/shrine/plugins/rack_response.rb, line 111 def get_byte_ranges(range_header) Rack::Utils.get_byte_ranges(range_header, file.size) end
parse_content_range(range_header)
click to toggle source
Retrieves a range value parsed from HTTP “Range” header.
# File lib/shrine/plugins/rack_response.rb, line 105 def parse_content_range(range_header) ranges = get_byte_ranges(range_header) ranges.first if ranges && ranges.one? end
rack_body(range: nil, **)
click to toggle source
Returns an object that responds to each and close, which yields contents of the file.
# File lib/shrine/plugins/rack_response.rb, line 100 def rack_body(range: nil, **) FileBody.new(file, range: range) end
rack_headers(filename: nil, type: nil, disposition: "inline", range: false)
click to toggle source
Returns a hash of “Content-Length”, “Content-Type” and “Content-Disposition” headers, whose values are extracted from metadata. Also returns the correct “Content-Range” header on ranged requests.
# File lib/shrine/plugins/rack_response.rb, line 52 def rack_headers(filename: nil, type: nil, disposition: "inline", range: false) { "Content-Length" => content_length(range), "Content-Type" => content_type(type), "Content-Disposition" => content_disposition(disposition, filename), "Content-Range" => content_range(range), "Accept-Ranges" => accept_ranges(range), "ETag" => etag, }.compact end
rack_status(range: nil, **)
click to toggle source
Returns “200 OK” on full request, and “206 Partial Content” on ranged request.
# File lib/shrine/plugins/rack_response.rb, line 44 def rack_status(range: nil, **) range ? 206 : 200 end