5 module EventManager # :nodoc:
9 @events.clear if @events
16 def register_event(event)
17 (@events ||= []) << event
20 def determine_event(verb, path, if_nil = :present_error)
21 event = events.find(method(if_nil)) do |e|
22 e.verb == verb && e.recognize(path)
27 determine_event(:get, '404', :not_found)
31 Event.new(:get, 'not_found', false) do
34 if request.path_info == '/' && request.request_method == 'GET'
35 erb :default_index, :views_directory => SINATRA_ROOT + '/files'
37 erb :not_found, :views_directory => SINATRA_ROOT + '/files'
46 cattr_accessor :logger
47 cattr_accessor :after_filters
48 cattr_accessor :before_filters
52 self.before_filters = []
53 self.after_filters = []
55 def self.before_attend(method_name = nil, &block)
56 setup_filter(:before_filters, method_name, &block)
59 def self.after_attend(method_name = nil, &block)
60 setup_filter(:after_filters, method_name, &block)
63 def self.setup_filter(filter_set_name, method_name, &block)
64 raise "Must specify method or block" if method_name.nil? and !block_given?
65 send(filter_set_name) << if block_given?
72 after_attend :log_event
74 attr_reader :path, :verb
76 def initialize(verb, path, register = true, &block)
79 @route = Route.new(path)
81 EventManager.register_event(self) if register
85 request.params.merge!(@route.params)
86 context = EventContext.new(request)
88 caught = catch(:halt) do
89 call_filters(before_filters, context)
92 when :filter_chain_completed
94 context.instance_eval(&@block) if @block
103 context.status caught
105 context.body context.body || body || ''
106 call_filters(after_filters, context)
113 @route.recognize(path)
119 if Options.use_mutex?
120 @@mutex.synchronize do
129 # calls a filter chain according to rules.
130 def call_filters(filter_set, context)
131 filter_set.each do |filter|
136 context.instance_eval(&filter)
139 :filter_chain_completed
144 class StaticEvent < Event # :nodoc:
146 def initialize(path, root, register = true)
148 super(:get, path, register)
152 filename = physical_path_for(path)
153 File.exists?(filename) && File.file?(filename)
156 def physical_path_for(path)
157 path.gsub(/^#{@path}/, @root)
161 @filename = physical_path_for(request.path_info)
162 context = EventContext.new(request)
164 context.header 'Content-Type' => MIME_TYPES[File.extname(@filename)[1..-1]]
165 context.header 'Content-Length' => File.size(@filename).to_s
170 File.open(@filename, "rb") do |file|
171 while part = file.read(8192)
180 "ai" => "application/postscript",
181 "asc" => "text/plain",
182 "avi" => "video/x-msvideo",
183 "bin" => "application/octet-stream",
184 "bmp" => "image/bmp",
185 "class" => "application/octet-stream",
186 "cer" => "application/pkix-cert",
187 "crl" => "application/pkix-crl",
188 "crt" => "application/x-x509-ca-cert",
189 #"crl" => "application/x-pkcs7-crl",
191 "dms" => "application/octet-stream",
192 "doc" => "application/msword",
193 "dvi" => "application/x-dvi",
194 "eps" => "application/postscript",
195 "etx" => "text/x-setext",
196 "exe" => "application/octet-stream",
197 "gif" => "image/gif",
198 "htm" => "text/html",
199 "html" => "text/html",
200 "jpe" => "image/jpeg",
201 "jpeg" => "image/jpeg",
202 "jpg" => "image/jpeg",
203 "lha" => "application/octet-stream",
204 "lzh" => "application/octet-stream",
205 "mov" => "video/quicktime",
206 "mpe" => "video/mpeg",
207 "mpeg" => "video/mpeg",
208 "mpg" => "video/mpeg",
209 "pbm" => "image/x-portable-bitmap",
210 "pdf" => "application/pdf",
211 "pgm" => "image/x-portable-graymap",
212 "png" => "image/png",
213 "pnm" => "image/x-portable-anymap",
214 "ppm" => "image/x-portable-pixmap",
215 "ppt" => "application/vnd.ms-powerpoint",
216 "ps" => "application/postscript",
217 "qt" => "video/quicktime",
218 "ras" => "image/x-cmu-raster",
219 "rb" => "text/plain",
220 "rd" => "text/plain",
221 "rtf" => "application/rtf",
222 "sgm" => "text/sgml",
223 "sgml" => "text/sgml",
224 "tif" => "image/tiff",
225 "tiff" => "image/tiff",
226 "txt" => "text/plain",
227 "xbm" => "image/x-xbitmap",
228 "xls" => "application/vnd.ms-excel",
230 "xpm" => "image/x-xpixmap",
231 "xwd" => "image/x-xwindowdump",
232 "zip" => "application/zip",