class Utopia::Static::LocalFile
Represents a local file on disk which can be served directly, or passed upstream to sendfile.
Constants
- CONTENT_LENGTH
- CONTENT_RANGE
Attributes
etag[R]
path[R]
range[R]
root[R]
Public Class Methods
new(root, path)
click to toggle source
# File lib/utopia/static/local_file.rb, line 31 def initialize(root, path) @root = root @path = path @etag = Digest::SHA1.hexdigest("#{File.size(full_path)}#{mtime_date}") @range = nil end
Public Instance Methods
bytesize()
click to toggle source
# File lib/utopia/static/local_file.rb, line 57 def bytesize File.size(full_path) end
Also aliased as: size
each() { |part| ... }
click to toggle source
# File lib/utopia/static/local_file.rb, line 68 def each File.open(full_path, "rb") do |file| file.seek(@range.begin) remaining = @range.end - @range.begin+1 while remaining > 0 break unless part = file.read([8192, remaining].min) remaining -= part.length yield part end end end
empty?()
click to toggle source
This reflects whether calling each would yield anything.
# File lib/utopia/static/local_file.rb, line 62 def empty? bytesize == 0 end
full_path()
click to toggle source
# File lib/utopia/static/local_file.rb, line 49 def full_path File.join(@root, @path.components) end
modified?(env)
click to toggle source
# File lib/utopia/static/local_file.rb, line 83 def modified?(env) if modified_since = env['HTTP_IF_MODIFIED_SINCE'] return false if File.mtime(full_path) <= Time.parse(modified_since) end if etags = env['HTTP_IF_NONE_MATCH'] etags = etags.split(/\s*,\s*/) return false if etags.include?(etag) || etags.include?('*') end return true end
mtime_date()
click to toggle source
# File lib/utopia/static/local_file.rb, line 53 def mtime_date File.mtime(full_path).httpdate end
serve(env, response_headers)
click to toggle source
# File lib/utopia/static/local_file.rb, line 99 def serve(env, response_headers) ranges = Rack::Utils.get_byte_ranges(env['HTTP_RANGE'], size) response = [200, response_headers, self] # puts "Requesting ranges: #{ranges.inspect} (#{size})" if ranges == nil or ranges.size != 1 # No ranges, or multiple ranges (which we don't support). # TODO: Support multiple byte-ranges, for now just send entire file: response[0] = 200 response[1][CONTENT_LENGTH] = size.to_s @range = 0...size else # Partial content: @range = ranges[0] partial_size = @range.size response[0] = 206 response[1][CONTENT_LENGTH] = partial_size.to_s response[1][CONTENT_RANGE] = "bytes #{@range.min}-#{@range.max}/#{size}" end return response end
to_path()
click to toggle source
Fit in with Rack::Sendfile
# File lib/utopia/static/local_file.rb, line 45 def to_path full_path end