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