Class: Sinatra::Helpers::StaticFile

Inherits:
File
  • Object
show all
Defined in:
lib/sinatra/base.rb

Overview

Rack response body used to deliver static files. The file contents are generated iteratively in 8K chunks.

Constant Summary collapse

CHUNK_SIZE =
8192

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#rangeObject

a Range or nil



218
219
220
# File 'lib/sinatra/base.rb', line 218

def range
  @range
end

Instance Method Details

#byte_ranges(env, size) ⇒ Object

TODO: Copied from the new method Rack::Utils::byte_ranges; this method can be removed once a version of Rack with that method is released and Sinatra can depend on it.



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/sinatra/base.rb', line 232

def byte_ranges(env, size)
  # See <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.35>
  http_range = env['HTTP_RANGE']
  return nil unless http_range
  ranges = []
  http_range.split(/,\s*/).each do |range_spec|
    matches = range_spec.match(/bytes=(\d*)-(\d*)/)
    return nil  unless matches
    r0,r1 = matches[1], matches[2]
    if r0.empty?
      return nil  if r1.empty?
      # suffix-byte-range-spec, represents trailing suffix of file
      r0 = [size - r1.to_i, 0].max
      r1 = size - 1
    else
      r0 = r0.to_i
      if r1.empty?
        r1 = size - 1
      else
        r1 = r1.to_i
        return nil  if r1 < r0  # backwards range is syntactically invalid
        r1 = size-1  if r1 >= size
      end
    end
    ranges << (r0..r1)  if r0 <= r1
  end
  ranges
end

#eachObject



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/sinatra/base.rb', line 263

def each
  if @range
    self.pos = @range.begin
    length = @range.end - @range.begin + 1
    while length > 0 && (buf = read([CHUNK_SIZE,length].min))
      yield buf
      length -= buf.length
    end
  else
    rewind
    while buf = read(CHUNK_SIZE)
      yield buf
    end
  end
end

#parse_ranges(env, size) ⇒ Object

Checks for byte-ranges in the request and sets self.range appropriately. Returns false if the ranges are unsatisfiable and the request should return 416.



222
223
224
225
226
227
228
# File 'lib/sinatra/base.rb', line 222

def parse_ranges(env, size)
  #r = Rack::Utils::byte_ranges(env, size)  # TODO: not available yet in released Rack
  r = byte_ranges(env, size)
  return false if r == []  # Unsatisfiable; report error
  @range = r[0] if r && r.length == 1  # Ignore multiple-range requests for now
  return true
end