Class: Merb::Dispatcher

Inherits:
Object show all
Defined in:
lib/merb-core/dispatch/dispatcher.rb

Constant Summary collapse

DEFAULT_ERROR_TEMPLATE =
File.expand_path(File.dirname(__FILE__) / 'exceptions.html')
@@mutex =
Mutex.new
@@work_queue =
Queue.new

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.use_mutexObject

Returns the value of attribute use_mutex.



6
7
8
# File 'lib/merb-core/dispatch/dispatcher.rb', line 6

def use_mutex
  @use_mutex
end

Class Method Details

.handle(rack_env) ⇒ Object

This is where we grab the incoming request REQUEST_URI and use that in the merb RouteMatcher to determine which controller and method to run. Returns a 2 element tuple of: [controller, action]

ControllerExceptions are rescued here and redispatched.

Parameters

rack_env<Rack::Environment>

The rack environment, which is used to instantiate a Merb::Request

response<IO>

An IO object to hold the response

Returns

Array[Merb::Controller, Symbol]

An array containing the Merb::Controller and the action that was dispatched to.



33
34
35
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/merb-core/dispatch/dispatcher.rb', line 33

def handle(rack_env)
  start   = Time.now
  request = Merb::Request.new(rack_env)
  Merb.logger.info "Started request handling: #{start.to_s}"
  
  route_index, route_params = Merb::Router.match(request)
  route = Merb::Router.routes[route_index] if route_index
 
  return dispatch_redirection(request,route) if route && route.behavior.redirects?      
  
  if route_params.empty?
    raise ::Merb::ControllerExceptions::NotFound, "No routes match the request: #{request.uri}."
  end
  request.route_params = route_params
  request.params.merge! route_params
        
  controller_name = (route_params[:namespace] ? route_params[:namespace] + '/' : '') + route_params[:controller]
  
  unless controller_name
    raise Merb::ControllerExceptions::NotFound, "Route matched, but route did not specify a controller. Did you forgot to add :controller => \"people\" or :controller segment to route definition? Here is what's specified: #{request.route_params.inspect}" 
  end
  
  Merb.logger.debug("Routed to: #{request.route_params.inspect}")

  cnt = controller_name.snake_case.to_const_string
  
  if !Merb::Controller._subclasses.include?(cnt)
    raise Merb::ControllerExceptions::NotFound, "Controller '#{cnt}' not found. If Merb tries to look for a controller for static files, you way need to check up your Rackup file, see Problems section at: http://wiki.merbivore.com/pages/rack-middleware"
  end
  if cnt == "Application"
    raise Merb::ControllerExceptions::NotFound, "The 'Application' controller has no public actions"
  end

  begin
    klass = Object.full_const_get(cnt)
  rescue NameError => e
    Merb.logger.warn!("Controller class not found for controller #{controller_name}: #{e.message}")
    raise Merb::ControllerExceptions::NotFound
  end

  Merb.logger.info("Params: #{klass._filter_params(request.params).inspect}")

  action = route_params[:action]

  if route.allow_fixation? && request.params.key?(Merb::Controller._session_id_key)
    Merb.logger.info("Fixated session id: #{Merb::Controller._session_id_key}")
    request.cookies[Merb::Controller._session_id_key] = request.params[Merb::Controller._session_id_key]
  end  
  
  controller = dispatch_action(klass, action, request)
  controller._benchmarks[:dispatch_time] = Time.now - start
  controller.route = route
  Merb.logger.info controller._benchmarks.inspect
  Merb.logger.flush

  controller
# this is the custom dispatch_exception; it allows failures to still be dispatched
# to the error controller
rescue => exception
  Merb.logger.error(Merb.exception(exception))
  unless request.xhr?
    exception = controller_exception(exception)
    dispatch_exception(request, exception)
  else
    Struct.new(:headers, :status, :body).new({}, 500,
      <<-HERE
#{exception.message}
 
Params:
#{(request.params || {}).map { |p,v| "  #{p}: #{v}\n"}.join("\n")}
 
Session:
#{(request.session || {}).map { |p,v| "  #{p}: #{v}\n"}.join("\n")}
 
Cookies:
#{(request.cookies || {}).map { |p,v| "  #{p}: #{v}\n"}.join("\n")}
 
Stacktrace:
#{exception.backtrace.join("\n")}
      HERE
    )
  end
end

.work_queueObject



11
12
13
# File 'lib/merb-core/dispatch/dispatcher.rb', line 11

def work_queue 
  @@work_queue
end