about summary refs log tree commit homepage
path: root/lib/mongrel.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mongrel.rb')
-rw-r--r--lib/mongrel.rb63
1 files changed, 40 insertions, 23 deletions
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 9c7a804..59402cc 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -5,7 +5,6 @@ require 'stringio'
 require 'mongrel/cgi'
 require 'mongrel/handlers'
 require 'mongrel/command'
-require 'timeout'
 require 'mongrel/tcphack'
 require 'yaml'
 
@@ -256,11 +255,15 @@ module Mongrel
     # Receives a block passing it the header and body for you to work with.
     # When the block is finished it writes everything you've done to
     # the socket in the proper order.  This lets you intermix header and
-    # body content as needed.
-    def start(status=200)
+    # body content as needed.  Handlers are able to modify pretty much
+    # any part of the request in the chain, and can stop further processing
+    # by simple passing "finalize=true" to the start method.  By default
+    # all handlers run and then mongrel finalizes the request when they're
+    # all done.
+    def start(status=200, finalize=false)
       @status = status.to_i
       yield @header, @body
-      finished
+      finished if finalize
     end
 
     # Primarily used in exception handling to reset the response output in order to write
@@ -268,7 +271,7 @@ module Mongrel
     # sent the header or the body.  This is pretty catastrophic actually.
     def reset
       if @body_sent
-        raise "You ahve already sent the request body."
+        raise "You have already sent the request body."
       elsif @header_sent
         raise "You have already sent the request headers."
       else
@@ -278,23 +281,29 @@ module Mongrel
     end
 
     def send_status
-      status = "HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length: #{@body.length}\r\nConnection: close\r\n"
-      @socket.write(status)
-      @status_sent = true
+      if not @status_sent
+        status = "HTTP/1.1 #{@status} #{HTTP_STATUS_CODES[@status]}\r\nContent-Length: #{@body.length}\r\nConnection: close\r\n"
+        @socket.write(status)
+        @status_sent = true
+      end
     end
 
     def send_header
-      @header.out.rewind
-      @socket.write(@header.out.read)
-      @socket.write("\r\n")
-      @header_sent = true
+      if not @header_sent
+        @header.out.rewind
+        @socket.write(@header.out.read)
+        @socket.write("\r\n")
+        @header_sent = true
+      end
     end
 
     def send_body
-      @body.rewind
-      # connection: close is also added to ensure that the client does not pipeline.
-      @socket.write(@body.read)
-      @body_sent = true
+      if not @body_sent
+        @body.rewind
+        # connection: close is also added to ensure that the client does not pipeline.
+        @socket.write(@body.read)
+        @body_sent = true
+      end
     end
 
     # This takes whatever has been done to header and body and then writes it in the
@@ -306,7 +315,7 @@ module Mongrel
     end
 
     def done
-      @status_sent && @header_sent && @body_sent
+      (@status_sent and @header_sent and @body_sent)
     end
   end
   
@@ -332,6 +341,7 @@ module Mongrel
   class HttpServer
     attr_reader :acceptor
     attr_reader :workers
+    attr_reader :classifier
 
     # Creates a working server on host:port (strange things happen if port isn't a Number).
     # Use HttpServer::run to start the server and HttpServer.acceptor.join to
@@ -387,6 +397,10 @@ module Mongrel
                 break if response.done
               end
 
+              if not response.done
+                response.finished
+              end
+
             else
               client.write(Const::ERROR_404_RESPONSE)
             end
@@ -482,11 +496,14 @@ module Mongrel
     def register(uri, handler)
       script_name, path_info, handlers = @classifier.resolve(uri)
 
-      if not handlers or (path_info and path_info != "/" and path_info.length == 0)
-        # new uri that is just longer
+      if not handlers
         @classifier.register(uri, [handler])
       else
-        handlers << handler
+        if path_info.length == 0 or (script_name == "/" and path_info == "/")
+          handlers << handler
+        else
+          @classifier.register(uri, [handler])
+        end
       end
     end
 
@@ -745,9 +762,9 @@ module Mongrel
       MongrelDbg.begin_trace :rails
       MongrelDbg.begin_trace :files
       
-      uri "/", :handler => plugin("/handlers/requestlog::files")
-      uri "/", :handler => plugin("/handlers/requestlog::objects")
-      uri "/", :handler => plugin("/handlers/requestlog::params")
+      uri location, :handler => plugin("/handlers/requestlog::files")
+      uri location, :handler => plugin("/handlers/requestlog::objects")
+      uri location, :handler => plugin("/handlers/requestlog::params")
     end