module Repobrowse::Static

Public Instance Methods

fopen(r, pathname) click to toggle source
# File lib/repobrowse/static.rb, line 19
def fopen(r, pathname)
  F.open(pathname)
rescue SystemCallError
  r404(r)
end
prepare_range(env, r, fp, h, beg_s, fin_s, size) click to toggle source
# File lib/repobrowse/static.rb, line 25
def prepare_range(env, r, fp, h, beg_s, fin_s, size)
  code = 200
  len = size
  beg = beg_s.to_i
  fin = fin_s.to_i
  if beg_s == ''
    if fin_s != '' # "bytes=-end" => last N bytes
      beg = size - fin
      beg = 0 if beg < 0
      fin = size - 1
      code = 206
    else
      code = 416
    end
  else
    if beg > size
      code = 416
    elsif fin_s == '' || fin >= size
      fin = size - 1
      code = 206
    elsif fin < size
      code = 206
    else
      code = 416
    end
  end
  if code == 206
    len = fin - beg + 1;
    if len <= 0
      code = 416
    else
      # most Rack servers do not handle range requests correctly
      # if they use .to_path
      fp.autoclose = false
      fp.seek(beg, IO::SEEK_SET) or r.halt [ 500, [], [] ]
      fp = Repobrowse::LimitRd.new(fp, fin - beg + 1, ''.b)
      h['Accept-Ranges'] = -'bytes'
      h['Content-Range'] = "bytes #{beg}-#{fin}/#{size}"
    end
  end
  if code == 416
    h['Content-Range'] = -"bytes */#{size}"
    r.halt [ 416, h, [] ]
  end
  [ code, len, fp ]
end
static(r, pathname, type, exp = 31536000) click to toggle source

expires in 1 year

# File lib/repobrowse/static.rb, line 73
def static(r, pathname, type, exp = 31536000)
  r.get do
    fp = fopen(r, pathname)
    h = { 'Content-Type' => type }
    if exp
      h['Expires'] = -((Time.now + exp).httpdate)
      h['Cache-Control'] = -"public, max-age=#{exp}"
    else
      h['Expires'] = 'Fri, 01 Jan 1980 00:00:00 GMT'
      h['Pragma'] = 'no-cache'
      h['Cache-Control'] = 'no-cache, max-age=0, must-revalidate'
    end
    # TODO: If-Modified-Since and Last-Modified?
    code = 200
    st = fp.stat
    size = st.size
    if env['HTTP_RANGE'] =~ /\bbytes=(\d*)-(\d*)\z/
      code, size, fp = prepare_range(env, r, fp, h, $1, $2, size)
    end
    h['Content-Length'] = -size.to_s
    r.halt [ code, h, fp ]
  end
end