Class: Rack::Mapper

Inherits:
Object
  • Object
show all
Defined in:
lib/rack/mapper.rb

Defined Under Namespace

Classes: AsyncLogger, Logger

Instance Method Summary collapse

Constructor Details

#initialize(map) ⇒ Mapper

Returns a new instance of Mapper.



6
7
8
# File 'lib/rack/mapper.rb', line 6

def initialize map
  @map = remap(map)
end

Instance Method Details

#app_instance(app, path) ⇒ Object



21
22
23
24
25
# File 'lib/rack/mapper.rb', line 21

def app_instance app, path
  app.new do |instance|
    instance.instance_variable_set(:@rack_mapper_path, path)
  end
end

#call(env) ⇒ Object



16
17
18
19
# File 'lib/rack/mapper.rb', line 16

def call env
  rest, path, app = find_mapping(env['PATH_INFO'])
  app ? dispatch(app, env, rest, path) : not_found(env)
end

#dispatch(app, env, rest, path) ⇒ Object



27
28
29
30
31
32
33
34
35
# File 'lib/rack/mapper.rb', line 27

def dispatch app, env, rest, path
  app.call(
    env.merge(
      'PATH_INFO'    => rest,
      'SCRIPT_NAME'  => ::File.join(env['SCRIPT_NAME'], path),
      'REQUEST_PATH' => ::File.join(env['SCRIPT_NAME'], path, rest),
    )
  )
end

#find_mapping(path) ⇒ Object



41
42
43
44
45
46
47
48
# File 'lib/rack/mapper.rb', line 41

def find_mapping path
  @map.each do |re, location, app|
    if re.match(path)
      return ["/#{$1}", location, app]
    end
  end
  return nil
end

#not_found(env) ⇒ Object



37
38
39
# File 'lib/rack/mapper.rb', line 37

def not_found env
  [404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["no application mounted at #{env['REQUEST_PATH']}"]]
end

#remap(map) ⇒ Object



10
11
12
13
14
# File 'lib/rack/mapper.rb', line 10

def remap map
  map.map     {|path, app| [path, app.respond_to?(:new) ? app_instance(app, path) : app]}
     .sort_by {|path, app| path.size}.reverse
     .map     {|path, app| [Regexp.new("^#{path.chomp('/')}(?:/(.*)|$)"), path, app]}
end