1
0
Fork 0
mirror of https://github.com/puma/puma.git synced 2022-11-09 13:48:40 -05:00

Additional simple feature for upload progress plugin. New redirect header and configuration option.

git-svn-id: svn+ssh://rubyforge.org/var/svn/mongrel/trunk@245 19e92222-5c0b-0410-8929-a290d50e31e9
This commit is contained in:
zedshaw 2006-06-18 04:57:26 +00:00
parent e5c6b9ad70
commit 364270615b
4 changed files with 129 additions and 6 deletions

View file

@ -40,6 +40,8 @@ config = Mongrel::Configurator.new :host => ARGV[0], :port => ARGV[1] do
uri "/files", :handler => Mongrel::DirHandler.new(ARGV[2])
uri "/files", :handler => stats
uri "/status", :handler => Mongrel::StatusHandler.new(:stats_filter => stats)
redirect "/redir1", "/"
redirect "/to", /to/, 'w'
end
trap("INT") { stop }

View file

@ -171,6 +171,7 @@ module Mongrel
HTTP_X_FORWARDED_FOR="HTTP_X_FORWARDED_FOR".freeze
HTTP_IF_UNMODIFIED_SINCE="HTTP_IF_UNMODIFIED_SINCE".freeze
HTTP_IF_NONE_MATCH="HTTP_IF_NONE_MATCH".freeze
REDIRECT = "HTTP/1.1 302 Found\r\nLocation: %s\r\nConnection: close\r\n\r\n".freeze
end
@ -534,9 +535,15 @@ 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
data = data[nparsed ... data.length] || ""
if handlers[0].request_notify
# this first handler wants to be notified when the process starts
handlers[0].request_begins(params)
end
# TODO: Find a faster/better way to carve out the range, preferably without copying.
request = HttpRequest.new(params, data[nparsed ... data.length] || "", client)
request = HttpRequest.new(params, data, client)
# in the case of large file uploads the user could close the socket, so skip those requests
break if request.body == nil # nil signals from HttpRequest::initialize that the request was aborted
@ -926,6 +933,16 @@ module Mongrel
GemPlugin::Manager.instance.create(name, ops)
end
# Let's you do redirects easily as described in Mongrel::RedirectHandler.
# You use it inside the configurator like this:
#
# redirect("/test", "/to/there") # simple
# redirect("/to", /t/, 'w') # regexp
# redirect("/hey", /(w+)/) {|match| ...} # block
#
def redirect(from, pattern, replacement = nil, &block)
uri from, :handler => Mongrel::RedirectHandler.new(pattern, replacement, &block)
end
# Works like a meta run method which goes through all the
# configured listeners. Use the Configurator.join method
@ -968,13 +985,21 @@ module Mongrel
# found in Rails applications that are either slow or become unresponsive
# after a little while.
#
# TODO: Document the optional selections from the what parameter
# You can pass an extra parameter *what* to indicate what you want to
# debug. For example, if you just want to dump rails stuff then do:
#
# debug "/", what = [:rails]
#
# And it will only produce the log/mongrel_debug/rails.log file.
# Available options are: :object, :railes, :files, :threads, :params
#
# NOTE: Use [:files] to get acccesses dumped to stderr like with WEBrick.
def debug(location, what = [:object, :rails, :files, :threads, :params])
require 'mongrel/debug'
handlers = {
:object => "/handlers/requestlog::access",
:files => "/handlers/requestlog::access",
:rails => "/handlers/requestlog::files",
:files => "/handlers/requestlog::objects",
:object => "/handlers/requestlog::objects",
:threads => "/handlers/requestlog::threads",
:params => "/handlers/requestlog::params"
}

View file

@ -31,11 +31,19 @@ module Mongrel
# should be implemented using the HttpHandlerPlugin mixin.
#
class HttpHandler
attr_reader :header_only
attr_reader :request_notify
attr_accessor :listener
# This will be called by Mongrel on the *first* (index 0) handler *if* it has
# HttpHandler.request_notify set to *true*. You only get the parameters
# for the request, with the idea that you'd "bound" the beginning of the
# request processing and the first call to process.
def request_begins(params)
end
def process(request, response)
end
end
@ -45,9 +53,12 @@ module Mongrel
# the process method later.
module HttpHandlerPlugin
attr_reader :options
attr_reader :header_only
attr_reader :request_notify
attr_accessor :listener
def request_begins(params)
end
def initialize(options={})
@options = options
@header_only = false
@ -398,4 +409,48 @@ module Mongrel
end
end
end
# This handler allows you to redirect one url to another.
# You can use it like String#gsub, where the string is the REQUEST_URI.
# REQUEST_URI is the full path with GET parameters.
#
# Eg. /test/something?help=true&disclaimer=false
#
# == Examples
#
# h = Mongrel::HttpServer.new('0.0.0.0')
# h.register '/test', Mongrel::RedirectHandler.new('/to/there') # simple
# h.register '/to', Mongrel::RedirectHandler.new(/t/, 'w') # regexp
# # and with a block
# h.register '/hey', Mongrel::RedirectHandler.new(/(\w+)/) { |match| ... }
#
class RedirectHandler < Mongrel::HttpHandler
# You set the rewrite rules when building the object.
#
# pattern => What to look for or replacement if used alone
#
# replacement, block => One of them is used to replace the found text
def initialize(pattern, replacement = nil, &block)
unless replacement or block
@replacement = pattern
else
@pattern, @replacement, @block = pattern, replacement, block
end
end
# Process the request and return a redirect response
def process(request, response)
unless @pattern
response.socket.write(Mongrel::Const::REDIRECT % @replacement)
else
if @block
new_path = request.params['REQUEST_URI'].gsub(@pattern, &@block)
else
new_path = request.params['REQUEST_URI'].gsub(@pattern, @replacement)
end
response.socket.write(Mongrel::Const::REDIRECT % new_path)
end
end
end
end

View file

@ -0,0 +1,41 @@
require 'test/unit'
require 'mongrel'
require 'mongrel/redirect_handler'
require 'net/http'
require 'uri'
require 'timeout'
class TC_RedirectHandler < Test::Unit::TestCase
def setup
@server = Mongrel::HttpServer.new('0.0.0.0', 9998)
@server.run
@client = Net::HTTP.new('0.0.0.0', 9998)
end
def teardown
@server.stop
end
def test_simple_redirect
tester = Mongrel::RedirectHandler.new('/yo')
@server.register("/test", tester)
sleep(1)
res = @client.request_get('/test')
assert res != nil, "Didn't get a response"
assert_equal ['/yo'], res.get_fields('Location')
end
def test_rewrite
tester = Mongrel::RedirectHandler.new(/(\w+)/, '+\1+')
@server.register("/test", tester)
sleep(1)
res = @client.request_get('/test/something')
assert_equal ['/+test+/+something+'], res.get_fields('Location')
end
end