diff options
-rw-r--r-- | Rakefile | 2 | ||||
-rw-r--r-- | doc/site/src/default.template | 9 | ||||
-rw-r--r-- | doc/site/src/news.page | 30 | ||||
-rw-r--r-- | lib/mongrel.rb | 18 | ||||
-rw-r--r-- | lib/mongrel/handlers.rb | 9 | ||||
-rw-r--r-- | projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb | 38 |
6 files changed, 66 insertions, 40 deletions
@@ -85,6 +85,7 @@ task :install do sh %{rake package} sh %{gem install pkg/mongrel-#{version}} sub_project("mongrel_status", :install) + sub_project("mongrel_upload_progress", :install) sub_project("mongrel_console", :install) if RUBY_PLATFORM =~ /mswin/ sub_project("mongrel_service", :install) @@ -93,6 +94,7 @@ end task :uninstall => [:clean] do sub_project("mongrel_status", :uninstall) + sub_project("mongrel_upload_progress", :uninstall) sub_project("mongrel_console", :uninstall) sh %{gem uninstall mongrel} sub_project("gem_plugin", :uninstall) diff --git a/doc/site/src/default.template b/doc/site/src/default.template index c369aae..122f078 100644 --- a/doc/site/src/default.template +++ b/doc/site/src/default.template @@ -46,6 +46,15 @@ <h4>NEWS</h4> <dl> + <dt>Jun-25-2006</dt> + <dd> + <h5><a href="{relocatable: news.html}">Mongrel 0.3.13.2 -- RailsConf 2006 Release</a></h5> + + <p>Release from RailsConf that does Upload Progress and defending better.</p> + <a href="{relocatable: news.html}" title="Read About It">Read About It</a> + <a href="{relocatable: news.html}"><img src="{relocatable: images/li4.gif}" alt="more" /><br /></a></p> + </dd> + <dt>Jun-20-2006</dt> <dd> <h5><a href="{relocatable: news.html}">Mongrel 0.3.13.1 Small Bug Fixes</a></h5> diff --git a/doc/site/src/news.page b/doc/site/src/news.page index 8feb00a..dae4e27 100644 --- a/doc/site/src/news.page +++ b/doc/site/src/news.page @@ -7,7 +7,35 @@ ordering: 2 h1. Latest News -h2. Jun 20: Mongrel 0.3.13.2 -- Small Fixes +h2. Jun 25: Mongrel 0.3.13.2 -- RailsConf 2006 Release + +This is the release that came out of RailsConf hacking with folks like Rick +Olsen, Why The Luck Stiff and other incredibly cool folks. The conference +was great, so lets hope this release is good too. The big thing it adds +is *upload progress in Mongrel*. That's right, Why and Rick pinned me down +and made me put it in Mongrel. They worked up the mongrel_upload_progress +plugin and are now working on Rails and Camping code to make it happen. + +Install from the gem servers with your usual commands: + + gem update + + *or* + + gem update mongrel + + *or* + + gem install mongrel + +But if you can't wait for the gem mirrors to update, then you can also do: + + gem install mongrel --source=http://mongrel.rubyforge.org/releases + +To get around it all. + + +h2. Jun 20: Mongrel 0.3.13.2 Pre-Release -- Small Fixes This is a small release that fixes a little bug, some of the documentation, and adds the new RedirectHandler code and a @redirect@ call for the mongrel.conf diff --git a/lib/mongrel.rb b/lib/mongrel.rb index 08417e9..55aaa39 100644 --- a/lib/mongrel.rb +++ b/lib/mongrel.rb @@ -184,7 +184,12 @@ module Mongrel # # The HttpRequest.initialize method will convert any request that is larger than # Const::MAX_BODY into a Tempfile and use that as the body. Otherwise it uses - # a StringIO object. To be safe, you should assume it works like a file. + # a StringIO object. To be safe, you should assume it works like a file. + # + # The HttpHandler.request_notify system is implemented by having HttpRequest call + # HttpHandler.request_begins, HttpHandler.request_progress, HttpHandler.process during + # the IO processing. This adds a small amount of overhead but lets you implement + # finer controlled handlers and filters. class HttpRequest attr_reader :body, :params @@ -209,9 +214,11 @@ module Mongrel begin @body.write(initial_body) + notifier.request_begins(params) if notifier # write the odd sized chunk first clen -= @body.write(@socket.read(clen % Const::CHUNK_SIZE)) + notifier.request_progress(params, clen, total) if notifier # then stream out nothing but perfectly sized chunks while clen > 0 and !@socket.closed? @@ -227,7 +234,6 @@ module Mongrel @body.rewind rescue Object # any errors means we should delete the file, including if the file is dumped - STDERR.puts "ERROR: #$!" @socket.close unless @socket.closed? @body.delete if @body.class == Tempfile @body = nil # signals that there was a problem @@ -539,17 +545,11 @@ module Mongrel params[Const::PATH_INFO] = path_info params[Const::SCRIPT_NAME] = script_name params[Const::REMOTE_ADDR] = params[Const::HTTP_X_FORWARDED_FOR] || client.peeraddr.last - notifier = nil + notifier = handlers[0].request_notify ? handlers[0] : nil # TODO: Find a faster/better way to carve out the range, preferably without copying. data = data[nparsed ... data.length] || "" - if handlers[0].request_notify - # this first handler wants to be notified when the process starts - notifier = handlers[0] - notifier.request_begins(params) - end - request = HttpRequest.new(params, data, client, notifier) # in the case of large file uploads the user could close the socket, so skip those requests diff --git a/lib/mongrel/handlers.rb b/lib/mongrel/handlers.rb index f7f7e74..2a72ebd 100644 --- a/lib/mongrel/handlers.rb +++ b/lib/mongrel/handlers.rb @@ -41,6 +41,12 @@ module Mongrel def request_begins(params) end + # Called by Mongrel for each IO chunk that is received on the request socket + # from the client, allowing you to track the progress of the IO and monitor + # the input. + def request_progress(params, clen, total) + end + def process(request, response) end @@ -59,6 +65,9 @@ module Mongrel def request_begins(params) end + def request_progress(params, clen, total) + end + def initialize(options={}) @options = options @header_only = false 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 a1bd0f8..bbdc649 100644 --- a/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb +++ b/projects/mongrel_upload_progress/lib/mongrel_upload_progress/init.rb @@ -1,8 +1,7 @@ require 'mongrel' require 'gem_plugin' -require File.join(File.dirname(__FILE__), 'progress') -class Uploads +class Mongrel::Uploads include Singleton def initialize @@ -38,52 +37,31 @@ class Uploads end end -class Progress < GemPlugin::Plugin "/handlers" - include Mongrel::HttpHandlerPlugin - - def initialize(options) - end - - def process(request, response) - 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] + @path_info = options[:path_info] @request_notify = true end def request_begins(params) - upload_notify(:add, params, params[Const::CONTENT_LENGTH].to_i) + upload_notify(:add, params, params[Mongrel::Const::CONTENT_LENGTH].to_i) if params['PATH_INFO'] == @path_info end def request_progress(params, clen, total) - upload_notify(:mark, params, clen) + upload_notify(:mark, params, clen) if params['PATH_INFO'] == @path_info end def process(request, response) - upload_notify(:finish, request.params) + upload_notify(:finish, request.params) if request.params['PATH_INFO'] == @path_info 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 + upload_id = Mongrel::HttpRequest.query_parse(params['QUERY_STRING'])['upload_id'] + if params[Mongrel::Const::REQUEST_METHOD] == 'POST' && upload_id + Mongrel::Uploads.instance.send(action, upload_id, *args) if upload_id end end end |