Module: Fastr::Dispatch

Included in:
Application
Defined in:
lib/fastr/dispatch.rb

Constant Summary collapse

PUBLIC_FOLDER =

The folder containing static content.

"public"

Instance Method Summary collapse

Instance Method Details

#dispatch(env) ⇒ Array

Convenience wrapper for do_dispatch This is the heart of the server, called indirectly by a Rack aware server.

Parameters:

  • env (Hash)

Returns:

  • (Array)


11
12
13
14
15
16
17
18
19
20
21
# File 'lib/fastr/dispatch.rb', line 11

def dispatch(env)
  return [500, {'Content-Type' => 'text/plain'}, ["Server Not Ready"]] if @booting

  begin
    new_env = plugin_before_dispatch(env)
    plugin_after_dispatch(new_env, do_dispatch(new_env))
  rescue Exception => e
    bt = e.backtrace.join("\n")
    [500, {'Content-Type' => 'text/plain'}, ["Exception: #{e}\n\n#{bt}"]]
  end
end

#dispatch_controller(route, env) ⇒ Object

Raises:



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
# File 'lib/fastr/dispatch.rb', line 41

def dispatch_controller(route, env)
  vars = route[:ok]
  controller = vars[:controller]
  action = vars[:action].to_sym

  raise Fastr::Error.new("Controller and action not present in route") if controller.nil? or action.nil?


  klass = "#{controller.camelcase}Controller"

  log.info "Routing to controller: #{klass}, action: #{action}"

  klass_inst = Module.const_get(klass)
  obj = klass_inst.new
  setup_controller(obj, env, vars)

  # Run before filters
  response = Fastr::Filter.run_before_filters(obj, klass_inst, action)

  # No before filters halted, send to action
  if response.nil?
    response = obj.send(action)
  end

  # Run after filters
  response = Fastr::Filter.run_after_filters(obj, klass_inst, action, response)

  code, hdrs, body = *response

  # Merge headers with anything specified in the controller
  hdrs.merge!(obj.headers)

  [code, hdrs, body]
end

#dispatch_public(env, path) ⇒ Object



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/fastr/dispatch.rb', line 76

def dispatch_public(env, path)
  path = "#{self.app_path}/#{PUBLIC_FOLDER}/#{path[1..(path.length - 1)]}"
  if not File.directory? path and File.exists? path
    f = File.open(path)
    hdrs = {}

    type = MIME::Types.type_for(File.basename(path))

    if not type.nil?
        hdrs["Content-Type"] = type[0].to_s
    end

    return [200, hdrs, [f.read]]
  else
    return nil
  end
end

#do_dispatch(env) ⇒ Object

Route, instantiate controller, return response from controller’s action.



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/fastr/dispatch.rb', line 24

def do_dispatch(env)
  path = env['PATH_INFO']

  # Try to serve a public file
  ret = dispatch_public(env, path)
  return ret if not ret.nil?

  log.debug "Checking for routes that match: #{path}"
  route = router.match(env)

  if route.has_key? :ok
    dispatch_controller(route, env)
  else
    [404, {"Content-Type" => "text/plain"}, ["404 Not Found: #{path}"]]
  end
end

#plugin_after_dispatch(env, response) ⇒ Hash

Runs after_dispatch in all plugins.

Parameters:

  • env (Hash)

Returns:

  • (Hash)


139
140
141
142
143
144
145
146
147
148
149
# File 'lib/fastr/dispatch.rb', line 139

def plugin_after_dispatch(env, response)
  new_response = response

  self.plugins.each do |plugin|
    if plugin.respond_to? :after_dispatch
      new_response = plugin.send(:after_dispatch, self, env, response)
    end
  end

  new_response
end

#plugin_before_dispatch(env) ⇒ Hash

Runs before_dispatch in all plugins.

Parameters:

  • env (Hash)

Returns:

  • (Hash)


123
124
125
126
127
128
129
130
131
132
133
# File 'lib/fastr/dispatch.rb', line 123

def plugin_before_dispatch(env)
  new_env = env

  self.plugins.each do |plugin|
    if plugin.respond_to? :before_dispatch
      new_env = plugin.send(:before_dispatch, self, env)
    end
  end

  new_env
end

#setup_controller(controller, env, vars) ⇒ Object

Sets up a controller for a request.



95
96
97
98
99
100
101
102
103
# File 'lib/fastr/dispatch.rb', line 95

def setup_controller(controller, env, vars)
  controller.env = env
  controller.headers = {}

  setup_controller_params(controller, env, vars)

  controller.cookies = Fastr::HTTP.parse_cookies(env)
  controller.app = self
end

#setup_controller_params(controller, env, vars) ⇒ Object

Populate the parameters based on the HTTP method.



106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/fastr/dispatch.rb', line 106

def setup_controller_params(controller, env, vars)
  if Fastr::HTTP.method?(env, :get)
    controller.get_params = Fastr::HTTP.parse_query_string(env['QUERY_STRING'])
    controller.params = controller.get_params.merge(vars)
  elsif Fastr::HTTP.method?(env, :post)
    controller.post_params = {}
    controller.post_params = Fastr::HTTP.parse_query_string(env['rack.input'].read) if env['rack.input']
    controller.params = controller.post_params.merge(vars)
  else
    controller.params = vars
  end
end