lib/upr/input_wrapper.rb in upr-0.1.0 vs lib/upr/input_wrapper.rb in upr-0.2.0

- old
+ new

@@ -7,14 +7,16 @@ # that may wrap env["rack.input"] in the middleware chain. class InputWrapper < Struct.new(:app, :path_info, :frequency, :backend, :input, :pos, :seen, :content_length, :upload_id, :mtime) + include Params + def initialize(app, options = {}) super(app, Array(options[:path_info] || nil), - options[:frequency] || 3, + options[:frequency] || 1, options[:backend]) # support :drb for compatibility with mongrel_upload_progress if options[:drb] backend and raise ArgumentError, ":backend and :drb are incompatible" @@ -34,27 +36,22 @@ if path_info.empty? || path_info.include?(env["PATH_INFO"]) # benefit curl users... /\A100-continue\z/i =~ env['HTTP_EXPECT'] and return [ 100, {}, [] ] length = env["CONTENT_LENGTH"] and length = length.to_i - env["TRANSFER_ENCODING"] =~ %r{\Achunked\z}i and length = nil - if length.nil? || length > 0 - req = Rack::Request.new(env) - - # can't blindly parse params here since we don't want to read - # the POST body if there is one, so only parse stuff in the - # query string... - if uid = req.GET["upload_id"] + chunked = env["TRANSFER_ENCODING"] =~ %r{\Achunked\z}i and length = nil + if chunked || (length && length > 0) + if uid = extract_upload_id(env) return dup._call(env, uid, length) end end end app.call(env) end def _call(env, uid, length) - self.upload_id = env["upr.upload_id"] = uid + self.upload_id = uid self.mtime = self.pos = self.seen = 0 self.input = env["rack.input"] env["rack.input"] = self self.content_length = length backend.start(upload_id, length) @@ -62,24 +59,30 @@ app.call(env) end def _incr(nr) self.pos += nr + _finish if content_length && pos >= content_length if (nr = pos - seen) > 0 && mtime <= (Time.now.to_i - frequency) backend.incr(upload_id, nr) self.seen = pos self.mtime = Time.now.to_i end end + def _finish + self.seen = backend.finish(upload_id).seen + self.content_length ||= self.seen + end + def size rv = input.size # we had an unknown length and just had to read in everything to get it if content_length.nil? _incr(rv - seen) - self.content_length = rv + _finish end rv end def rewind @@ -87,24 +90,25 @@ input.rewind end def gets rv = input.gets - _incr(rv.size) unless rv.nil? + rv.nil? ? _finish : _incr(rv.size) rv end def read(*args) rv = input.read(*args) - _incr(rv.size) unless rv.nil? + rv.nil? || rv.size == 0 ? _finish : _incr(rv.size) rv end def each(&block) input.each do |chunk| # usually just a line _incr(chunk.size) yield chunk end + _finish end end end