module Merb class Dispatcher class << self attr_accessor :path_prefix def use_mutex=(val) @@use_mutex = val end @@mutex = Mutex.new @@use_mutex = ::Merb::Server.use_mutex # 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] def handle(request, response) request_uri = request.params[Mongrel::Const::REQUEST_URI] request_uri.sub!(path_prefix, '') if path_prefix route = route_path(request_uri) allowed = route.delete(:allowed) rest = route.delete(:rest) controller = instantiate_controller(route[:controller], request.body, request.params, route, response) if rest method = controller.request.method if allowed.keys.include?(method) && action = allowed[method] controller.params[:action] = action else raise Merb::RestfulMethodNotAllowed.new(method, allowed) end else action = route[:action] end if @@use_mutex @@mutex.synchronize { controller.dispatch(action) } else controller.dispatch(action) end [controller, action] end def route_path(path) path = path.sub(/\/+/, '/').sub(/\?.*$/, '') path = path[0..-2] if (path[-1] == ?/) && path.size > 1 Merb::Router.match(path) end # take a controller class name string and reload or require # the right controller file then CamelCase it and turn it # into a new object passing in the request and response. # this is where your Merb::Controller is instantiated. def instantiate_controller(controller_name, req, env, params, res) if !File.exist?(DIST_ROOT+"/app/controllers/#{controller_name.snake_case}.rb") raise "Bad controller! #{controller_name.snake_case}" end unless $TESTING begin unless MERB_ENV == 'production' Object.send(:remove_const, controller_name.camel_case.intern) rescue nil load(controller_name.snake_case + '.rb') end return Object.const_get( controller_name.camel_case ).new(req, env, params, res) rescue RuntimeError warn "Error getting instance of '#{controller_name.camel_case}': #{$!}" raise $! end end end # end class << self end end