|
|
What this is
This file is included in the DevDaily.com
"Ruby Source Code
Warehouse" project. The intent of this project is to help you "Learn
Ruby by Example" TM.
Other links
The source code
#CGI::Application
#Copyright(c) 2002 MoonWolf
require 'cgi'
require "cgi/session"
class CGI
class Application
class MethodChain
def initialize
@chain = []
end
def push(label, m)
@chain.push [label, m]
end
def shift(label=nil)
@chain.shift
end
def unshift(label, m)
@chain.unshift [label, m]
end
end
def initialize
end
def setup(opt={})
end
def teardown
end
def run_mode(cgi)
rm ,= cgi.params.fetch('rm', 'start')
rm
end
def method_chain(cgi)
chain = MethodChain.new
rm = run_mode(cgi)
chain.push "do", ["do_" + rm, cgi]
chain
end
def out(options={})
throw :out, [yield, options]
end
def dispatch(cgi, chain)
body, options = catch(:out) {
memo = {}
while m = chain.shift
label, (method,*param) = m
if respond_to?(method)
begin
param.push memo
param.push chain
new_chain = send(method, *param)
chain = new_chain if MethodChain === new_chain
rescue Exception
error cgi, $!.inspect + "\n" + $!.backtrace.join("\n")
end
end
end
error cgi, "method chain empty"
}
end
def run(cgi)
chain = method_chain(cgi)
body, options = dispatch(cgi, chain)
cgi.out(options) {
body
}
end
def error(cgi, msg, memo=nil,chain=nil)
msg = h(msg).gsub(/\n/," ")
out() {<
ERROR #{self.type}
ERROR #{self.type}
#{msg}
EOS
end
# Utility
def h(str)
CGI.escapeHTML(str.to_s)
end
def u(str)
CGI.escape(str.to_s)
end
def qs(hash)
url = '?'
url << hash.collect {|key,value|
u(key.to_s) << '=' << u(value.to_s)
}.sort.join(';')
h(url)
end
def get_param(cgi, name, type, must = true)
raise ArgumentError if must && !cgi.has_key?(name)
value ,= cgi[name]
return nil if !value and !must
value = value.read if value.respond_to?(:read)
case type
when :text
value
when :flag
case value.trim.downcase
when /\A(?:on|yes|y|true|1)\z/
true
when /\A(?:off|no|n|false|0)\z/
false
else
raise ArgumentError
end
when :integer
Integer(value)
when Array
raise ArgumentError unless type.include?(value)
value
when Hash
raise ArgumentError unless type.has_key?(value)
type[value]
when Regexp
raise ArgumentError if value !~ type
end
end
class SessionManaged < CGI::Application
def setup(opt={})
@session_opt = opt['session_opt'] || {}
@session_key = @session_opt['session_key'] || '_session_id'
@dbman = @session_opt['database_manager'] || CGI::Session::FileStore
@session_opt['session_key'] = @session_key
@session_opt['database_manager'] = @dbman
end
def timeout
20*60 # sec
end
#
def get_session(cgi)
if cgi.cookies[@session_key].empty? && !cgi.has_key?(@session_key)
nil
else
session = CGI::Session.new(cgi, @session_opt)
end
end
def expired?(session)
if expire=session['expire']
if Time.now.to_i >= expire.to_i
true
else
false
end
else
true
end
end
def new_session(cgi)
opt = { 'new_session' => true }.update(@session_opt)
session = CGI::Session.new(cgi, opt)
session['expire'] = (Time.now.to_i + timeout).to_s
session['sequence'] = rand(1000000).to_s
session
end
def sequence_incr(session, memo, chain)
session['sequence'] = (session['sequence'].to_i + 1).to_s
end
def expire_extend(session, memo, chain)
session['expire'] = (Time.now.to_i + timeout).to_s
end
def method_chain(cgi)
chain = MethodChain.new
rm = run_mode(cgi)
session = get_session(cgi)
if session && session['expire']
chain.push "sequence_incr", [:sequence_incr, session]
if expired?(session)
chain.push "expired", ["expired_" + rm, cgi, session]
chain.push "sessionexpired", [:sessionexpired, cgi, session, rm]
else
chain.push "expire_extend", [:expire_extend, session]
chain.push "session", ["session_" + rm, cgi, session]
end
end
chain.push "do", ["do_" + rm, cgi]
end
end # SessionManaged
end # Application
end # CGI
|