Class: OMF::Web::Rack::MultiFile

Inherits:
Rack::File
  • Object
show all
Defined in:
lib/omf-web/rack/multi_file.rb

Overview

Rack::MultiFile serves files which it looks for below an array of roots directories given, according to the path info of the Rack request.

Handlers can detect if bodies are a Rack::File, and use mechanisms like sendfile on the path.

Instance Method Summary collapse

Constructor Details

#initialize(roots, opts = {}) ⇒ MultiFile

Returns a new instance of MultiFile.



13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/omf-web/rack/multi_file.rb', line 13

def initialize(roots, opts = {})
  super nil, opts[:cache_control]
  @roots = roots
  if opts[:sub_path]
    @sub_path = opts[:sub_path].split SEPS
  end
  if @version = opts[:version]
    # read VERSION_MAP.yaml files
    @version_map = {}
    require 'yaml'
    yml = File.join((@sub_path || []), 'VERSION_MAP.yaml')
    @roots.reverse.each do |dir|
      fn = File.join(dir, yml)
      #puts "Checking for #{fn}"
      if File.readable?(fn)
        mh = YAML.load_file(fn)
        #puts "VERSIONS: #{mh.inspect}"
        @version_map.merge!(mh)
      end
    end
  end
end

Instance Method Details

#_call(env) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/omf-web/rack/multi_file.rb', line 36

def _call(env)
  @path_info = ::Rack::Utils.unescape(env["PATH_INFO"])
  parts = @path_info.split SEPS
  if @version_map
    if pkg_name = @version_map[parts[1]]
      parts[1] = pkg_name # replace with version
    end
  end
  if @sub_path
    parts = @sub_path + parts
  end

  return fail(403, "Forbidden")  if parts.include? ".."

  @roots.each do |root|
    @path = F.join(root, *parts)
    #puts ">>>> CHECKING #{@path}"
    available = begin
      F.file?(@path) && F.readable?(@path)
    rescue SystemCallError
      false
    end

    if available
      return serving(env)
    end
  end
  fail(404, "File not found: #{@path_info}")
end