mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Mongrel gets some hooks to help with upload progress.
git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@260 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
parent
49856e52b0
commit
f26ffd1a91
6 changed files with 66 additions and 40 deletions
2
Rakefile
2
Rakefile
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue