about summary refs log tree commit homepage
path: root/lib/mongrel.rb
diff options
context:
space:
mode:
authorzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-06-15 18:14:07 +0000
committerzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-06-15 18:14:07 +0000
commit39c1bad6267bd74f5fa0a6a625b7ae48e47793fb (patch)
tree77b051222bba63c8d76425d88f3116c555f361aa /lib/mongrel.rb
parent375a0b5c5ed4316c1a1a59735f7767e2aeadaf3b (diff)
downloadunicorn-39c1bad6267bd74f5fa0a6a625b7ae48e47793fb.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@238 19e92222-5c0b-0410-8929-a290d50e31e9
Diffstat (limited to 'lib/mongrel.rb')
-rw-r--r--lib/mongrel.rb39
1 files changed, 28 insertions, 11 deletions
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index bd3bb75..6090708 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -372,7 +372,7 @@ module Mongrel
     def send_status(content_length=nil)
       if not @status_sent
         content_length ||= @body.length
-        @socket.write(Const::STATUS_FORMAT % [status, HTTP_STATUS_CODES[@status], content_length])
+        write(Const::STATUS_FORMAT % [status, HTTP_STATUS_CODES[@status], content_length])
         @status_sent = true
       end
     end
@@ -380,7 +380,7 @@ module Mongrel
     def send_header
       if not @header_sent
         @header.out.rewind
-        @socket.write(@header.out.read + Const::LINE_END)
+        write(@header.out.read + Const::LINE_END)
         @header_sent = true
       end
     end
@@ -388,7 +388,7 @@ module Mongrel
     def send_body
       if not @body_sent
         @body.rewind
-        @socket.write(@body.read)
+        write(@body.read)
         @body_sent = true
       end
     end
@@ -404,22 +404,31 @@ module Mongrel
     def send_file(path)
       File.open(path, "rb") do |f|
         if @socket.respond_to? :sendfile
-          @socket.sendfile(f)
+          begin
+            @socket.sendfile(f)
+          rescue => details
+            socket_error(details)
+          end
         else
           while chunk = f.read(Const::CHUNK_SIZE) and chunk.length > 0
-            @socket.write(chunk)
+            write(chunk)
           end
         end
-
         @body_send = true
       end
-    rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
+    end
+
+    def socket_error(details)
       # ignore these since it means the client closed off early
-      STDERR.puts "Client closed socket early requesting file #{path}: #$!"
+      @socket.close unless @socket.closed?
+      done = true
+      raise details
     end
 
     def write(data)
       @socket.write(data)
+    rescue => details
+      socket_error(details)
     end
 
     # This takes whatever has been done to header and body and then writes it in the
@@ -430,6 +439,14 @@ module Mongrel
       send_body
     end
 
+    # Used during error conditions to mark the response as "done" so there isn't any more processing
+    # sent to the client.
+    def done=(val)
+      @status_sent = true
+      @header_sent = true
+      @body_sent = true
+    end
+
     def done
       (@status_sent and @header_sent and @body_sent)
     end
@@ -530,11 +547,11 @@ module Mongrel
               # 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
+                break if response.done or client.closed?
               end
 
               # And finally, if nobody closed the response off, we finalize it.
-              if not response.done
+              unless response.done or client.closed?
                 response.finished
               end
             else
@@ -560,7 +577,7 @@ module Mongrel
         STDERR.puts "#{Time.now}: ERROR: #$!"
         STDERR.puts details.backtrace.join("\n")
       ensure
-        client.close
+        client.close unless client.closed?
       end
     end