lib/merb/merb_handler.rb in merb-0.3.4 vs lib/merb/merb_handler.rb in merb-0.3.7
- old
+ new
@@ -7,48 +7,46 @@
@status_sent = true
end
end
end
-
-
class MerbHandler < Mongrel::HttpHandler
@@file_only_methods = ["GET","HEAD"]
- # take the name of a directory and use that as the doc root or public
+ # Take the name of a directory and use that as the doc root or public
# directory of your site. This is set to the root of your merb app + '/public'
# by default.
def initialize(dir, opts = {})
@files = Mongrel::DirHandler.new(dir,false)
end
# process incoming http requests and do a number of things
- # 1. check for rails style cached pages. add .html to the
- # url and see if there is a static file in public that matches.
- # serve that file directly without invoking Merb and be done with it.
- # 2. Serve static asset and html files directly from public/ if
- # they exist.
- # 3. If none of the above apply, we take apart the request url
- # and feed it into Merb::RouteMatcher to let it decide which
- # controller and method will serve the request.
- # 4. after the controller has done its thing, we check for the
- # X-SENDFILE header. if you set this header to the path to a file
- # in your controller then mongrel will serve the file directly
- # and your controller can go on processing other requests.
+ # 1. Check for rails style cached pages. add .html to the url and see if
+ # there is a static file in public that matches. serve that file directly
+ # without invoking Merb and be done with it.
+ # 2. Serve static asset and html files directly from public/ if they exist.
+ # 3. If none of the above apply, we take apart the request url and feed it
+ # into Merb::RouteMatcher to let it decide which controller and method will
+ # serve the request.
+ # 4. After the controller has done its thing, we check for the X-SENDFILE
+ # header. if you set this header to the path to a file in your controller
+ # then mongrel will serve the file directly and your controller can go on
+ # processing other requests.
def process(request, response)
start = Time.now
+ benchmarks = {}
if response.socket.closed?
return
end
MERB_LOGGER.info("\nRequest: REQUEST_URI: #{request.params[Mongrel::Const::REQUEST_URI]} (#{Time.now.strftime("%Y-%m-%d %H:%M:%S")})")
- # Rails style page caching. Check the public dir first for
- # .html pages and serve directly. Otherwise fall back to Merb
- # routing and request dispatching.
+ # Rails style page caching. Check the public dir first for .html pages and
+ # serve directly. Otherwise fall back to Merb routing and request
+ # dispatching.
path_info = request.params[Mongrel::Const::PATH_INFO]
page_cached = path_info + ".html"
get_or_head = @@file_only_methods.include? request.params[Mongrel::Const::REQUEST_METHOD]
if get_or_head and @files.can_serve(path_info)
@@ -63,12 +61,16 @@
else
begin
# Let Merb:Dispatcher find the route and call the filter chain and action
controller = nil
controller, action = Merb::Dispatcher.handle(request, response)
-
- MERB_LOGGER.info("Routing to controller: #{controller.class} action: #{action}\nRoute Recognition & Parsing HTTP Input took: #{Time.now - start} seconds")
+
+ benchmarks.merge!(controller._benchmarks)
+ benchmarks[:controller] = controller.class.to_s
+ benchmarks[:action] = action
+
+ MERB_LOGGER.info("Routing to controller: #{controller.class} action: #{action}\nRoute Recognition & Parsing HTTP Input took: #{benchmarks[:setup_time]} seconds")
rescue Object => e
response.start(500) do |head,out|
head["Content-Type"] = "text/html"
MERB_LOGGER.info(Merb.exception(e))
out << Merb.html_exception(e)
@@ -76,12 +78,12 @@
return
end
sendfile, clength = nil
response.status = controller.status
- # check for the X-SENDFILE header from your Merb::Controller
- # and serve the file directly instead of buffering.
+ # Check for the X-SENDFILE header from your Merb::Controller and serve
+ # the file directly instead of buffering.
controller.headers.each do |k, v|
if k =~ /^X-SENDFILE$/i
sendfile = v
elsif k =~ /^CONTENT-LENGTH$/i
clength = v.to_i
@@ -91,18 +93,19 @@
end
end
end
if sendfile
- MERB_LOGGER.info("X-SENDFILE: #{sendfile}\nComplete Request took: #{Time.now - start} seconds")
+ benchmarks[:sendfile_time] = Time.now - start
+ MERB_LOGGER.info("X-SENDFILE: #{sendfile}\nComplete Request took: #{benchmarks[:sendfile_time]} seconds")
file_status = File.stat(sendfile)
response.status = 200
# Set the last modified times as well and etag for all files
response.header[Mongrel::Const::LAST_MODIFIED] = file_status.mtime.httpdate
# Calculated the same as apache, not sure how well the works on win32
response.header[Mongrel::Const::ETAG] = Mongrel::Const::ETAG_FORMAT % [file_status.mtime.to_i, file_status.size, file_status.ino]
- # send a status with out content length
+ # Send a status with out content length
response.send_status(file_status.size)
response.send_header
response.send_file(sendfile)
elsif controller.body.respond_to? :read
response.send_status(clength)
@@ -114,16 +117,21 @@
controller.body.close
end
elsif Proc === controller.body
controller.body.call
else
- MERB_LOGGER.info("Response status: #{response.status}\nComplete Request took: #{Time.now - start} seconds\n\n")
- # render response from successful controller
+ # Render response from successful controller
body = (controller.body.to_s rescue '')
response.send_status(body.length)
response.send_header
response.write(body)
end
+
+ total_request_time = Time.now - start
+ benchmarks[:total_request_time] = total_request_time
+
+ MERB_LOGGER.info("Request Times: #{benchmarks.inspect}")
+ MERB_LOGGER.info("Response status: #{response.status}\nComplete Request took: #{total_request_time} seconds, #{1.0/total_request_time} Requests/Second\n\n")
end
end
end
\ No newline at end of file