diff options
author | why <why@19e92222-5c0b-0410-8929-a290d50e31e9> | 2006-04-11 00:00:52 +0000 |
---|---|---|
committer | why <why@19e92222-5c0b-0410-8929-a290d50e31e9> | 2006-04-11 00:00:52 +0000 |
commit | 3cf03ae9f3f12c5dd754f4d02cd9086fe804e0c2 (patch) | |
tree | 2446e1c29383603bb1fdc9d9c1d44990f421dfe2 /lib | |
parent | 894f4a0bd3407d99b779e739ef3c8c42c64bd4b1 (diff) | |
download | unicorn-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.rb | 28 | ||||
-rw-r--r-- | lib/mongrel/camping.rb | 19 | ||||
-rw-r--r-- | lib/mongrel/handlers.rb | 23 |
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) |