Module: Ramaze::Dispatcher

Extended by:
Trinity
Defined in:
lib/ramaze/dispatcher.rb,
lib/ramaze/dispatcher/file.rb,
lib/ramaze/dispatcher/error.rb,
lib/ramaze/contrib/profiling.rb,
lib/ramaze/dispatcher/action.rb,
lib/ramaze/dispatcher/directory.rb

Overview

The Dispatcher receives requests from adapters and sets up the proper environment to process them and respond.

Defined Under Namespace

Classes: Action, ActionProfiler, Directory, Error, File

Constant Summary collapse

FILTER =

requests are passed to every

[ Dispatcher::File, Dispatcher::Action ]

Class Method Summary collapse

Class Method Details

.dispatch(path) ⇒ Object

filters the path until a response or redirect is thrown or a filter is successful, builds a response from the returned hash in case of throws.



98
99
100
101
102
103
104
105
106
# File 'lib/ramaze/dispatcher.rb', line 98

def dispatch(path)
  catch(:respond){
    redirected = catch(:redirect){
      filter(path)
      throw(:respond)
    }
    response.build(*redirected)
  }
end

.dispatch_to(path) ⇒ Object

protects against recursive dispatch and reassigns the path_info in the request, the rest of the request is kept intact.



53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ramaze/dispatcher.rb', line 53

def dispatch_to(path)
  if request.path_info == path
    if error = Thread.current[:exception]
      raise error
    else
      raise "Recursive redirect from #{path} to #{path}"
    end
  end
  request.path_info = path
  general_dispatch path
end

.error(obj, meta = {}) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/ramaze/dispatcher.rb', line 121

def error(obj, meta = {})
  controller = Thread.current[:controller]
  meta[:controller] ||= controller if controller

  if Global.middleware
    message = "No action for '#{meta[:path]}'"
    message << " on '#{CGI.escapeHTML(controller.to_s)}'" if controller

    raise(obj) if obj.respond_to?(:message)
    raise(Ramaze::Error, message)
  else
    Dispatcher::Error.call(obj, meta)
  end
end

.filter(path) ⇒ Object

Calls .call(path) on every object in Dispatcher::FILTER until one returns something else than false/nil.



111
112
113
114
115
116
117
118
119
# File 'lib/ramaze/dispatcher.rb', line 111

def filter(path)
  result = nil
  FILTER.each do |dispatcher|
    result = dispatcher.call(path)
    return result if result and not result.respond_to?(:exception)
  end

  error(result, :path => path)
end

.general_dispatch(path) ⇒ Object

splits up the dispatch based on Global.shield



66
67
68
69
70
71
72
# File 'lib/ramaze/dispatcher.rb', line 66

def general_dispatch(path)
  if Global.shield
    shielded_dispatch path
  else
    dispatch path
  end
end

.handleObject

Entry point for Adapter#respond, takes a Rack::Request and Rack::Response, sets up the environment and the goes on to dispatch for the given path from rack_request.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/ramaze/dispatcher.rb', line 31

def handle
  path = request.path_info.squeeze('/')

  if new_path = Rewrite.resolve(path)
    path = new_path
    Log.dev("Rewriting `#{path}' to `#{path}'")
  end

  case path
  when *Global.ignore
    unless ::File.exist?(Dispatcher::File.resolve_path(path))
      return response.build(Global.ignore_body, Global.ignore_status)
    end
  end

  general_dispatch path
rescue Object => exception
  error(exception)
end

.shielded_dispatch(path) ⇒ Object

Protects somewhat against hammering of erroring paths, since error-pages take a while to build in the default mode it is possible to decrease overall speed quite a bit by hitting Ramaze with such paths. shielded_dispatch checks the path and caches erronous responses so they won’t be recreated but simply pushed out again without stopping at the Controller. Please note that this is just minor protection and the best option is to create a performant error-page instead.



82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/ramaze/dispatcher.rb', line 82

def shielded_dispatch(path)
  shield_cache = Cache.shield
  handled = shield_cache[path]
  return handled if handled

  dispatched = dispatch(path)

  unless trait[:shielded].include?(dispatched.status)
    dispatched
  else
    shield_cache[path] = dispatched
  end
end