Class: Regurgitator::LocalFile
- Inherits:
-
Object
- Object
- Regurgitator::LocalFile
- Defined in:
- lib/regurgitator/local_file.rb
Overview
used to serve local files, bypassing HTTP to the backend device
Instance Attribute Summary collapse
-
#response ⇒ Object
readonly
Stores the Rack response (a 3-element Array) on success to simulate HTTP_Spew::Request objects.
-
#to_path ⇒ Object
readonly
may be called by some Rack web servers to use sendfile(2).
-
#uri ⇒ Object
readonly
used to provide redirects to clients.
Instance Method Summary collapse
-
#each ⇒ Object
normal Rack HTTP server endpoint, used if the server can’t handle
to_path
. -
#initialize(env, path, uri, stat) ⇒ LocalFile
constructor
A new instance of LocalFile.
- #modified_since?(modified_since, stat) ⇒ Boolean
Constructor Details
#initialize(env, path, uri, stat) ⇒ LocalFile
Returns a new instance of LocalFile.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/regurgitator/local_file.rb', line 17 def initialize(env, path, uri, stat) if modified_since = env["HTTP_IF_MODIFIED_SINCE"] modified_since?(modified_since, stat) or return end size = stat.size headers = { "Content-Type" => "application/octet-stream".freeze, # always ".fid" "Content-Length" => size.to_s, "Last-Modified" => stat.mtime.httpdate, "Accept-Ranges" => "bytes".freeze, } @response = [ 200, headers ] ranges = Rack::Utils.get_byte_ranges(env['HTTP_RANGE'], size) if nil == ranges || ranges.size > 1 @range = nil elsif @range = ranges[0] @response[0] = 206 headers["Content-Range"] = "bytes #{@range.begin}-#{@range.end}/#{size}" headers["Content-Length"] = (@range.end - @range.begin + 1).to_s else @response[0] = 416 headers["Content-Range"] = "bytes */#{size}" headers["Content-Length"] = '0'.freeze @response << [] return end case env["REQUEST_METHOD"] when "GET" @to_path, @uri = path, uri @response << self when "HEAD" @response << [] else raise "BUG: Unexpected REQUEST_METHOD=#{env['REQUEST_METHOD']}" end end |
Instance Attribute Details
#response ⇒ Object (readonly)
Stores the Rack response (a 3-element Array) on success to simulate HTTP_Spew::Request objects
15 16 17 |
# File 'lib/regurgitator/local_file.rb', line 15 def response @response end |
#to_path ⇒ Object (readonly)
may be called by some Rack web servers to use sendfile(2)
8 9 10 |
# File 'lib/regurgitator/local_file.rb', line 8 def to_path @to_path end |
#uri ⇒ Object (readonly)
used to provide redirects to clients
11 12 13 |
# File 'lib/regurgitator/local_file.rb', line 11 def uri @uri end |
Instance Method Details
#each ⇒ Object
normal Rack HTTP server endpoint, used if the server can’t handle to_path
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/regurgitator/local_file.rb', line 59 def each File.open(@to_path) do |fp| buf = "" max = 0x4000 if @range fp.seek(@range.begin) len = @range.end - @range.begin + 1 while len > 0 && fp.read(len > max ? max : len, buf) len -= buf.size yield buf end else while fp.read(0x4000, buf) yield buf end end buf.clear end end |
#modified_since?(modified_since, stat) ⇒ Boolean
79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/regurgitator/local_file.rb', line 79 def modified_since?(modified_since, stat) begin modified_since = Time.httpdate(modified_since) rescue ArgumentError h = { "Content-Type" => "text/plain", "Content-Length" => "0" } @response = [ 400, h, [] ] return false end stat.mtime > modified_since and return true @response = [ 304, {}, [] ] false end |