nitro 0.8.0 → 0.9.3
Sign up to get free protection for your applications and to get access to all the features.
- data/AUTHORS +3 -4
- data/ChangeLog +418 -0
- data/LICENSE +1 -1
- data/README +157 -89
- data/RELEASES +50 -0
- data/Rakefile +5 -7
- data/benchmark/nitro/bench.rb +5 -0
- data/benchmark/nitro/simple-webrick-n-200.txt +44 -0
- data/benchmark/nitro/static-webrick-n-200.txt +43 -0
- data/benchmark/nitro/tiny-lhttpd-n-200-c-5.txt +43 -0
- data/benchmark/nitro/tiny-webrick-n-200-c-5.txt +44 -0
- data/benchmark/nitro/tiny-webrick-n-200.txt +44 -0
- data/benchmark/nitro/tiny2-webrick-n-200.txt +44 -0
- data/{lib/nitro/server/cluster.rb → bin/cluster} +26 -30
- data/bin/proto/README +2 -2
- data/bin/proto/{apache.conf → conf/apache.conf} +0 -0
- data/bin/proto/conf/app.conf.rb +22 -0
- data/bin/proto/conf/lhttpd.conf +236 -0
- data/bin/proto/ctl +4 -0
- data/bin/proto/lib/README +5 -0
- data/bin/proto/log/README +3 -0
- data/bin/proto/root/fcgi.rb +6 -0
- data/bin/proto/root/index.xhtml +65 -7
- data/bin/proto/root/m/nitro.png +0 -0
- data/examples/blog/README +7 -5
- data/examples/blog/{apache.conf → conf/apache.conf} +0 -0
- data/examples/blog/conf/app.conf.rb +56 -0
- data/examples/blog/conf/lhttpd.conf +236 -0
- data/examples/blog/ctl +4 -0
- data/examples/blog/lib/blog.rb +11 -136
- data/examples/blog/lib/blog/controller.rb +99 -0
- data/examples/blog/lib/blog/model.rb +39 -0
- data/examples/blog/log/README +3 -0
- data/examples/blog/root/comments.xhtml +2 -2
- data/examples/blog/root/fcgi.rb +6 -0
- data/examples/blog/root/index.xhtml +4 -5
- data/examples/blog/root/login.xhtml +2 -2
- data/examples/blog/root/style.xsl +9 -9
- data/examples/blog/root/view_entry.xhtml +2 -2
- data/examples/flash/conf/app.conf.rb +23 -0
- data/examples/flash/ctl +4 -0
- data/examples/flash/log/README +3 -0
- data/examples/flash/root/index.xhtml +0 -9
- data/examples/flash/root/show_inline_text.xhtml +10 -5
- data/examples/no_xsl_blog/README +12 -0
- data/examples/no_xsl_blog/conf/apache.conf +0 -0
- data/examples/no_xsl_blog/conf/app.conf.rb +57 -0
- data/examples/no_xsl_blog/conf/lhttpd.conf +236 -0
- data/examples/no_xsl_blog/ctl +4 -0
- data/examples/no_xsl_blog/lib/blog.rb +20 -0
- data/examples/no_xsl_blog/lib/blog/controller.rb +102 -0
- data/examples/no_xsl_blog/lib/blog/model.rb +39 -0
- data/examples/no_xsl_blog/lib/blog/template.rb +134 -0
- data/examples/no_xsl_blog/log/README +3 -0
- data/examples/no_xsl_blog/root/comments.xhtml +41 -0
- data/examples/no_xsl_blog/root/entry_form.xhtml +22 -0
- data/examples/no_xsl_blog/root/fcgi.rb +6 -0
- data/examples/no_xsl_blog/root/index.xhtml +39 -0
- data/examples/no_xsl_blog/root/login.xhtml +21 -0
- data/examples/no_xsl_blog/root/m/bubbles.gif +0 -0
- data/examples/no_xsl_blog/root/m/comments_curve.gif +0 -0
- data/examples/no_xsl_blog/root/m/down.gif +0 -0
- data/examples/no_xsl_blog/root/m/footer_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/garrow.gif +0 -0
- data/examples/no_xsl_blog/root/m/gbull.gif +0 -0
- data/examples/no_xsl_blog/root/m/grbull.gif +0 -0
- data/examples/no_xsl_blog/root/m/h1_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/header_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/nitro.gif +0 -0
- data/examples/no_xsl_blog/root/m/obull.gif +0 -0
- data/examples/no_xsl_blog/root/m/page_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/rss.gif +0 -0
- data/examples/no_xsl_blog/root/m/side_title_bg.gif +0 -0
- data/examples/no_xsl_blog/root/m/sidebar_bg.gif +0 -0
- data/examples/no_xsl_blog/root/recent_posts.xhtml +14 -0
- data/examples/no_xsl_blog/root/style.css +301 -0
- data/examples/no_xsl_blog/root/view_entry.xhtml +25 -0
- data/examples/no_xsl_blog/root/view_entry.xml +12 -0
- data/examples/og/run.rb +2 -2
- data/examples/tiny/README +2 -2
- data/examples/tiny/conf/apache.conf +5 -0
- data/examples/tiny/conf/app.conf.rb +21 -0
- data/examples/tiny/conf/lhttpd.conf +236 -0
- data/examples/tiny/ctl +4 -0
- data/examples/tiny/log/README +3 -0
- data/examples/tiny/root/fcgi.rb +6 -0
- data/examples/tiny/root/index.xhtml +7 -4
- data/examples/tiny/root/nitro.png +0 -0
- data/lib/glue.rb +13 -9
- data/lib/glue/array.rb +1 -1
- data/lib/glue/cache.rb +1 -1
- data/lib/glue/flexob.rb +12 -0
- data/lib/glue/hash.rb +1 -1
- data/lib/glue/inflector.rb +2 -2
- data/lib/glue/logger.rb +4 -8
- data/lib/glue/misc.rb +14 -0
- data/lib/glue/number.rb +1 -1
- data/lib/glue/object.rb +26 -0
- data/lib/glue/pool.rb +1 -1
- data/lib/glue/property.rb +84 -91
- data/lib/glue/string.rb +1 -1
- data/lib/glue/time.rb +1 -1
- data/lib/glue/validation.rb +1 -1
- data/lib/nitro.rb +18 -6
- data/lib/nitro/adaptors/cgi.rb +291 -0
- data/lib/nitro/adaptors/fastcgi.rb +42 -0
- data/lib/nitro/adaptors/runner.rb +123 -0
- data/lib/nitro/adaptors/webrick.rb +110 -0
- data/lib/nitro/buffering.rb +43 -0
- data/lib/nitro/builders/form.rb +1 -1
- data/lib/nitro/builders/rss.rb +1 -1
- data/{bin → lib/nitro}/cluster.rb +26 -30
- data/lib/nitro/context.rb +82 -0
- data/lib/nitro/controller.rb +50 -0
- data/lib/nitro/cookie.rb +46 -0
- data/lib/nitro/dispatcher.rb +105 -0
- data/lib/nitro/filters.rb +9 -10
- data/lib/nitro/localization.rb +42 -0
- data/lib/nitro/mail.rb +11 -14
- data/lib/nitro/render.rb +275 -0
- data/lib/nitro/request.rb +128 -0
- data/lib/nitro/response.rb +38 -0
- data/lib/nitro/scaffold.rb +11 -11
- data/lib/nitro/session.rb +84 -0
- data/lib/nitro/{server/shaders.rb → shaders.rb} +56 -36
- data/lib/nitro/ui/pager.rb +23 -26
- data/lib/nitro/{sitemap.rb → ui/sitemap.rb} +4 -12
- data/lib/nitro/uri.rb +1 -1
- data/lib/nitro/version.rb +10 -8
- data/lib/og.rb +66 -65
- data/lib/og/backend.rb +1 -1
- data/lib/og/backends/mysql.rb +48 -52
- data/lib/og/backends/psql.rb +34 -37
- data/lib/og/connection.rb +15 -15
- data/lib/og/enchant.rb +16 -9
- data/lib/og/meta.rb +127 -54
- data/lib/og/mock.rb +18 -18
- data/lib/og/version.rb +6 -4
- data/lib/parts/content.rb +4 -8
- data/test/glue/tc_logger.rb +3 -0
- data/test/glue/tc_property.rb +19 -3
- data/test/nitro/adaptors/tc_cgi.rb +63 -0
- data/test/nitro/adaptors/tc_webrick.rb +15 -0
- data/test/nitro/builders/tc_xml.rb +2 -2
- data/test/nitro/tc_context.rb +13 -0
- data/test/nitro/tc_controller.rb +47 -0
- data/test/nitro/tc_dispatcher.rb +64 -0
- data/test/nitro/tc_session.rb +20 -0
- data/test/nitro/{tc_sitemap.rb → ui/tc_sitemap.rb} +1 -1
- data/test/root/blog/list.xhtml +6 -0
- data/test/tc_og.rb +41 -4
- metadata +115 -59
- data/bin/proto/app.rb +0 -20
- data/bin/proto/config.rb +0 -77
- data/examples/blog/app.rb +0 -21
- data/examples/blog/config.rb +0 -95
- data/examples/blog/env.rb +0 -22
- data/examples/flash/README +0 -34
- data/examples/flash/app.rb +0 -20
- data/examples/flash/config.rb +0 -38
- data/examples/flash/lib/flash.rb +0 -40
- data/examples/flash/tmp.swf +0 -0
- data/examples/tiny/app.rb +0 -19
- data/examples/tiny/config.rb +0 -29
- data/examples/tiny/root/nitro-small.png +0 -0
- data/lib/nitro/application.rb +0 -217
- data/lib/nitro/config.rb +0 -128
- data/lib/nitro/events.rb +0 -122
- data/lib/nitro/html.rb +0 -151
- data/lib/nitro/http.rb +0 -102
- data/lib/nitro/l10n.rb +0 -30
- data/lib/nitro/server.rb +0 -59
- data/lib/nitro/server/appserver.rb +0 -67
- data/lib/nitro/server/cookie.rb +0 -87
- data/lib/nitro/server/dispatcher.rb +0 -62
- data/lib/nitro/server/filters.rb +0 -75
- data/lib/nitro/server/filters/autologin.rb +0 -51
- data/lib/nitro/server/fragment.rb +0 -70
- data/lib/nitro/server/handlers.rb +0 -127
- data/lib/nitro/server/render.rb +0 -426
- data/lib/nitro/server/request.rb +0 -658
- data/lib/nitro/server/requestpart.rb +0 -54
- data/lib/nitro/server/script.rb +0 -387
- data/lib/nitro/server/server.rb +0 -57
- data/lib/nitro/server/session.rb +0 -220
- data/lib/nitro/server/user.rb +0 -46
- data/lib/nitro/server/webrick.rb +0 -180
- data/lib/nitro/service.rb +0 -26
- data/lib/xsl/ui.xsl +0 -51
- data/lib/xsl/xforms.xsl +0 -28
- data/test/nitro/server/tc_cookie.rb +0 -34
- data/test/nitro/server/tc_filters.rb +0 -38
- data/test/nitro/server/tc_request.rb +0 -70
- data/test/nitro/server/tc_requestpart.rb +0 -28
- data/test/nitro/server/tc_session.rb +0 -34
- data/test/nitro/tc_events.rb +0 -44
- data/test/nitro/tc_html.rb +0 -79
- data/test/nitro/tc_http.rb +0 -18
@@ -1,127 +0,0 @@
|
|
1
|
-
# code:
|
2
|
-
# * George Moschovitis <gm@navel.gr>
|
3
|
-
#
|
4
|
-
# (c) 2004 Navel, all rights reserved.
|
5
|
-
# $Id: handlers.rb 167 2004-11-23 14:03:10Z gmosx $
|
6
|
-
|
7
|
-
require "glue/cache"
|
8
|
-
require "nitro/server/filters"
|
9
|
-
|
10
|
-
module N
|
11
|
-
|
12
|
-
# = Handler
|
13
|
-
#
|
14
|
-
# App server handlers handle requests to specific resources.
|
15
|
-
# Handlers are a special kinf of filters so the can be chained
|
16
|
-
# in the rendering pipeline.
|
17
|
-
#
|
18
|
-
# === Design:
|
19
|
-
#
|
20
|
-
# Handlers are NOT singleton classes. This way we can assign one
|
21
|
-
# handler class to multiple resources, and keep statistics and
|
22
|
-
# metrics for each resource.
|
23
|
-
#
|
24
|
-
class Handler < N::ServerFilter
|
25
|
-
|
26
|
-
# Perform the actual work of the handler
|
27
|
-
# Typically calls the next filter in the pipeline afterwards.
|
28
|
-
#
|
29
|
-
def process(request)
|
30
|
-
# nop
|
31
|
-
|
32
|
-
# walk the filter pipeline
|
33
|
-
@next_filter.process(request) if @next_filter
|
34
|
-
end
|
35
|
-
|
36
|
-
end # class
|
37
|
-
|
38
|
-
# = Handler Error
|
39
|
-
#
|
40
|
-
# Raise this if an error happens when handling a request
|
41
|
-
#
|
42
|
-
class HandlerError < StandardError; end
|
43
|
-
|
44
|
-
# = Script Handler
|
45
|
-
#
|
46
|
-
# Base handler for scripts. All othere script handlers are extensions
|
47
|
-
# from this class.
|
48
|
-
#
|
49
|
-
class ScriptHandler < Handler
|
50
|
-
|
51
|
-
# cache the compiled page scripts to optimize future references.
|
52
|
-
# use a thread safe cache.
|
53
|
-
@@compiled_script_cache = N::SafeHash.new()
|
54
|
-
|
55
|
-
# dont allow 2 threads to compile the same script. In fact dont allow
|
56
|
-
# two threads to compile in parallel.
|
57
|
-
@@compile_sync = Sync.new
|
58
|
-
|
59
|
-
# Overload the path.
|
60
|
-
# FIXME: better name and much better documentation.
|
61
|
-
#
|
62
|
-
def overload_path(path)
|
63
|
-
path.gsub!(/\/\//, '/')
|
64
|
-
|
65
|
-
if ::File.exists?("#$root_dir/#{path}")
|
66
|
-
return path
|
67
|
-
else
|
68
|
-
Logger.debug "OVERLOAD: '#{path}' -> 'p/#{path}'" if $DBG
|
69
|
-
return "p/#{path}"
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
# the compiler returns a singleton class customized for rendering the
|
74
|
-
# input script. The original idea was to define render() as a static
|
75
|
-
# method and return the class, but we will use a singleton object to
|
76
|
-
# keep custom data structures (sub-page-graph, metrics, etc)
|
77
|
-
#
|
78
|
-
# script_path is used as key in the Dynamic class creation and for
|
79
|
-
# caching
|
80
|
-
#
|
81
|
-
# === Design:
|
82
|
-
# we use __ for out too to avoid nasty collisions.
|
83
|
-
#
|
84
|
-
def compile_script(script)
|
85
|
-
compiled_script = nil
|
86
|
-
|
87
|
-
# dont allow 2 threads to compile the same script. In fact dont
|
88
|
-
# allow two threads to compile in parallel.
|
89
|
-
# gmosx: SOS this eval assigns the variable compiled_script!
|
90
|
-
@@compile_sync.synchronize {
|
91
|
-
eval(script)
|
92
|
-
}
|
93
|
-
|
94
|
-
return compiled_script
|
95
|
-
end
|
96
|
-
|
97
|
-
def compiled_script_cache
|
98
|
-
return @@compiled_script_cache
|
99
|
-
end
|
100
|
-
|
101
|
-
# Log a rendering error. The accumulated log is available
|
102
|
-
# for rendering in the offending page when in Debug mode.
|
103
|
-
#
|
104
|
-
def log_error(request, ex)
|
105
|
-
request.log_error "--------"
|
106
|
-
request.log_error "#{request.path}:"
|
107
|
-
request.log_error "#{ex.class}: #{ex}"
|
108
|
-
request.log_error ex.backtrace()
|
109
|
-
raise ScriptHandlerError.new(0, "error")
|
110
|
-
end
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
# =ScriptHandlerError
|
115
|
-
#
|
116
|
-
# Raise this if an error happens when handling a script.
|
117
|
-
#
|
118
|
-
class ScriptHandlerError < HandlerError
|
119
|
-
attr_reader :error_line
|
120
|
-
|
121
|
-
def initialize(error_line, message = nil)
|
122
|
-
@error_line, @message = error_line, message
|
123
|
-
end
|
124
|
-
|
125
|
-
end
|
126
|
-
|
127
|
-
end # module
|
data/lib/nitro/server/render.rb
DELETED
@@ -1,426 +0,0 @@
|
|
1
|
-
# George Moschovitis <gm@navel.gr>
|
2
|
-
# (c) 2004-2005 Navel, all rights reserved.
|
3
|
-
# $Id: render.rb 200 2004-12-27 11:24:41Z gmosx $
|
4
|
-
|
5
|
-
require 'cgi'
|
6
|
-
|
7
|
-
module N
|
8
|
-
|
9
|
-
# = RenderUtils
|
10
|
-
#
|
11
|
-
# Various render related utilities.
|
12
|
-
|
13
|
-
module RenderUtils
|
14
|
-
|
15
|
-
# Split the path to base, render_class and method.
|
16
|
-
#
|
17
|
-
# == Examples
|
18
|
-
#
|
19
|
-
# / -> nil, index, nil
|
20
|
-
# /add_user -> nil, add_user, nil
|
21
|
-
# /add_user?user=gmosx -> nil, add_user, user=gmosx
|
22
|
-
# /blog/new_entry -> blog, new_entry
|
23
|
-
# /blog -> blog, index, nil
|
24
|
-
|
25
|
-
def self.split_path(path)
|
26
|
-
# paths that start with rest/xxx are REST requests.
|
27
|
-
# FIXME: better chack here!
|
28
|
-
if path.slice!(/rest\//)
|
29
|
-
api = :rest
|
30
|
-
else
|
31
|
-
api = :http
|
32
|
-
end
|
33
|
-
|
34
|
-
parts = path.split('/')
|
35
|
-
|
36
|
-
case parts.size
|
37
|
-
when 0
|
38
|
-
base = ''
|
39
|
-
render_class = $services[:index]
|
40
|
-
meth = 'index'
|
41
|
-
when 2
|
42
|
-
if render_class = $services[parts[1]]
|
43
|
-
base = parts[1]
|
44
|
-
meth = 'index'
|
45
|
-
else
|
46
|
-
base = ''
|
47
|
-
render_class = $services[:index]
|
48
|
-
meth = parts[1]
|
49
|
-
end
|
50
|
-
when 3
|
51
|
-
base = parts[1]
|
52
|
-
render_class = $services[parts[1]]
|
53
|
-
meth = parts[2]
|
54
|
-
end
|
55
|
-
|
56
|
-
# p '--', api, base, render_class, meth, '--'
|
57
|
-
|
58
|
-
return api, base, render_class, meth
|
59
|
-
end
|
60
|
-
|
61
|
-
# Given the method try find the matching template.
|
62
|
-
# Can search for xhtml or xml templates.
|
63
|
-
# Returns nil if no template file is found.
|
64
|
-
#
|
65
|
-
def self.template_for_method(base, meth, ext = $template_ext)
|
66
|
-
# attempt to find a template of the form
|
67
|
-
# base/meth.xhtml
|
68
|
-
path = "#$root_dir/#{base}/#{meth}.#{ext}".squeeze('/')
|
69
|
-
|
70
|
-
unless File.exist?(path)
|
71
|
-
# attempt to find a template of the form
|
72
|
-
# base/meth/index.xhtml
|
73
|
-
path = "#$root_dir/#{base}/#{meth}/#{$index_template}".squeeze('/')
|
74
|
-
|
75
|
-
unless File.exist?(path)
|
76
|
-
# No template found!
|
77
|
-
path = nil
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
return path
|
82
|
-
end
|
83
|
-
|
84
|
-
# Transform a template to ruby rendering code.
|
85
|
-
#
|
86
|
-
def self.transform_template(path)
|
87
|
-
Logger.debug "Transforming '#{path}'" if $DBG
|
88
|
-
|
89
|
-
text = File.read(path)
|
90
|
-
hash, text = $shader.process(path, text)
|
91
|
-
|
92
|
-
return text
|
93
|
-
end
|
94
|
-
|
95
|
-
|
96
|
-
# Compile a HTTP method.
|
97
|
-
#
|
98
|
-
def self.compile_http_method(klass, base, meth)
|
99
|
-
Logger.debug "Compiling HTTP method '#{klass}:#{meth}'" if $DBG
|
100
|
-
|
101
|
-
valid = false
|
102
|
-
|
103
|
-
code = %{
|
104
|
-
def __#{meth}
|
105
|
-
@response.header['Content-Type'] = 'text/html'
|
106
|
-
@out ||= ''
|
107
|
-
}
|
108
|
-
|
109
|
-
# call 'before' filter chain.
|
110
|
-
if klass.respond_to?(:before_filters)
|
111
|
-
code << %{
|
112
|
-
#{klass.gen_filters_call_code(klass.before_filters)}
|
113
|
-
}
|
114
|
-
end
|
115
|
-
|
116
|
-
# call the action
|
117
|
-
if klass.instance_methods.include?(meth)
|
118
|
-
valid = true
|
119
|
-
code << %{
|
120
|
-
#{meth}();
|
121
|
-
}
|
122
|
-
end
|
123
|
-
|
124
|
-
# call the programmatically generated template if exists.
|
125
|
-
if klass.instance_methods.include?("#{meth}__xhtml")
|
126
|
-
valid = true
|
127
|
-
code << %{
|
128
|
-
return unless #{meth}__xhtml();
|
129
|
-
}
|
130
|
-
end
|
131
|
-
|
132
|
-
# call the template
|
133
|
-
if template = template_for_method(base, meth)
|
134
|
-
valid = true
|
135
|
-
code << %{
|
136
|
-
return unless __#{meth}_xhtml();
|
137
|
-
}
|
138
|
-
end
|
139
|
-
|
140
|
-
raise "Invalid method '#{meth}' for service '#{klass}'!" unless valid
|
141
|
-
|
142
|
-
# call 'after' filter chain.
|
143
|
-
if klass.respond_to?(:after_filters)
|
144
|
-
code << %{
|
145
|
-
#{klass.gen_filters_call_code(klass.after_filters)}
|
146
|
-
}
|
147
|
-
end
|
148
|
-
|
149
|
-
code << %{
|
150
|
-
redirect_referer if @out.empty?
|
151
|
-
end
|
152
|
-
}
|
153
|
-
|
154
|
-
if template
|
155
|
-
code << %{
|
156
|
-
def __#{meth}_xhtml
|
157
|
-
#{transform_template(template)}
|
158
|
-
end
|
159
|
-
}
|
160
|
-
end
|
161
|
-
=begin
|
162
|
-
puts '--'
|
163
|
-
puts dump(code)
|
164
|
-
puts '--'
|
165
|
-
=end
|
166
|
-
klass.class_eval(code)
|
167
|
-
|
168
|
-
return "__#{meth}"
|
169
|
-
end
|
170
|
-
|
171
|
-
# Compile a REST method.
|
172
|
-
#
|
173
|
-
def self.compile_rest_method(klass, base, meth)
|
174
|
-
Logger.debug "Compiling REST method '#{klass}:#{meth}'" if $DBG
|
175
|
-
|
176
|
-
valid = false
|
177
|
-
|
178
|
-
code = %{
|
179
|
-
def __rest_#{meth}
|
180
|
-
@response.header['Content-Type'] = 'text/xml'
|
181
|
-
@out ||= ''
|
182
|
-
}
|
183
|
-
|
184
|
-
# call 'before' filter chain.
|
185
|
-
if klass.respond_to?(:before_filters)
|
186
|
-
code << %{
|
187
|
-
#{klass.gen_filters_call_code(klass.before_filters)}
|
188
|
-
}
|
189
|
-
end
|
190
|
-
|
191
|
-
# call the action
|
192
|
-
if klass.instance_methods.include?(meth)
|
193
|
-
valid = true
|
194
|
-
code << %{
|
195
|
-
#{meth}();
|
196
|
-
}
|
197
|
-
end
|
198
|
-
|
199
|
-
# call the programmatically generated template if exists.
|
200
|
-
if klass.instance_methods.include?("#{meth}__xml")
|
201
|
-
valid = true
|
202
|
-
code << %{
|
203
|
-
return unless #{meth}__xml();
|
204
|
-
}
|
205
|
-
end
|
206
|
-
|
207
|
-
# call the template
|
208
|
-
if template = template_for_method(base, meth, 'xml')
|
209
|
-
valid = true
|
210
|
-
code << %{
|
211
|
-
return unless __#{meth}_xml();
|
212
|
-
}
|
213
|
-
end
|
214
|
-
|
215
|
-
raise "Invalid method '#{meth}' for service #{klass}!" unless valid
|
216
|
-
|
217
|
-
# call 'after' filter chain.
|
218
|
-
if klass.respond_to?(:after_filters)
|
219
|
-
code << %{
|
220
|
-
#{klass.gen_filters_call_code(klass.after_filters)}
|
221
|
-
}
|
222
|
-
end
|
223
|
-
|
224
|
-
code << %{
|
225
|
-
end
|
226
|
-
}
|
227
|
-
|
228
|
-
if template
|
229
|
-
code << %{
|
230
|
-
def __#{meth}_xml
|
231
|
-
#{transform_template(template)}
|
232
|
-
end
|
233
|
-
}
|
234
|
-
end
|
235
|
-
|
236
|
-
klass.class_eval(code)
|
237
|
-
|
238
|
-
return "__rest_#{meth}"
|
239
|
-
end
|
240
|
-
|
241
|
-
def self.dump(str)
|
242
|
-
str.split("\n").each_with_index do |line, idx|
|
243
|
-
puts "#{idx+1}: #{line}"
|
244
|
-
end
|
245
|
-
end
|
246
|
-
end
|
247
|
-
|
248
|
-
# = RenderExit
|
249
|
-
#
|
250
|
-
# Raise this exception to stop rendering.
|
251
|
-
|
252
|
-
class RenderExit < Exception
|
253
|
-
end
|
254
|
-
|
255
|
-
# = Render
|
256
|
-
|
257
|
-
module Render
|
258
|
-
# The outbut buffer. The output of a script/action is accumulated
|
259
|
-
# in this buffer.
|
260
|
-
attr :out
|
261
|
-
|
262
|
-
# The parameters of this request as Hash.
|
263
|
-
attr_accessor :params
|
264
|
-
|
265
|
-
# The request.
|
266
|
-
attr_accessor :request
|
267
|
-
|
268
|
-
# The response.
|
269
|
-
attr_accessor :response
|
270
|
-
|
271
|
-
# The session contains variables that stay alive for the full
|
272
|
-
# user session.
|
273
|
-
attr_accessor :session
|
274
|
-
|
275
|
-
# An array holding the rendering errors for this
|
276
|
-
# request.
|
277
|
-
#
|
278
|
-
attr_accessor :rendering_errors
|
279
|
-
|
280
|
-
def initialize(base_path = '', request = nil, response = nil, session = nil)
|
281
|
-
@base_path = base_path
|
282
|
-
@request = request
|
283
|
-
@response = response
|
284
|
-
@session = session
|
285
|
-
@params = request.query
|
286
|
-
|
287
|
-
@out_buffers = nil
|
288
|
-
end
|
289
|
-
|
290
|
-
# Returns the output of the rendering as string.
|
291
|
-
#
|
292
|
-
def render(path, request = nil, response = nil, session = nil)
|
293
|
-
path, query_string = path.split('?')
|
294
|
-
|
295
|
-
@request ||= request
|
296
|
-
@response ||= response
|
297
|
-
@session ||= session
|
298
|
-
|
299
|
-
@params = @request.set_query(query_string) if query_string
|
300
|
-
|
301
|
-
base, render_class, meth = $methods[path]
|
302
|
-
|
303
|
-
unless meth
|
304
|
-
api, base, render_class, meth = RenderUtils.split_path(path)
|
305
|
-
|
306
|
-
raise "Invalid service!" unless render_class
|
307
|
-
|
308
|
-
case api
|
309
|
-
when :http
|
310
|
-
meth = RenderUtils.compile_http_method(render_class, base, meth)
|
311
|
-
when :rest
|
312
|
-
meth = RenderUtils.compile_rest_method(render_class, base, meth)
|
313
|
-
end
|
314
|
-
|
315
|
-
$methods[path] = [base, render_class, meth] unless $reload_scripts
|
316
|
-
end
|
317
|
-
|
318
|
-
begin
|
319
|
-
if self.class == render_class
|
320
|
-
self.send(meth)
|
321
|
-
else
|
322
|
-
=begin
|
323
|
-
gmosx: reolading fucks up validation and meta data propagation.
|
324
|
-
if $reload_scripts and defined?(render_class::SOURCE_FILE)
|
325
|
-
load(render_class::SOURCE_FILE)
|
326
|
-
end
|
327
|
-
=end
|
328
|
-
r = render_class.new(base, @request, @response, @session)
|
329
|
-
r.send(meth)
|
330
|
-
@out = r.out
|
331
|
-
end
|
332
|
-
rescue N::RenderExit => e
|
333
|
-
# Just stop rendering.
|
334
|
-
# For example called by redirects.
|
335
|
-
rescue Exception, StandardError => e
|
336
|
-
log_error "error while handling '#{path}'."
|
337
|
-
log_error pp_exception(e)
|
338
|
-
# more fault tolerant, only flags the erroneous box with
|
339
|
-
# error not the full page.
|
340
|
-
@out << '(error)'
|
341
|
-
end
|
342
|
-
|
343
|
-
# stop the filter pipeline
|
344
|
-
return false
|
345
|
-
end
|
346
|
-
|
347
|
-
# Render the referer of this method.
|
348
|
-
#
|
349
|
-
def render_referer
|
350
|
-
render(@request.referer.gsub(/#$srv_url/, ''))
|
351
|
-
end
|
352
|
-
|
353
|
-
# Send a redirect response.
|
354
|
-
#
|
355
|
-
def redirect(url, status = 303)
|
356
|
-
@response.status = status
|
357
|
-
@response.body = "<html><a href=\"#{url.to_s}\">#{url.to_s}</a>.</html>\n"
|
358
|
-
@response.header['location'] = url.to_s
|
359
|
-
|
360
|
-
# stop the rendering
|
361
|
-
raise N::RenderExit
|
362
|
-
end
|
363
|
-
|
364
|
-
# Redirect to the referer of this method.
|
365
|
-
#
|
366
|
-
def redirect_referer(postfix = nil, status = 303)
|
367
|
-
redirect("#{@request.referer}#{postfix}", status)
|
368
|
-
end
|
369
|
-
|
370
|
-
# Log a rendering error.
|
371
|
-
#--
|
372
|
-
# FIXME: find a better name
|
373
|
-
#++
|
374
|
-
def log_error(str)
|
375
|
-
@rendering_errors ||= []
|
376
|
-
@rendering_errors << str
|
377
|
-
Logger.error str
|
378
|
-
end
|
379
|
-
|
380
|
-
# --------------------------------------------------------------------
|
381
|
-
# Output buffering methods.
|
382
|
-
|
383
|
-
# Start (push) a new output buffer.
|
384
|
-
#
|
385
|
-
def ob_start
|
386
|
-
@out_buffers = [] unless @out_buffers
|
387
|
-
@out_buffers.push(@out)
|
388
|
-
@out = ''
|
389
|
-
end
|
390
|
-
|
391
|
-
# End (pop) the current output buffer.
|
392
|
-
#
|
393
|
-
def ob_end
|
394
|
-
@out = @out_buffers.pop
|
395
|
-
end
|
396
|
-
|
397
|
-
# End (pop) the current output buffer and write to the parent.
|
398
|
-
#
|
399
|
-
def ob_write_end
|
400
|
-
nested_buffer = @out
|
401
|
-
@out = @out_buffers.pop
|
402
|
-
@out << nested_buffer
|
403
|
-
end
|
404
|
-
|
405
|
-
# --------------------------------------------------------------------
|
406
|
-
# Caching methods.
|
407
|
-
|
408
|
-
#--
|
409
|
-
# FIXME: pseudocode, not working.
|
410
|
-
#++
|
411
|
-
def cache_start
|
412
|
-
valid?
|
413
|
-
ob_start
|
414
|
-
end
|
415
|
-
|
416
|
-
#--
|
417
|
-
# FIXME: pseudocode, not working.
|
418
|
-
#++
|
419
|
-
def cache_end
|
420
|
-
save_fragment(@out)
|
421
|
-
ob_write_end
|
422
|
-
end
|
423
|
-
end
|
424
|
-
|
425
|
-
end # module
|
426
|
-
|