diff options
author | why <why@19e92222-5c0b-0410-8929-a290d50e31e9> | 2006-06-25 04:54:43 +0000 |
---|---|---|
committer | why <why@19e92222-5c0b-0410-8929-a290d50e31e9> | 2006-06-25 04:54:43 +0000 |
commit | 49856e52b045cac75e064e498e68ce3cfa48026c (patch) | |
tree | 164e17749798c79f1f15b459f157a7a6e031331d | |
parent | bd2106601addb084d169da5899cbb24ff2452e66 (diff) | |
download | unicorn-49856e52b045cac75e064e498e68ce3cfa48026c.tar.gz |
* mongrel_upload_progress/lib/mongrel_upload_progress/progress.rb: ditto. git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@259 19e92222-5c0b-0410-8929-a290d50e31e9
-rw-r--r-- | projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb | 57 | ||||
-rw-r--r-- | projects/mongrel_upload_progress/lib/mongrel_upload_progress/progress.rb | 87 |
2 files changed, 14 insertions, 130 deletions
diff --git a/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb b/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb index 0bd0aae..a1bd0f8 100644 --- a/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb +++ b/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb @@ -2,7 +2,6 @@ require 'mongrel' require 'gem_plugin' require File.join(File.dirname(__FILE__), 'progress') - class Uploads include Singleton @@ -46,14 +45,6 @@ class Progress < GemPlugin::Plugin "/handlers" end def process(request, response) - if params[Const::REQUEST_METHOD] == 'POST' - qs = self.class.query_parse(params['QUERY_STRING']) - if qs['upload_id'] and not qs['upload_id'].empty? - upload_id = qs['upload_id'] - Uploads.instance.add(upload_id, clen) if upload_id - end - end - qs = Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING']) status = Mongrel::Uploads.instance.check(qs['upload_id']) response.start 200 do |head, out| @@ -73,46 +64,26 @@ class Upload < GemPlugin::Plugin "/handlers" def initialize(options = {}) @upload_path = options[:upload_path] || 'tmp/uploads' @redirect_url = options[:redirect_url] + @request_notify = true end - def process(request, response) - @cgi = nil - @files = [] - qs = Mongrel::HttpRequest.query_parse(request.params['QUERY_STRING']) - if request.params[Mongrel::Const::REQUEST_METHOD] == 'POST' && qs['upload_id'] - save_file(request, response, qs['upload_id']) - process_upload(request, response, qs['upload_id']) - else - response.start(204) {} - end + def request_begins(params) + upload_notify(:add, params, params[Const::CONTENT_LENGTH].to_i) end - protected - # Called when a file has been uploaded. - def process_upload(request, response, upid) - if @redirect_url - response.start 302 do |head, out| - location = '%s%supload_id=%s' % [@redirect_url, (@redirect_url =~ /\?/ ? '&' : '?'), upid] - head['Location'] = @files.inject(location) { |loc, file| loc << "&file[]=#{file}" } - end - else - response.start(200) { |h, o| o.write "Successfully uploaded #{@files * ', '}."} - end + def request_progress(params, clen, total) + upload_notify(:mark, params, clen) + end + + def process(request, response) + upload_notify(:finish, request.params) end - def save_file(request, response, upid) - @cgi = Mongrel::CGIWrapper.new(request, response) - @cgi.handler = self - - @cgi.params['data'].each_with_index do |data, i| - @files << data.original_filename - upload_file = File.join(@upload_path, [upid, i, @files.last] * '.') - FileUtils.mkdir_p(@upload_path) - if data.is_a?(Tempfile) - FileUtils.cp data.path, upload_file - else - File.open(upload_file, 'wb') { |f| f.write data.read } - end + private + def upload_notify(action, params, *args) + upload_id = params['upload_id'] + if params[Const::REQUEST_METHOD] == 'POST' && upload_id + Uploads.instance.send(action, upload_id, *args) if upload_id end end end diff --git a/projects/mongrel_upload_progress/lib/mongrel_upload_progress/progress.rb b/projects/mongrel_upload_progress/lib/mongrel_upload_progress/progress.rb deleted file mode 100644 index 533bd19..0000000 --- a/projects/mongrel_upload_progress/lib/mongrel_upload_progress/progress.rb +++ /dev/null @@ -1,87 +0,0 @@ -module Mongrel - class Uploads - include Singleton - - def initialize - @guard = Mutex.new - @counters = {} - end - - def check(upid) - @counters[upid] - end - - def add(upid, size) - stats = {'size' => size, 'received' => 0} - @guard.synchronize do - @counters[upid] = stats - end - end - - def mark(upid, len) - upload = @counters[upid] - recvd = upload['size'] - len - @guard.synchronize do - upload['received'] = recvd - end - end - - def finish(upid) - upload = @counters[upid] - recvd = upload['size'] - @guard.synchronize do - upload['received'] = recvd - end - end - end - - class HttpRequest - def initialize(params, initial_body, socket) - @params = params - @socket = socket - - clen = params[Const::CONTENT_LENGTH].to_i - initial_body.length - upload_id = nil - - if params[Const::REQUEST_METHOD] == 'POST' - qs = self.class.query_parse(params['QUERY_STRING']) - if qs['upload_id'] and not qs['upload_id'].empty? - upload_id = qs['upload_id'] - Uploads.instance.add(upload_id, clen) if upload_id - end - end - - if clen > Const::MAX_BODY - @body = Tempfile.new(self.class.name) - @body.binmode - else - @body = StringIO.new - end - - begin - @body.write(initial_body) - - # write the odd sized chunk first - clen -= @body.write(@socket.read(clen % Const::CHUNK_SIZE)) - - # then stream out nothing but perfectly sized chunks - while clen > 0 - data = @socket.read(Const::CHUNK_SIZE) - # have to do it this way since @socket.eof? causes it to block - raise "Socket closed or read failure" if not data or data.length != Const::CHUNK_SIZE - clen -= @body.write(data) - Uploads.instance.mark(upload_id, clen) if upload_id - end - - # rewind to keep the world happy - Uploads.instance.finish(upload_id) if upload_id - @body.rewind - rescue Object - # any errors means we should delete the file, including if the file is dumped - STDERR.puts "Error reading request: #$!" - @body.delete if @body.class == Tempfile - @body = nil # signals that there was a problem - end - end - end -end
\ No newline at end of file |