C0 code coverage information
Generated on Sat Feb 02 17:44:25 +0100 2008 with rcov 0.8.1.2
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Copyright (c) 2008 Michael Fellinger m.fellinger@gmail.com
2 # All files in this distribution are subject to the terms of the Ruby license.
3
4 require 'timeout'
5
6 require 'ramaze/error'
7 require 'ramaze/adapter'
8 require 'ramaze/tool/mime'
9
10 require 'ramaze/dispatcher/action'
11 require 'ramaze/dispatcher/error'
12 require 'ramaze/dispatcher/file'
13 require 'ramaze/dispatcher/directory'
14
15 module Ramaze
16
17 # The Dispatcher receives requests from adapters and sets up the proper environment
18 # to process them and respond.
19
20 module Dispatcher
21
22 # requests are passed to every
23 FILTER = [ Dispatcher::File, Dispatcher::Action ] unless defined?(FILTER)
24
25 # Response codes to cache the output of for repeated requests.
26 trait :shielded => [ STATUS_CODE["Not Found"] ]
27
28 class << self
29 include Trinity
30
31 # Entry point for Adapter#respond, takes a Rack::Request and
32 # Rack::Response, sets up the environment and the goes on to dispatch
33 # for the given path from rack_request.
34 def handle rack_request, rack_response
35 setup_environment(rack_request, rack_response)
36
37 path = request.path_info.squeeze('/')
38
39 case path
40 when *Global.ignore
41 unless ::File.exist?(Dispatcher::File.resolve_path(path))
42 return response.build(Global.ignore_body, Global.ignore_status)
43 end
44 end
45
46 general_dispatch path
47 rescue Object => error
48 meta = { :path => path,
49 :request => request,
50 :controller => Thread.current[:controller] }
51 Dispatcher::Error.process(error, meta)
52 end
53
54 # protcets against recursive dispatch and reassigns the path_info in the
55 # request, the rest of the request is kept intact.
56 def dispatch_to(path)
57 if request.path_info == path
58 if error = Thread.current[:exception]
59 raise error
60 else
61 raise "Recursive redirect from #{path} to #{path}"
62 end
63 end
64 request.path_info = path
65 general_dispatch path
66 end
67
68 # splits up the dispatch based on Global.shield
69 def general_dispatch(path)
70 if Global.shield
71 shielded_dispatch path
72 else
73 dispatch path
74 end
75 end
76
77 # Protects somewhat against hammering of erroring paths, since error-pages
78 # take a while to build in the default mode it is possible to decrease
79 # overall speed quite a bit by hitting Ramaze with such paths.
80 # shielded_dispatch checks the path and caches erronous responses so they
81 # won't be recreated but simply pushed out again without stopping at the
82 # Controller.
83 # Please note that this is just minor protection and the best option is to
84 # create a performant error-page instead.
85 def shielded_dispatch(path)
86 shield_cache = Cache.shield
87 handled = shield_cache[path]
88 return handled if handled
89
90 dispatched = dispatch(path)
91
92 unless trait[:shielded].include?(dispatched.status)
93 dispatched
94 else
95 shield_cache[path] = dispatched
96 end
97 end
98
99 # filters the path until a response or redirect is thrown or a filter is
100 # successful, builds a response from the returned hash in case of throws.
101 def dispatch(path)
102 catch(:respond){
103 redirected = catch(:redirect){
104 filter(path)
105 throw(:respond)
106 }
107 response.build(*redirected)
108 }
109 end
110
111 # Calls .process(path) on every class in Dispatcher::FILTER until one
112 # returns something else than false/nil.
113
114 def filter(path)
115 result = nil
116 FILTER.each do |dispatcher|
117 result = dispatcher.process(path)
118 return result if result and not result.respond_to?(:exception)
119 end
120
121 meta = {
122 :path => path,
123 :controller => Thread.current[:controller]
124 }
125 Dispatcher::Error.process(result, meta)
126 end
127
128 # finalizes the session and assigns the key to the response via
129 # set_cookie.
130
131 def set_cookie
132 session.finalize
133 hash = {:value => session.session_id}.merge(Session::COOKIE)
134 response.set_cookie(Session::SESSION_KEY, hash)
135 end
136
137 # Setup the Trinity (Request, Response, Session) and store them as
138 # thread-variables in Thread.current
139 # Thread.current[:request] == Request.current
140 # Thread.current[:response] == Response.current
141 # Thread.current[:session] == Session.current
142
143 def setup_environment rack_request, rack_response
144 this = Thread.current
145 this[:request] = rack_request
146 this[:session] = Session.new(request) if Global.sessions
147 this[:response] = rack_response
148 end
149 end
150 end
151 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.1.2.