diff options
author | Eric Wong <normalperson@yhbt.net> | 2010-08-17 08:35:03 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2010-08-17 08:41:15 +0000 |
commit | ac05e7035e1946b78ce4679548db7680aa01734c (patch) | |
tree | 1379997b2686b9fa777216ad06f1ffe9be5b6027 /lib/rainbows | |
parent | 9c5669e232f8f57c2d8e08d84e21bf09cd87bfa1 (diff) | |
download | rainbows-ac05e7035e1946b78ce4679548db7680aa01734c.tar.gz |
First off we use an FD_MAP to avoid creating redundant IO objects which map to the same FD. When that doesn't work, we'll fall back to trapping Errno::EBADF and IOError where appropriate.
Diffstat (limited to 'lib/rainbows')
-rw-r--r-- | lib/rainbows/dev_fd_response.rb | 4 | ||||
-rw-r--r-- | lib/rainbows/response/body.rb | 8 |
2 files changed, 10 insertions, 2 deletions
diff --git a/lib/rainbows/dev_fd_response.rb b/lib/rainbows/dev_fd_response.rb index 637bcc2..7f70b8e 100644 --- a/lib/rainbows/dev_fd_response.rb +++ b/lib/rainbows/dev_fd_response.rb @@ -14,7 +14,8 @@ class Rainbows::DevFdResponse < Struct.new(:app) # :stopdoc: - # + FD_MAP = Rainbows::FD_MAP + # make this a no-op under Rubinius, it's pointless anyways # since Rubinius doesn't have IO.copy_stream def self.new(app) @@ -37,6 +38,7 @@ class Rainbows::DevFdResponse < Struct.new(:app) headers = HeaderHash.new(headers) st = io.stat fileno = io.fileno + FD_MAP[fileno] = io if st.file? headers['Content-Length'] ||= st.size.to_s headers.delete('Transfer-Encoding') diff --git a/lib/rainbows/response/body.rb b/lib/rainbows/response/body.rb index cf14f08..2535374 100644 --- a/lib/rainbows/response/body.rb +++ b/lib/rainbows/response/body.rb @@ -30,6 +30,12 @@ module Rainbows::Response::Body # :nodoc: ALIASES = {} + FD_MAP = Rainbows::FD_MAP + + def io_for_fd(fd) + FD_MAP.delete(fd) || IO.new(fd) + end + # to_io is not part of the Rack spec, but make an exception here # since we can conserve path lookups and file descriptors. # \Rainbows! will never get here without checking for the existence @@ -41,7 +47,7 @@ module Rainbows::Response::Body # :nodoc: # try to take advantage of Rainbows::DevFdResponse, calling File.open # is a last resort path = body.to_path - path =~ %r{\A/dev/fd/(\d+)\z} ? IO.new($1.to_i) : File.open(path) + path =~ %r{\A/dev/fd/(\d+)\z} ? io_for_fd($1.to_i) : File.open(path) end end |