about summary refs log tree commit homepage
path: root/lib
diff options
context:
space:
mode:
authorwhy <why@19e92222-5c0b-0410-8929-a290d50e31e9>2006-04-11 00:00:52 +0000
committerwhy <why@19e92222-5c0b-0410-8929-a290d50e31e9>2006-04-11 00:00:52 +0000
commit3cf03ae9f3f12c5dd754f4d02cd9086fe804e0c2 (patch)
tree2446e1c29383603bb1fdc9d9c1d44990f421dfe2 /lib
parent894f4a0bd3407d99b779e739ef3c8c42c64bd4b1 (diff)
downloadunicorn-3cf03ae9f3f12c5dd754f4d02cd9086fe804e0c2.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@155 19e92222-5c0b-0410-8929-a290d50e31e9
Diffstat (limited to 'lib')
-rw-r--r--lib/mongrel.rb28
-rw-r--r--lib/mongrel/camping.rb19
-rw-r--r--lib/mongrel/handlers.rb23
3 files changed, 43 insertions, 27 deletions
diff --git a/lib/mongrel.rb b/lib/mongrel.rb
index 830aba1..228fd9f 100644
--- a/lib/mongrel.rb
+++ b/lib/mongrel.rb
@@ -9,6 +9,15 @@ require 'mongrel/tcphack'
 require 'yaml'
 require 'time'
 
+begin
+  require 'rubygems'
+  require 'sendfile'
+  $mongrel_has_sendfile = true
+  STDERR.puts "** You have sendfile installed, will use that to serve files."
+rescue Object
+  $mongrel_has_sendfile = false
+end
+
 # Mongrel module containing all of the classes (include C extensions) for running
 # a Mongrel web server.  It contains a minimalist HTTP server with just enough
 # functionality to service web application requests fast as possible.
@@ -324,6 +333,25 @@ module Mongrel
       end
     end
 
+    # Appends the contents of +path+ to the response stream.  The file is opened for binary
+    # reading and written in chunks to the socket.  If the
+    # <a href="http://rubyforge.org/projects/ruby-sendfile">sendfile</a> library is found,
+    # it is used to send the file, often with greater speed and less memory/cpu usage.
+    def send_file(path)
+      File.open(path, "rb") do |f|
+        if @socket.respond_to? :sendfile
+          @socket.sendfile(f)
+        else
+          while chunk = f.read(Const::CHUNK_SIZE)
+            @socket.write(chunk)
+          end
+        end
+          end
+    rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
+          # ignore these since it means the client closed off early
+        STDERR.puts "Client closed socket requesting file #{req}: #$!"
+    end
+
     def write(data)
       @socket.write(data)
     end
diff --git a/lib/mongrel/camping.rb b/lib/mongrel/camping.rb
index 26546c1..fb4efb8 100644
--- a/lib/mongrel/camping.rb
+++ b/lib/mongrel/camping.rb
@@ -34,21 +34,30 @@ module Mongrel
       def process(request, response)
         req = StringIO.new(request.body)
         controller = @klass.run(req, request.params)
+        sendfile = nil
         response.start(controller.status) do |head,out|
           controller.headers.each do |k, v|
-            [*v].each do |vi|
-              head[k] = vi
+            if k =~ /^X-SENDFILE$/i
+              sendfile = v
+            else
+              [*v].each do |vi|
+                head[k] = vi
+              end
             end
           end
-          if controller.body.respond_to? :read
+          response.send_header
+
+          if sendfile
+            response.send_file(sendfile)
+          elsif controller.body.respond_to? :read
             while chunk = controller.body.read(16384)
-              out << chunk
+              @response.write(chunk)
             end
             if controller.body.respond_to? :close
               controller.body.close
             end
           else
-            out << controller.body
+            @response.write(controller.body)
           end
         end
       end
diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb
index 6496d90..f9ad95f 100644
--- a/lib/mongrel/handlers.rb
+++ b/lib/mongrel/handlers.rb
@@ -1,12 +1,3 @@
-require 'rubygems'
-begin
-  require 'sendfile'
-  $mongrel_has_sendfile = true
-  STDERR.puts "** You have sendfile installed, will use that to serve files."
-rescue Object
-  $mongrel_has_sendfile = false
-end
-
 module Mongrel
 
   # You implement your application handler with this.  It's very light giving
@@ -188,22 +179,10 @@ module Mongrel
       response.send_header
 
       if not header_only
-        begin
-          if $mongrel_has_sendfile
-            File.open(req, "rb") { |f| response.socket.sendfile(f) }
-          else
-            File.open(req, "rb") { |f| response.socket.write(f.read) }
-          end
-        rescue EOFError,Errno::ECONNRESET,Errno::EPIPE,Errno::EINVAL,Errno::EBADF
-          # ignore these since it means the client closed off early
-          STDERR.puts "Client closed socket requesting file #{req}: #$!"
-        end
-      else
-        response.send_body # should send nothing
+        response.send_file(req)
       end
     end
 
-
     # Process the request to either serve a file or a directory listing
     # if allowed (based on the listing_allowed paramter to the constructor).
     def process(request, response)