1 # Copyright (C) 2017 all contributors <repobrowse@80x24.org>
2 # License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
3 # frozen_string_literal: true
5 module Repobrowse::Static
8 while buf = read(8192, buf)
16 def fopen(env, r, pathname)
18 rescue SystemCallError => e
21 'Content-Type' => -'text/plain; charset=UTF-8',
22 'Content-Length' => -b.size.to_s,
24 env['rack.logger']&.debug("E: #{pathname.inspect}: #{e.message}")
25 r.halt [ 404, h, [ b ] ]
28 def prepare_range(r, fp, h, beg, fin, size)
32 if fin != -'' # "bytes=-end" => last N bytes
43 elsif fin == -'' || fin >= size
57 fp.seek(beg, IO::SEEK_SET) or r.halt [ 500, [], [] ]
58 h['Accept-Ranges'] = -'bytes'
59 h['Content-Range'] = "bytes #{beg}-#{fin}/#{size}"
63 h['Content-Range'] = -"bytes */#{size}"
69 def static(env, r, pathname, type, exp = 31536000)
70 h = { 'Content-Type' => type }
72 h['Expires'] = -((Time.now + exp).httpdate)
73 h['Cache-Control'] = -"public, max-age=#{exp}"
75 h['Expires'] = 'Fri, 01 Jan 1980 00:00:00 GMT'
76 h['Pragma'] = 'no-cache'
77 h['Cache-Control'] = 'no-cache, max-age=0, must-revalidate'
79 fp = fopen(env, r, pathname)
80 # TODO: If-Modified-Since and Last-Modified?
84 if env['HTTP_RANGE'] =~ /\bbytes=(\d*)-(\d*)\z/
85 code, size = prepare_range(r, fp, h, $1, $2, size)
87 h['Content-Length'] = -size.to_s
88 r.halt [ code, h, fp ]