nitro 0.20.0 → 0.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +752 -543
- data/INSTALL +38 -38
- data/README +264 -225
- data/Rakefile +48 -49
- data/bin/nitro +3 -3
- data/bin/nitrogen +6 -6
- data/doc/AUTHORS +10 -10
- data/doc/CHANGELOG.1 +1939 -1939
- data/doc/CHANGELOG.2 +954 -954
- data/doc/LICENSE +3 -3
- data/doc/MIGRATION +28 -0
- data/doc/RELEASES +814 -643
- data/doc/config.txt +5 -5
- data/install.rb +7 -17
- data/lib/nitro.rb +38 -9
- data/lib/nitro/adapter/cgi.rb +311 -312
- data/lib/nitro/adapter/fastcgi.rb +18 -25
- data/lib/nitro/adapter/webrick.rb +128 -137
- data/lib/nitro/adapter/wee.rb +51 -0
- data/lib/nitro/caching.rb +20 -20
- data/lib/nitro/caching/actions.rb +43 -43
- data/lib/nitro/caching/fragments.rb +46 -46
- data/lib/nitro/caching/invalidation.rb +11 -11
- data/lib/nitro/caching/output.rb +65 -65
- data/lib/nitro/caching/stores.rb +67 -67
- data/lib/nitro/compiler.rb +262 -0
- data/lib/nitro/compiler/elements.rb +0 -0
- data/lib/nitro/compiler/errors.rb +65 -0
- data/lib/nitro/compiler/localization.rb +25 -0
- data/lib/nitro/compiler/markup.rb +19 -0
- data/lib/nitro/compiler/shaders.rb +206 -0
- data/lib/nitro/compiler/squeeze.rb +20 -0
- data/lib/nitro/compiler/xslt.rb +61 -0
- data/lib/nitro/context.rb +87 -88
- data/lib/nitro/controller.rb +151 -158
- data/lib/nitro/cookie.rb +34 -34
- data/lib/nitro/dispatcher.rb +195 -186
- data/lib/nitro/element.rb +132 -126
- data/lib/nitro/element/java_script.rb +6 -6
- data/lib/nitro/flash.rb +66 -66
- data/lib/nitro/mail.rb +192 -192
- data/lib/nitro/mixin/buffer.rb +66 -0
- data/lib/nitro/mixin/debug.rb +16 -16
- data/lib/nitro/mixin/form.rb +88 -0
- data/lib/nitro/mixin/helper.rb +2 -2
- data/lib/nitro/mixin/javascript.rb +108 -108
- data/lib/nitro/mixin/markup.rb +144 -0
- data/lib/nitro/mixin/pager.rb +202 -202
- data/lib/nitro/mixin/rss.rb +67 -0
- data/lib/nitro/mixin/table.rb +63 -0
- data/lib/nitro/mixin/xhtml.rb +75 -0
- data/lib/nitro/mixin/xml.rb +124 -0
- data/lib/nitro/render.rb +183 -359
- data/lib/nitro/request.rb +140 -140
- data/lib/nitro/response.rb +27 -27
- data/lib/nitro/routing.rb +21 -21
- data/lib/nitro/scaffold.rb +124 -118
- data/lib/nitro/server.rb +117 -80
- data/lib/nitro/server/runner.rb +341 -0
- data/lib/nitro/service.rb +12 -12
- data/lib/nitro/service/xmlrpc.rb +22 -22
- data/lib/nitro/session.rb +122 -120
- data/lib/nitro/session/drb.rb +9 -9
- data/lib/nitro/session/drbserver.rb +34 -34
- data/lib/nitro/template.rb +171 -155
- data/lib/nitro/testing/assertions.rb +90 -90
- data/lib/nitro/testing/context.rb +16 -16
- data/lib/nitro/testing/testcase.rb +34 -34
- data/proto/conf/lhttpd.conf +9 -9
- data/proto/public/error.xhtml +75 -75
- data/proto/public/index.xhtml +18 -18
- data/proto/public/js/behaviour.js +65 -65
- data/proto/public/js/controls.js +1 -1
- data/proto/public/js/prototype.js +3 -3
- data/proto/public/settings.xhtml +61 -61
- data/proto/run.rb +1 -5
- data/test/nitro/adapter/raw_post1.bin +0 -0
- data/test/nitro/adapter/tc_cgi.rb +57 -57
- data/test/nitro/adapter/tc_webrick.rb +4 -4
- data/test/nitro/mixin/tc_pager.rb +25 -25
- data/test/nitro/mixin/tc_rss.rb +24 -0
- data/test/nitro/mixin/tc_table.rb +31 -0
- data/test/nitro/mixin/tc_xhtml.rb +13 -0
- data/test/nitro/tc_caching.rb +10 -10
- data/test/nitro/tc_context.rb +8 -8
- data/test/nitro/tc_controller.rb +48 -48
- data/test/nitro/tc_cookie.rb +6 -6
- data/test/nitro/tc_dispatcher.rb +64 -64
- data/test/nitro/tc_element.rb +27 -27
- data/test/nitro/tc_flash.rb +31 -31
- data/test/nitro/tc_mail.rb +63 -63
- data/test/nitro/tc_server.rb +26 -26
- data/test/nitro/tc_session.rb +9 -9
- data/test/nitro/tc_template.rb +19 -19
- data/test/public/blog/list.xhtml +1 -1
- metadata +31 -37
- data/lib/nitro/buffering.rb +0 -45
- data/lib/nitro/builder/form.rb +0 -104
- data/lib/nitro/builder/rss.rb +0 -104
- data/lib/nitro/builder/table.rb +0 -80
- data/lib/nitro/builder/xhtml.rb +0 -132
- data/lib/nitro/builder/xml.rb +0 -131
- data/lib/nitro/conf.rb +0 -36
- data/lib/nitro/environment.rb +0 -21
- data/lib/nitro/errors.rb +0 -69
- data/lib/nitro/localization.rb +0 -153
- data/lib/nitro/markup.rb +0 -147
- data/lib/nitro/output.rb +0 -24
- data/lib/nitro/runner.rb +0 -348
- data/lib/nitro/shaders.rb +0 -206
- data/test/nitro/builder/tc_rss.rb +0 -23
- data/test/nitro/builder/tc_table.rb +0 -30
- data/test/nitro/builder/tc_xhtml.rb +0 -39
- data/test/nitro/builder/tc_xml.rb +0 -56
- data/test/nitro/tc_localization.rb +0 -49
|
File without changes
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
require 'facet/string/demodulize'
|
|
2
|
+
|
|
3
|
+
module Nitro
|
|
4
|
+
|
|
5
|
+
class ActionCompileError < SyntaxError
|
|
6
|
+
SOURCE_CODE_RADIUS = 5
|
|
7
|
+
|
|
8
|
+
attr_accessor :original_excpetion
|
|
9
|
+
|
|
10
|
+
def initialize(source_code, filename, original_exception)
|
|
11
|
+
@source_code = source_code.split("\n")
|
|
12
|
+
@filename = filename
|
|
13
|
+
@original_exception = original_exception
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def line_number
|
|
17
|
+
trace = @original_exception.backtrace.join
|
|
18
|
+
|
|
19
|
+
if trace.include?(":in `class_eval'")
|
|
20
|
+
trace.scan(/:([0-9]*):in `class_eval'/).first.first.to_i
|
|
21
|
+
else
|
|
22
|
+
1
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def source_extract(indent = 0)
|
|
27
|
+
ln = line_number
|
|
28
|
+
start_line = [ln - SOURCE_CODE_RADIUS, 0].max
|
|
29
|
+
end_line = [ln + SOURCE_CODE_RADIUS - 1, @source_code.length].min
|
|
30
|
+
|
|
31
|
+
number = start_line
|
|
32
|
+
extract = @source_code[start_line..end_line].collect do |line|
|
|
33
|
+
number += 1
|
|
34
|
+
line = line.gsub(/; @out << %\^/, ' ?>').gsub(/\^;/, '<?r ')
|
|
35
|
+
if number == line_number
|
|
36
|
+
"#{' ' * indent}#{number}: #{line}"
|
|
37
|
+
else
|
|
38
|
+
"#{' ' * indent}#{number}: #{line}"
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
return extract.join("\n")
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def backtrace
|
|
46
|
+
@original_exception.backtrace.collect do |line|
|
|
47
|
+
line.gsub("#{Nitro::LibPath}/", '')
|
|
48
|
+
end.compact
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def to_s
|
|
52
|
+
"#{self.class.to_s.demodulize} (#{@original_exception.class}): '#@filename' at line ##{line_number}"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def message
|
|
56
|
+
"#{to_s}\n#{source_extract}"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
class TemplateCompileError < ActionCompileError
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
require 'glue/localization'
|
|
2
|
+
|
|
3
|
+
module Glue
|
|
4
|
+
|
|
5
|
+
class Localization
|
|
6
|
+
|
|
7
|
+
class << self
|
|
8
|
+
|
|
9
|
+
# Transform localization macros.
|
|
10
|
+
|
|
11
|
+
def transform(text)
|
|
12
|
+
# handle symbols
|
|
13
|
+
text.gsub!(/\[\[\:(.*?)\]\]/, '#{@lc[\1]}')
|
|
14
|
+
|
|
15
|
+
# handle strings
|
|
16
|
+
text.gsub!(/\[\[(.*?)\]\]/, '#{@lc["\1"]}')
|
|
17
|
+
|
|
18
|
+
return text
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'nitro/mixin/markup'
|
|
2
|
+
|
|
3
|
+
module Nitro
|
|
4
|
+
|
|
5
|
+
module Markup
|
|
6
|
+
|
|
7
|
+
# Transform the markup macros.
|
|
8
|
+
# Maps #(..) to :sanitize.
|
|
9
|
+
# Maps #|..| to :markup.
|
|
10
|
+
|
|
11
|
+
def self.transform(text)
|
|
12
|
+
text.gsub!(/\#\((.*?)\)/, '#{sanitize(\1)}')
|
|
13
|
+
text.gsub!(/\#\|(.*?)\|/, '#{markup(\1)}')
|
|
14
|
+
return text
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
end
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
require 'nitro/template'
|
|
2
|
+
require 'nitro/element'
|
|
3
|
+
|
|
4
|
+
module Nitro
|
|
5
|
+
|
|
6
|
+
# A shader defines a transformation-pipeline that tansforms
|
|
7
|
+
# the .xhtml files to actual ruby code ready for evaluation
|
|
8
|
+
# (compilation) by the engine.
|
|
9
|
+
#
|
|
10
|
+
# Shaders employ a folded-filter design.
|
|
11
|
+
#--
|
|
12
|
+
# TODO: pipeline stage mixin to be reused in filters too.
|
|
13
|
+
#++
|
|
14
|
+
|
|
15
|
+
class Shader
|
|
16
|
+
|
|
17
|
+
# the next stage in the Shader pipeline.
|
|
18
|
+
|
|
19
|
+
attr :next_stage
|
|
20
|
+
|
|
21
|
+
def initialize(next_stage = nil)
|
|
22
|
+
@next_stage = next_stage
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Process the text and optionally update the hash.
|
|
26
|
+
# The hash is a short, unique representation of the
|
|
27
|
+
# input text, typically used as a caching key.
|
|
28
|
+
|
|
29
|
+
def process(hash, text)
|
|
30
|
+
process_next(hash, text)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Set the next stage of the pipeline.
|
|
34
|
+
|
|
35
|
+
def << (next_stage = nil)
|
|
36
|
+
@next_stage = next_stage
|
|
37
|
+
return self
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Process the next stage of the pipeline.
|
|
41
|
+
|
|
42
|
+
def process_next(hash, text)
|
|
43
|
+
if @next_stage
|
|
44
|
+
return @next_stage.process(hash, text)
|
|
45
|
+
else
|
|
46
|
+
return hash, text
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Convert the xhtml script to actual Ruby code, ready
|
|
52
|
+
# to be evaluated.
|
|
53
|
+
|
|
54
|
+
class RubyShader < Shader
|
|
55
|
+
include TemplateMixin
|
|
56
|
+
|
|
57
|
+
# Convert the xhtml script to actual Ruby code, ready
|
|
58
|
+
# to be evaluated.
|
|
59
|
+
#--
|
|
60
|
+
# Investigate:
|
|
61
|
+
# perhaps xl:href should be used to be XLink compatible?
|
|
62
|
+
#++
|
|
63
|
+
|
|
64
|
+
def process(hash, text)
|
|
65
|
+
text = compile_template(text)
|
|
66
|
+
process_next(hash, text)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Loads and statically includes a file.
|
|
70
|
+
|
|
71
|
+
def load_statically_included(filename)
|
|
72
|
+
Logger.debug "Statically including '#{filename}'" if $DBG
|
|
73
|
+
|
|
74
|
+
text = File.read(filename)
|
|
75
|
+
text.gsub!(/<\?xml.*\?>/, '')
|
|
76
|
+
text.gsub!(/<\/?root(.*?)>/m, ' ');
|
|
77
|
+
|
|
78
|
+
return text
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Apply an XSL transformation to the script code.
|
|
84
|
+
# There is no need to keep post xsl. I can reuse the
|
|
85
|
+
# same xsl by calling transform again.
|
|
86
|
+
|
|
87
|
+
class XSLTShader < Shader
|
|
88
|
+
|
|
89
|
+
# The name
|
|
90
|
+
|
|
91
|
+
attr :name
|
|
92
|
+
|
|
93
|
+
# The xslt filename.
|
|
94
|
+
|
|
95
|
+
attr :xsl_filename
|
|
96
|
+
|
|
97
|
+
# The xslt transformer.
|
|
98
|
+
|
|
99
|
+
attr :xslt
|
|
100
|
+
|
|
101
|
+
# Last modified time of the xslt.
|
|
102
|
+
|
|
103
|
+
attr :mtime
|
|
104
|
+
|
|
105
|
+
def initialize(xsl_filename, next_stage = nil)
|
|
106
|
+
|
|
107
|
+
# leave this require here. only inlcude the xslt
|
|
108
|
+
# library if the project needs it.
|
|
109
|
+
|
|
110
|
+
require "xml/xslt"
|
|
111
|
+
|
|
112
|
+
@name = File.basename(xsl_filename, '.*')
|
|
113
|
+
@xsl_filename = xsl_filename
|
|
114
|
+
@xslt = XML::XSLT.new
|
|
115
|
+
@next_stage = next_stage
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Transform the given text.
|
|
119
|
+
|
|
120
|
+
def process(hash, text)
|
|
121
|
+
parse_xsl()
|
|
122
|
+
@xslt.xml = text
|
|
123
|
+
hash += @name
|
|
124
|
+
Logger.debug "Applying xsl '#{@xsl_filename}' to template" if $DBG
|
|
125
|
+
process_next(hash, xslt.serve)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
private
|
|
129
|
+
|
|
130
|
+
# Parse the xsl.
|
|
131
|
+
|
|
132
|
+
def parse_xsl
|
|
133
|
+
Logger.debug "Parsing xsl '#{@xsl_filename}'" if $DBG
|
|
134
|
+
@mtime = File.mtime(@xsl_filename)
|
|
135
|
+
@xslt.xsl = File.read(@xsl_filename)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# Compress the inline xhtml. Does not touch the ruby code.
|
|
141
|
+
|
|
142
|
+
class CompressShader < Shader
|
|
143
|
+
|
|
144
|
+
# Compress the inline xhtml. Does not touch the ruby code.
|
|
145
|
+
|
|
146
|
+
def process(hash, text)
|
|
147
|
+
text.gsub!(/\@out \<\< \%\^(.*?)\^/m) do |match|
|
|
148
|
+
c = $1.gsub(/^(\s*)/m, '').squeeze(" \t").tr("\n", '').tr("\t", ' ')
|
|
149
|
+
"@out << %{#{c}}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
process_next(hash, text)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# MorphingShader
|
|
158
|
+
|
|
159
|
+
class MorphingShader < Shader
|
|
160
|
+
|
|
161
|
+
def process(hash, text)
|
|
162
|
+
|
|
163
|
+
# <tag if="x">..</tag>
|
|
164
|
+
# <tag unless="x">..</tag>
|
|
165
|
+
|
|
166
|
+
text.gsub!(/<(\w*?)([^>]*?)(if|unless)=["|'](.*?)["|'](.*?)>(.*?)<\/\1>/m) do |match|
|
|
167
|
+
%{<?r #$3 #$4 ?>
|
|
168
|
+
<#$1#$2#$5>#$6</#$1>
|
|
169
|
+
<?r end ?>}
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# <tag times="x">..</tag>
|
|
173
|
+
|
|
174
|
+
text.gsub!(/<(\w*?)([^>]*?)times=["|'](.*?)["|'](.*?)>(.*?)<\/\1>/m) do |match|
|
|
175
|
+
%{<?r #$3.times do ?>
|
|
176
|
+
<#$1#$2#$4>#$5</#$1>
|
|
177
|
+
<?r end ?>}
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# <tag each="x">..</tag>
|
|
181
|
+
|
|
182
|
+
text.gsub!(/<(\w*?)([^>]*?)each=["|'](.*?)["|'](.*?)>(.*?)<\/\1>/m) do |match|
|
|
183
|
+
%{<?r for #$3 ?>
|
|
184
|
+
<#$1#$2#$4>#$5</#$1>
|
|
185
|
+
<?r end ?>}
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
process_next(hash, text)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
# ElementsShader
|
|
194
|
+
|
|
195
|
+
class ElementsShader < Shader
|
|
196
|
+
|
|
197
|
+
def process(hash, text)
|
|
198
|
+
text = ElementProcessor.render(text)
|
|
199
|
+
process_next(hash, text)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Nitro::Compiler
|
|
2
|
+
|
|
3
|
+
# Compress the inline xhtml. Does not touch the ruby code.
|
|
4
|
+
|
|
5
|
+
class Squeeze
|
|
6
|
+
|
|
7
|
+
# Compresses the inline xhtml. Does not touch the ruby code.
|
|
8
|
+
|
|
9
|
+
def transform(text)
|
|
10
|
+
return text.gsub(/\@out \<\< \%\^(.*?)\^/m) do |match|
|
|
11
|
+
c = $1.gsub(/^(\s*)/m, '').squeeze(" \t").tr("\n", '').tr("\t", ' ')
|
|
12
|
+
"@out << %{#{c}}"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# * George Moschovitis <gm@navel.gr>
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
require 'sync'
|
|
2
|
+
|
|
3
|
+
require 'xml/xslt'
|
|
4
|
+
|
|
5
|
+
module Nitro
|
|
6
|
+
|
|
7
|
+
# Apply XSL transformation.
|
|
8
|
+
|
|
9
|
+
class XSLTransform
|
|
10
|
+
@@sync = Sync.new
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
|
|
14
|
+
# The xslt filename.
|
|
15
|
+
|
|
16
|
+
attr :xsl_filename
|
|
17
|
+
|
|
18
|
+
# The xslt transformer.
|
|
19
|
+
|
|
20
|
+
attr :xslt
|
|
21
|
+
|
|
22
|
+
def initialize(xsl_filename, next_stage = nil)
|
|
23
|
+
|
|
24
|
+
# leave this require here. only inlcude the xslt
|
|
25
|
+
# library if the project needs it.
|
|
26
|
+
|
|
27
|
+
require "xml/xslt"
|
|
28
|
+
|
|
29
|
+
@name = File.basename(xsl_filename, '.*')
|
|
30
|
+
@xsl_filename = xsl_filename
|
|
31
|
+
@xslt = XML::XSLT.new
|
|
32
|
+
@next_stage = next_stage
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Transform the given xml.
|
|
36
|
+
|
|
37
|
+
def transform(text)
|
|
38
|
+
|
|
39
|
+
parse_xsl()
|
|
40
|
+
@xslt.xml = text
|
|
41
|
+
hash += @name
|
|
42
|
+
Logger.debug "Applying xsl '#{@xsl_filename}' to template" if $DBG
|
|
43
|
+
process_next(hash, xslt.serve)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
# Parse the xsl.
|
|
49
|
+
|
|
50
|
+
def parse_xsl
|
|
51
|
+
Logger.debug "Parsing xsl '#{@xsl_filename}'" if $DBG
|
|
52
|
+
@mtime = File.mtime(@xsl_filename)
|
|
53
|
+
@xslt.xsl = File.read(@xsl_filename)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# * George Moschovitis <gm@navel.gr>
|
data/lib/nitro/context.rb
CHANGED
|
@@ -2,101 +2,100 @@ require 'nitro/request'
|
|
|
2
2
|
require 'nitro/response'
|
|
3
3
|
require 'nitro/render'
|
|
4
4
|
require 'nitro/session'
|
|
5
|
-
require 'nitro/output'
|
|
6
5
|
require 'nitro/adapter/cgi.rb'
|
|
7
6
|
|
|
8
7
|
module Nitro
|
|
9
|
-
|
|
8
|
+
|
|
10
9
|
# Encapsulates an HTTP processing cycle context.
|
|
11
10
|
# Integrates the Request and the Response.
|
|
12
11
|
|
|
13
12
|
class Context
|
|
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
|
-
|
|
13
|
+
include Request
|
|
14
|
+
include Response
|
|
15
|
+
include Render
|
|
16
|
+
|
|
17
|
+
# The configuration parameters.
|
|
18
|
+
|
|
19
|
+
attr_accessor :conf
|
|
20
|
+
|
|
21
|
+
# The session contains variables that stay alive
|
|
22
|
+
# for the full user session. Session variables
|
|
23
|
+
# should be generally avoided. This variable
|
|
24
|
+
# becomes populated ONLY if needed.
|
|
25
|
+
|
|
26
|
+
attr_reader :session
|
|
27
|
+
|
|
28
|
+
# The dispatcher.
|
|
29
|
+
|
|
30
|
+
attr_accessor :dispatcher
|
|
31
|
+
|
|
32
|
+
def initialize(conf)
|
|
33
|
+
@conf = conf
|
|
34
|
+
@dispatcher = @conf.dispatcher
|
|
35
|
+
@context = self
|
|
36
|
+
|
|
37
|
+
# initialize response.
|
|
38
|
+
|
|
39
|
+
@status = CgiUtils::STATUS_OK
|
|
40
|
+
@response_headers = { 'Content-Type' => 'text/html' }
|
|
41
|
+
|
|
42
|
+
# initialize the output buffer.
|
|
43
|
+
|
|
44
|
+
@out = OutputBuffer.new
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Close the context, should be called at the
|
|
48
|
+
# end of the HTTP request handling code.
|
|
49
|
+
|
|
50
|
+
def close
|
|
51
|
+
@session.sync if @session
|
|
52
|
+
end
|
|
53
|
+
alias_method :finish, :close
|
|
54
|
+
|
|
55
|
+
#--
|
|
56
|
+
# FIXME: something more elegant/efficient.
|
|
57
|
+
#++
|
|
58
|
+
|
|
59
|
+
def out
|
|
60
|
+
if @out == '(error)'
|
|
61
|
+
@out = ''
|
|
62
|
+
render '/error'
|
|
63
|
+
@out
|
|
64
|
+
else
|
|
65
|
+
@out
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Lazy lookup of the session to avoid costly cookie
|
|
70
|
+
# lookup when not needed.
|
|
71
|
+
|
|
72
|
+
def session
|
|
73
|
+
@session || @session = Session.lookup(self)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Populate an object from request parameters.
|
|
77
|
+
# This is a truly dangerous method.
|
|
78
|
+
|
|
79
|
+
EXCLUDED_PARAMETERS = %w{ oid name }
|
|
80
|
+
|
|
81
|
+
def fill(obj, name = nil)
|
|
82
|
+
# if an object is passed create an instance.
|
|
83
|
+
obj = obj.new if obj.is_a?(Class)
|
|
84
|
+
|
|
85
|
+
@params.each do |param, val|
|
|
86
|
+
begin
|
|
87
|
+
# gmosx: DO NOT escape by default !!!
|
|
88
|
+
if not EXCLUDED_PARAMETERS.include?(param)
|
|
89
|
+
obj.send("__force_#{param}", val)
|
|
90
|
+
end
|
|
91
|
+
rescue NameError
|
|
92
|
+
next
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
return obj
|
|
97
|
+
end
|
|
98
|
+
alias_method :populate, :fill
|
|
100
99
|
end
|
|
101
100
|
|
|
102
101
|
end
|