From 25f477099bc025e95e423a713c9f5e3b29b3d4e5 Mon Sep 17 00:00:00 2001 From: zedshaw Date: Tue, 23 May 2006 03:58:37 +0000 Subject: PID file wiping is now stopped, and also allows to run a debug without wiping the PID file. git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@206 19e92222-5c0b-0410-8929-a290d50e31e9 --- bin/mongrel_rails | 9 +- lib/mongrel.rb | 3 +- lib/mongrel/handlers.rb | 29 ++++++ projects/mongrel_upload_progress/Rakefile | 1 + .../lib/mongrel_upload_progress/init.rb | 116 ++++++++++++++++++++- .../resources/defaults.yaml | 1 + 6 files changed, 154 insertions(+), 5 deletions(-) diff --git a/bin/mongrel_rails b/bin/mongrel_rails index b6ba92f..4886e6e 100644 --- a/bin/mongrel_rails +++ b/bin/mongrel_rails @@ -142,8 +142,13 @@ class Start < GemPlugin::Plugin "/commands" config.run config.log "Mongrel available at #{settings[:host]}:#{settings[:port]}" - config.log "Use CTRL-C to stop." if not @daemon - config.write_pid_file + + if not @daemon + config.log "Use CTRL-C to stop." + else + config.write_pid_file + end + config.join if config.needs_restart diff --git a/lib/mongrel.rb b/lib/mongrel.rb index a3e4fec..599bf2b 100644 --- a/lib/mongrel.rb +++ b/lib/mongrel.rb @@ -713,7 +713,8 @@ module Mongrel @listeners = {} @defaults = defaults @needs_restart = false - + @pid_file = defaults[:pid_file] + change_privilege(@defaults[:user], @defaults[:group]) if blk diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb index cccf365..1134bdf 100644 --- a/lib/mongrel/handlers.rb +++ b/lib/mongrel/handlers.rb @@ -28,6 +28,7 @@ module Mongrel # should be implemented using the HttpHandlerPlugin mixin. # class HttpHandler + attr_reader :header_only def process(request, response) end @@ -40,9 +41,11 @@ module Mongrel # the process method later. module HttpHandlerPlugin attr_reader :options + attr_reader :header_only def initialize(options={}) @options = options + @header_only = false end def process(request, response) @@ -261,4 +264,30 @@ module Mongrel end end + + + # When added to a config script (-S in mongrel_rails) it will + # look at the client's allowed response types and then gzip + # compress anything that is going out. + class DeflateCompressFilter < HttpHandler + HTTP_ACCEPT_ENCODING = "HTTP_ACCEPT_ENCODING" + + def initialize(ops) + @options = ops + end + + def process(request, response) + accepts = request.params[HTTP_ACCEPT_ENCODING] + # only process if they support compression + if accepts.include? "gzip" or accepts.include? "deflate" and not response.body_sent + head["Content-Encoding"] = "deflate" + # we can't just rewind the body and gzip it since the body could be an attached file + response.body.rewind + gzout << Zlib::Deflate.deflate(response.body.read) + gzout.rewind + response.body.close + response.body = gzout + end + end + end end diff --git a/projects/mongrel_upload_progress/Rakefile b/projects/mongrel_upload_progress/Rakefile index 7922206..9eae683 100644 --- a/projects/mongrel_upload_progress/Rakefile +++ b/projects/mongrel_upload_progress/Rakefile @@ -22,6 +22,7 @@ setup_gem(name, version) do |spec| spec.summary = "The mongrel_upload_progress GemPlugin" spec.description = spec.summary spec.author="Nobody" + spec.add_dependency('mongrel', '>= 0.3.13') spec.add_dependency('gem_plugin', '>= 0.2.1') spec.files += Dir.glob("resources/**/*") end 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 8eaad23..0bd0aae 100644 --- a/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb +++ b/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb @@ -1,6 +1,118 @@ +require 'mongrel' require 'gem_plugin' +require File.join(File.dirname(__FILE__), 'progress') -# give this class the name you want for your command mongrel_upload_progress -class ChangeME < GemPlugin::Plugin "/somecategory" + +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 Progress < GemPlugin::Plugin "/handlers" + include Mongrel::HttpHandlerPlugin + + def initialize(options) + 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| + out.write write_status(status, qs['upload_id']) + end + end + + protected + def write_status(status, upload_id) + status ? ([status['size'], status['received']] * ',') : "no status for #{upload_id}" + end end +class Upload < GemPlugin::Plugin "/handlers" + include Mongrel::HttpHandlerPlugin + + def initialize(options = {}) + @upload_path = options[:upload_path] || 'tmp/uploads' + @redirect_url = options[:redirect_url] + 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 + 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 + 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 + end + end +end diff --git a/projects/mongrel_upload_progress/resources/defaults.yaml b/projects/mongrel_upload_progress/resources/defaults.yaml index 10d2a47..beb3c6d 100644 --- a/projects/mongrel_upload_progress/resources/defaults.yaml +++ b/projects/mongrel_upload_progress/resources/defaults.yaml @@ -1,2 +1,3 @@ --- :debug: false +:upload_path: 'tmp/uploads' \ No newline at end of file -- cgit v1.2.3-24-ge0c7