about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-05-23 03:58:37 +0000
committerzedshaw <zedshaw@19e92222-5c0b-0410-8929-a290d50e31e9>2006-05-23 03:58:37 +0000
commit25f477099bc025e95e423a713c9f5e3b29b3d4e5 (patch)
treeb284ac466828c63d0ca7748e4f40f707dba70e87
parent4905d82fc0f96a79f2d3a5d9eaf93c1112684d7c (diff)
downloadunicorn-25f477099bc025e95e423a713c9f5e3b29b3d4e5.tar.gz
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@206 19e92222-5c0b-0410-8929-a290d50e31e9
-rw-r--r--bin/mongrel_rails9
-rw-r--r--lib/mongrel.rb3
-rw-r--r--lib/mongrel/handlers.rb29
-rw-r--r--projects/mongrel_upload_progress/Rakefile1
-rw-r--r--projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb116
-rw-r--r--projects/mongrel_upload_progress/resources/defaults.yaml1
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