diff options
author | Eric Wong <normalperson@yhbt.net> | 2009-10-02 20:44:03 -0700 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2009-10-02 21:21:28 -0700 |
commit | 37a12997628fcab722512f8a6370b92d44e33529 (patch) | |
tree | 9ced4ceaee3d4d6ce21dd1742f037d1d79a01e61 /lib/rainbows/revactor | |
download | rainbows-37a12997628fcab722512f8a6370b92d44e33529.tar.gz |
No tests yet, but the old "gossamer" and "rainbows" branches seem to be basically working.
Diffstat (limited to 'lib/rainbows/revactor')
-rw-r--r-- | lib/rainbows/revactor/tee_input.rb | 44 |
1 files changed, 44 insertions, 0 deletions
diff --git a/lib/rainbows/revactor/tee_input.rb b/lib/rainbows/revactor/tee_input.rb new file mode 100644 index 0000000..92effb4 --- /dev/null +++ b/lib/rainbows/revactor/tee_input.rb @@ -0,0 +1,44 @@ +# -*- encoding: binary -*- +require 'rainbows/revactor' + +module Rainbows + module Revactor + + # acts like tee(1) on an input input to provide a input-like stream + # while providing rewindable semantics through a File/StringIO + # backing store. On the first pass, the input is only read on demand + # so your Rack application can use input notification (upload progress + # and like). This should fully conform to the Rack::InputWrapper + # specification on the public API. This class is intended to be a + # strict interpretation of Rack::InputWrapper functionality and will + # not support any deviations from it. + class TeeInput < ::Unicorn::TeeInput + + private + + # tees off a +length+ chunk of data from the input into the IO + # backing store as well as returning it. +dst+ must be specified. + # returns nil if reading from the input returns nil + def tee(length, dst) + unless parser.body_eof? + begin + if parser.filter_body(dst, buf << socket.read).nil? + @tmp.write(dst) + return dst + end + rescue EOFError + end + end + finalize_input + end + + def finalize_input + while parser.trailers(req, buf).nil? + buf << socket.read + end + self.socket = nil + end + + end + end +end |