1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
# Web::Controller::PolyState
# Copyright(c) 2004 MoonWolf <moonwolf@moonwolf.com>
require 'web/escape'
require 'web/response'
require 'web/cookie'
module Web
module Controller
class PolyState
def initialize
end
def setup(opt={})
@opt = opt
@states = {}
end
def teardown
end
def cookie_name
'sessionid'
end
def cookie_path
nil
end
def cookie_domain
nil
end
def session_expires
Time.now + 600
end
def run(req)
begin
state = 'default'
session_id = req.cookies[cookie_name]
if session_id
session_id = session_id.value
ps = Web::Persistent.new(session_id,@opt)
ps.transaction {
if ps['state']
state = ps['state']
if ps['expire']<Time.now
state = 'default'
end
end
ps['state'] = state
ps['expire'] = session_expires
}
else
ps = Web::Persistent.new(nil,@opt)
ps.transaction {
ps['state'] = state
ps['expire'] = session_expires
}
session_id = ps.persistent_id
end
rsp = Web::Response.new
cookie = Web::Cookie.new(cookie_name, session_id)
cookie.path = cookie_path if cookie_path
cookie.domain = cookie_domain if cookie_domain
rsp = @states[state].run(req, rsp, ps, self)
rsp.cookies[cookie_name] = cookie
rsp
rescue StandardError,ScriptError
error($!.message + "\n" + $!.backtrace.join("\n"))
end
end
def error(msg)
rsp = Web::Response.new
msg = h(msg).gsub(/\n/,"<br>")
rsp.content_type = "text/html"
rsp.write <<EOS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>ERROR #{self.class}</title>
<link rel="INDEX" href="./">
</head>
<body>
<h1>ERROR #{self.class}</h1>
<pre>#{msg}</pre>
</body>
</html>
EOS
rsp
end
def h(str)
Web::escapeHTML(str)
end
def u(str)
Web::escape(str.to_s)
end
class State
def run_mode(req)
rm = req.get('rm')
if rm == nil
req.form.keys.each {|k|
if k=~/^rm_/
rm = $'
break
end
}
end
rm ||= 'start'
return rm
end
def run(req, rsp, ps, main)
begin
rm = 'do_' + run_mode(req)
send(rm, req, rsp, ps, main)
rsp
rescue StandardError,ScriptError
error($!.message + "\n" + $!.backtrace.join("\n"))
end
end
def transit(ps,state)
ps.transaction {
ps['state'] = state
}
end
def error(msg)
rsp = Web::Response.new
msg = h(msg).gsub(/\n/,"<br>")
rsp.content_type = "text/html"
rsp.write <<EOS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>ERROR #{self.class}</title>
<link rel="INDEX" href="./">
</head>
<body>
<h1>ERROR #{self.class}</h1>
<pre>#{msg}</pre>
</body>
</html>
EOS
rsp
end
def h(str)
Web::escapeHTML(str)
end
def u(str)
Web::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(req, name, type, must = true)
raise ArgumentError if must && !req.has_key?(name)
value = req[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
type[value]
when Regexp
m = type.match(value)
raise ArgumentError unless value
m
end
end
end # State
end # PolyState
end # Controller
end # Web
|