--- lib/mongrel.rb.org 2007-01-22 21:11:56.000000000 -0600 +++ lib/mongrel.rb 2007-01-22 21:53:44.000000000 -0600 @@ -156,6 +156,7 @@ REQUEST_METHOD="REQUEST_METHOD".freeze GET="GET".freeze HEAD="HEAD".freeze + PUT="PUT".freeze # ETag is based on the apache standard of hex mtime-size-inode (inode is 0 on win32) ETAG_FORMAT="\"%x-%x-%x\"".freeze HEADER_FORMAT="%s: %s\r\n".freeze @@ -190,12 +191,13 @@ # the IO processing. This adds a small amount of overhead but lets you implement # finer controlled handlers and filters. class HttpRequest - attr_reader :body, :params + attr_reader :body, :params, :interrupted # You don't really call this. It's made for you. # Main thing it does is hook up the params, and store any remaining # body data into the HttpRequest.body attribute. def initialize(params, socket, dispatchers) + @interrupted = false @params = params @socket = socket @dispatchers = dispatchers @@ -266,8 +268,7 @@ $!.backtrace.join("\n") # any errors means we should delete the file, including if the file is dumped @socket.close rescue Object - @body.delete if @body.class == Tempfile - @body = nil # signals that there was a problem + @interrupted = true end end @@ -286,6 +287,10 @@ end end + def cleanup + @body.delete if @body.class == Tempfile && @interrupted + end + # Performs URI escaping so that you can construct proper # query strings faster. Use this rather than the cgi.rb # version since it's faster. (Stolen from Camping). @@ -607,16 +612,20 @@ notifiers = handlers.select { |h| h.request_notify } request = HttpRequest.new(params, client, notifiers) - # in the case of large file uploads the user could close the socket, so skip those requests - break if request.body == nil # nil signals from HttpRequest::initialize that the request was aborted - # request is good so far, continue processing the response response = HttpResponse.new(client) # Process each handler in registered order until we run out or one finalizes the response. - handlers.each do |handler| - handler.process(request, response) - break if response.done or client.closed? + if request.interrupted + handlers.each do |handler| + handler.process(request, nil) if handler.accept_partial_requests? + end + request.cleanup + else + handlers.each do |handler| + handler.process(request, response) + break if response.done or client.closed? + end end # And finally, if nobody closed the response off, we finalize it.