nitro 0.8.0 → 0.9.3
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/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
|
-
|