innate 2012.03 → 2012.12
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/.travis.yml +0 -1
- data/AUTHORS +2 -2
- data/CHANGELOG +996 -887
- data/MANIFEST +2 -2
- data/example/custom_middleware.rb +12 -8
- data/innate.gemspec +7 -7
- data/lib/innate.rb +90 -88
- data/lib/innate/action.rb +4 -5
- data/lib/innate/default_middleware.rb +22 -0
- data/lib/innate/helper/aspect.rb +185 -22
- data/lib/innate/lru_hash.rb +113 -0
- data/lib/innate/node.rb +13 -8
- data/lib/innate/options.rb +2 -5
- data/lib/innate/spec/bacon.rb +6 -8
- data/lib/innate/version.rb +1 -1
- data/lib/innate/view/erb.rb +1 -2
- data/lib/innate/view/etanni.rb +1 -2
- data/spec/innate/helper/flash.rb +1 -1
- metadata +56 -76
- data/lib/innate/middleware_compiler.rb +0 -66
- data/lib/innate/rack_file_wrapper.rb +0 -24
data/MANIFEST
CHANGED
|
@@ -37,6 +37,7 @@ lib/innate/cache/marshal.rb
|
|
|
37
37
|
lib/innate/cache/memory.rb
|
|
38
38
|
lib/innate/cache/yaml.rb
|
|
39
39
|
lib/innate/current.rb
|
|
40
|
+
lib/innate/default_middleware.rb
|
|
40
41
|
lib/innate/dynamap.rb
|
|
41
42
|
lib/innate/helper.rb
|
|
42
43
|
lib/innate/helper/aspect.rb
|
|
@@ -48,13 +49,12 @@ lib/innate/helper/render.rb
|
|
|
48
49
|
lib/innate/log.rb
|
|
49
50
|
lib/innate/log/color_formatter.rb
|
|
50
51
|
lib/innate/log/hub.rb
|
|
51
|
-
lib/innate/
|
|
52
|
+
lib/innate/lru_hash.rb
|
|
52
53
|
lib/innate/mock.rb
|
|
53
54
|
lib/innate/node.rb
|
|
54
55
|
lib/innate/options.rb
|
|
55
56
|
lib/innate/options/dsl.rb
|
|
56
57
|
lib/innate/options/stub.rb
|
|
57
|
-
lib/innate/rack_file_wrapper.rb
|
|
58
58
|
lib/innate/request.rb
|
|
59
59
|
lib/innate/response.rb
|
|
60
60
|
lib/innate/route.rb
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
require 'rubygems'
|
|
2
|
-
require 'innate'
|
|
2
|
+
require File.expand_path('../../lib/innate', __FILE__)
|
|
3
3
|
|
|
4
4
|
class Demo
|
|
5
5
|
Innate.node '/'
|
|
@@ -14,22 +14,26 @@ class Demo
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
-
Innate.
|
|
17
|
+
Innate.options.mode = :dev
|
|
18
|
+
|
|
19
|
+
Innate.middleware(:dev) do
|
|
18
20
|
# Makes sure all requests and responses conform to Rack protocol
|
|
19
|
-
|
|
21
|
+
use Rack::Lint
|
|
20
22
|
|
|
21
23
|
# Avoid showing empty failure pages, give information when it happens.
|
|
22
|
-
|
|
24
|
+
use Rack::ShowStatus
|
|
23
25
|
|
|
24
26
|
# Catch exceptions inside Innate and give nice status info
|
|
25
|
-
|
|
27
|
+
use Rack::ShowExceptions
|
|
26
28
|
|
|
27
29
|
# Log access
|
|
28
|
-
|
|
30
|
+
use Rack::CommonLogger
|
|
29
31
|
|
|
30
32
|
# Reload modified files before request
|
|
31
|
-
|
|
33
|
+
use Rack::Reloader
|
|
32
34
|
|
|
33
35
|
# Start up the application
|
|
34
|
-
|
|
36
|
+
run Innate.core
|
|
35
37
|
end
|
|
38
|
+
|
|
39
|
+
Innate.start
|
data/innate.gemspec
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
Gem::Specification.new do |s|
|
|
4
4
|
s.name = "innate"
|
|
5
|
-
s.version = "2012.
|
|
5
|
+
s.version = "2012.12"
|
|
6
6
|
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.3.1") if s.respond_to? :required_rubygems_version=
|
|
8
8
|
s.authors = ["Michael 'manveru' Fellinger"]
|
|
9
|
-
s.date = "2012-
|
|
9
|
+
s.date = "2012-12-07"
|
|
10
10
|
s.description = "Simple, straight-forward base for web-frameworks."
|
|
11
11
|
s.email = "m.fellinger@gmail.com"
|
|
12
|
-
s.files = [".gems", ".gitignore", ".load_gemset", ".rvmrc", ".travis.yml", "AUTHORS", "CHANGELOG", "COPYING", "MANIFEST", "README.md", "Rakefile", "example/app/retro_games.rb", "example/app/todo/layout/default.xhtml", "example/app/todo/spec/todo.rb", "example/app/todo/start.rb", "example/app/todo/view/index.xhtml", "example/app/whywiki_erb/layout/wiki.html.erb", "example/app/whywiki_erb/spec/wiki.rb", "example/app/whywiki_erb/start.rb", "example/app/whywiki_erb/view/edit.erb", "example/app/whywiki_erb/view/index.erb", "example/custom_middleware.rb", "example/hello.rb", "example/howto_spec.rb", "example/link.rb", "example/provides.rb", "example/session.rb", "innate.gemspec", "lib/innate.rb", "lib/innate/action.rb", "lib/innate/adapter.rb", "lib/innate/cache.rb", "lib/innate/cache/api.rb", "lib/innate/cache/drb.rb", "lib/innate/cache/file_based.rb", "lib/innate/cache/marshal.rb", "lib/innate/cache/memory.rb", "lib/innate/cache/yaml.rb", "lib/innate/current.rb", "lib/innate/dynamap.rb", "lib/innate/helper.rb", "lib/innate/helper/aspect.rb", "lib/innate/helper/cgi.rb", "lib/innate/helper/flash.rb", "lib/innate/helper/link.rb", "lib/innate/helper/redirect.rb", "lib/innate/helper/render.rb", "lib/innate/log.rb", "lib/innate/log/color_formatter.rb", "lib/innate/log/hub.rb", "lib/innate/
|
|
12
|
+
s.files = [".gems", ".gitignore", ".load_gemset", ".rvmrc", ".travis.yml", "AUTHORS", "CHANGELOG", "COPYING", "MANIFEST", "README.md", "Rakefile", "example/app/retro_games.rb", "example/app/todo/layout/default.xhtml", "example/app/todo/spec/todo.rb", "example/app/todo/start.rb", "example/app/todo/view/index.xhtml", "example/app/whywiki_erb/layout/wiki.html.erb", "example/app/whywiki_erb/spec/wiki.rb", "example/app/whywiki_erb/start.rb", "example/app/whywiki_erb/view/edit.erb", "example/app/whywiki_erb/view/index.erb", "example/custom_middleware.rb", "example/hello.rb", "example/howto_spec.rb", "example/link.rb", "example/provides.rb", "example/session.rb", "innate.gemspec", "lib/innate.rb", "lib/innate/action.rb", "lib/innate/adapter.rb", "lib/innate/cache.rb", "lib/innate/cache/api.rb", "lib/innate/cache/drb.rb", "lib/innate/cache/file_based.rb", "lib/innate/cache/marshal.rb", "lib/innate/cache/memory.rb", "lib/innate/cache/yaml.rb", "lib/innate/current.rb", "lib/innate/default_middleware.rb", "lib/innate/dynamap.rb", "lib/innate/helper.rb", "lib/innate/helper/aspect.rb", "lib/innate/helper/cgi.rb", "lib/innate/helper/flash.rb", "lib/innate/helper/link.rb", "lib/innate/helper/redirect.rb", "lib/innate/helper/render.rb", "lib/innate/log.rb", "lib/innate/log/color_formatter.rb", "lib/innate/log/hub.rb", "lib/innate/lru_hash.rb", "lib/innate/mock.rb", "lib/innate/node.rb", "lib/innate/options.rb", "lib/innate/options/dsl.rb", "lib/innate/options/stub.rb", "lib/innate/request.rb", "lib/innate/response.rb", "lib/innate/route.rb", "lib/innate/session.rb", "lib/innate/session/flash.rb", "lib/innate/spec.rb", "lib/innate/spec/bacon.rb", "lib/innate/state.rb", "lib/innate/state/accessor.rb", "lib/innate/traited.rb", "lib/innate/trinity.rb", "lib/innate/version.rb", "lib/innate/view.rb", "lib/innate/view/erb.rb", "lib/innate/view/etanni.rb", "lib/innate/view/none.rb", "spec/example/app/retro_games.rb", "spec/example/hello.rb", "spec/example/link.rb", "spec/example/provides.rb", "spec/example/session.rb", "spec/helper.rb", "spec/innate/action/layout.rb", "spec/innate/action/layout/file_layout.xhtml", "spec/innate/cache/common.rb", "spec/innate/cache/marshal.rb", "spec/innate/cache/memory.rb", "spec/innate/cache/yaml.rb", "spec/innate/dynamap.rb", "spec/innate/etanni.rb", "spec/innate/helper.rb", "spec/innate/helper/aspect.rb", "spec/innate/helper/cgi.rb", "spec/innate/helper/flash.rb", "spec/innate/helper/link.rb", "spec/innate/helper/redirect.rb", "spec/innate/helper/render.rb", "spec/innate/helper/view/aspect_hello.xhtml", "spec/innate/helper/view/locals.xhtml", "spec/innate/helper/view/loop.xhtml", "spec/innate/helper/view/num.xhtml", "spec/innate/helper/view/partial.xhtml", "spec/innate/helper/view/recursive.xhtml", "spec/innate/mock.rb", "spec/innate/modes.rb", "spec/innate/node/mapping.rb", "spec/innate/node/node.rb", "spec/innate/node/resolve.rb", "spec/innate/node/view/another_layout/another_layout.xhtml", "spec/innate/node/view/bar.xhtml", "spec/innate/node/view/cat2/cat22.xhtml", "spec/innate/node/view/cat3/cat33.xhtml", "spec/innate/node/view/foo.html.xhtml", "spec/innate/node/view/only_view.xhtml", "spec/innate/node/view/sub/baz.xhtml", "spec/innate/node/view/sub/foo/baz.xhtml", "spec/innate/node/view/with_layout.xhtml", "spec/innate/node/wrap_action_call.rb", "spec/innate/options.rb", "spec/innate/parameter.rb", "spec/innate/provides.rb", "spec/innate/provides/list.html.xhtml", "spec/innate/provides/list.txt.xhtml", "spec/innate/request.rb", "spec/innate/response.rb", "spec/innate/route.rb", "spec/innate/session.rb", "spec/innate/traited.rb", "tasks/authors.rake", "tasks/bacon.rake", "tasks/changelog.rake", "tasks/gem.rake", "tasks/gem_setup.rake", "tasks/grancher.rake", "tasks/manifest.rake", "tasks/rcov.rake", "tasks/release.rake", "tasks/reversion.rake", "tasks/setup.rake", "tasks/ycov.rake"]
|
|
13
13
|
s.homepage = "http://github.com/manveru/innate"
|
|
14
14
|
s.require_paths = ["lib"]
|
|
15
15
|
s.rubyforge_project = "innate"
|
|
16
|
-
s.rubygems_version = "1.8.
|
|
16
|
+
s.rubygems_version = "1.8.24"
|
|
17
17
|
s.summary = "Powerful web-framework wrapper for Rack."
|
|
18
18
|
|
|
19
19
|
if s.respond_to? :specification_version then
|
|
@@ -21,16 +21,16 @@ Gem::Specification.new do |s|
|
|
|
21
21
|
|
|
22
22
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
|
23
23
|
s.add_runtime_dependency(%q<rack>, ["~> 1.4.1"])
|
|
24
|
-
s.add_development_dependency(%q<rack-test>, [">= 0.6.1"])
|
|
25
24
|
s.add_development_dependency(%q<bacon>, [">= 1.1.0"])
|
|
25
|
+
s.add_development_dependency(%q<rack-test>, [">= 0.6.1"])
|
|
26
26
|
else
|
|
27
27
|
s.add_dependency(%q<rack>, ["~> 1.4.1"])
|
|
28
|
-
s.add_dependency(%q<rack-test>, [">= 0.6.1"])
|
|
29
28
|
s.add_dependency(%q<bacon>, [">= 1.1.0"])
|
|
29
|
+
s.add_dependency(%q<rack-test>, [">= 0.6.1"])
|
|
30
30
|
end
|
|
31
31
|
else
|
|
32
32
|
s.add_dependency(%q<rack>, ["~> 1.4.1"])
|
|
33
|
-
s.add_dependency(%q<rack-test>, [">= 0.6.1"])
|
|
34
33
|
s.add_dependency(%q<bacon>, [">= 1.1.0"])
|
|
34
|
+
s.add_dependency(%q<rack-test>, [">= 0.6.1"])
|
|
35
35
|
end
|
|
36
36
|
end
|
data/lib/innate.rb
CHANGED
|
@@ -22,7 +22,6 @@ module Innate
|
|
|
22
22
|
require 'pathname'
|
|
23
23
|
require 'pp'
|
|
24
24
|
require 'set'
|
|
25
|
-
require 'socket'
|
|
26
25
|
require 'thread'
|
|
27
26
|
require 'uri'
|
|
28
27
|
|
|
@@ -33,12 +32,12 @@ module Innate
|
|
|
33
32
|
require 'innate/version'
|
|
34
33
|
require 'innate/traited'
|
|
35
34
|
require 'innate/trinity'
|
|
36
|
-
require 'innate/middleware_compiler'
|
|
37
35
|
require 'innate/options/dsl'
|
|
38
36
|
require 'innate/options/stub'
|
|
39
37
|
require 'innate/dynamap'
|
|
40
38
|
|
|
41
39
|
# innate full
|
|
40
|
+
require 'innate/lru_hash'
|
|
42
41
|
require 'innate/cache'
|
|
43
42
|
require 'innate/node'
|
|
44
43
|
require 'innate/options'
|
|
@@ -53,15 +52,30 @@ module Innate
|
|
|
53
52
|
require 'innate/session'
|
|
54
53
|
require 'innate/session/flash'
|
|
55
54
|
require 'innate/route'
|
|
56
|
-
require 'innate/rack_file_wrapper'
|
|
57
55
|
|
|
58
56
|
extend Trinity
|
|
59
57
|
|
|
58
|
+
##
|
|
59
|
+
# Hash that will contain the middleware for each defined mode.
|
|
60
|
+
#
|
|
61
|
+
# @return [Hash]
|
|
62
|
+
#
|
|
63
|
+
MIDDLEWARE = {}
|
|
64
|
+
|
|
60
65
|
# Contains all the module functions for Innate, we keep them in a module so
|
|
61
66
|
# Ramaze can simply use them as well.
|
|
62
67
|
module SingletonMethods
|
|
63
68
|
PROXY_OPTIONS = { :port => 'adapter.port', :host => 'adapter.host',
|
|
64
69
|
:adapter => 'adapter.handler' }
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# Returns an instance of `Rack::Builder` that can be used to start a Innate
|
|
73
|
+
# application.
|
|
74
|
+
#
|
|
75
|
+
# @return [Rack::Builder]
|
|
76
|
+
#
|
|
77
|
+
attr_accessor :app
|
|
78
|
+
|
|
65
79
|
# The method that starts the whole business.
|
|
66
80
|
#
|
|
67
81
|
# Call Innate.start after you defined your application.
|
|
@@ -78,14 +92,7 @@ module Innate
|
|
|
78
92
|
# # passing options
|
|
79
93
|
# Innate.start :adapter => :mongrel, :mode => :live
|
|
80
94
|
#
|
|
81
|
-
# # defining custom middleware
|
|
82
|
-
# Innate.start do |m|
|
|
83
|
-
# m.innate
|
|
84
|
-
# end
|
|
85
|
-
#
|
|
86
95
|
# @return [nil] if options.started is true
|
|
87
|
-
# @yield [MiddlewareCompiler]
|
|
88
|
-
# @param [Proc] block will be passed to {middleware!}
|
|
89
96
|
#
|
|
90
97
|
# @option param :host [String] ('0.0.0.0')
|
|
91
98
|
# IP address or hostname that we respond to - 0.0.0.0 for all
|
|
@@ -103,7 +110,7 @@ module Innate
|
|
|
103
110
|
# Trap this signal to issue shutdown, nil/false to disable trap
|
|
104
111
|
# @option param :mode [Symbol] (:dev)
|
|
105
112
|
# Indicates which default middleware to use, (:dev|:live)
|
|
106
|
-
def start(options = {}
|
|
113
|
+
def start(options = {})
|
|
107
114
|
root, file = options.delete(:root), options.delete(:file)
|
|
108
115
|
innate_options = Innate.options
|
|
109
116
|
|
|
@@ -118,19 +125,33 @@ module Innate
|
|
|
118
125
|
innate_options.merge!(options)
|
|
119
126
|
|
|
120
127
|
setup_dependencies
|
|
121
|
-
middleware!(innate_options.mode, &block) if block_given?
|
|
122
128
|
|
|
123
129
|
return if innate_options.started
|
|
130
|
+
|
|
124
131
|
innate_options.started = true
|
|
125
132
|
|
|
126
133
|
signal = innate_options.trap
|
|
134
|
+
|
|
127
135
|
trap(signal){ stop(10) } if signal
|
|
128
136
|
|
|
137
|
+
mode = self.options[:mode].to_sym
|
|
138
|
+
|
|
139
|
+
# While Rack itself will spit out errors for invalid instances of
|
|
140
|
+
# Rack::Builder these errors are typically not very user friendly.
|
|
141
|
+
if !Innate.app or !MIDDLEWARE[mode]
|
|
142
|
+
raise(
|
|
143
|
+
ArgumentError,
|
|
144
|
+
"The mode \"#{mode}\" does not have a set of middleware defined. " \
|
|
145
|
+
"You can define these middleware using " \
|
|
146
|
+
"#{self}.middleware(:#{mode}) { ... }"
|
|
147
|
+
)
|
|
148
|
+
end
|
|
149
|
+
|
|
129
150
|
start!
|
|
130
151
|
end
|
|
131
152
|
|
|
132
153
|
def start!(mode = options[:mode])
|
|
133
|
-
Adapter.start(
|
|
154
|
+
Adapter.start(Innate.app)
|
|
134
155
|
end
|
|
135
156
|
|
|
136
157
|
def stop(wait = 3)
|
|
@@ -149,6 +170,10 @@ module Innate
|
|
|
149
170
|
options[:setup].each{|obj| obj.teardown if obj.respond_to?(:teardown) }
|
|
150
171
|
end
|
|
151
172
|
|
|
173
|
+
def setup
|
|
174
|
+
options.mode ||= (ENV['RACK_ENV'] || :dev)
|
|
175
|
+
end
|
|
176
|
+
|
|
152
177
|
# Treat Innate like a rack application, pass the rack +env+ and optionally
|
|
153
178
|
# the +mode+ the application runs in.
|
|
154
179
|
#
|
|
@@ -157,20 +182,63 @@ module Innate
|
|
|
157
182
|
# @default mode options.mode
|
|
158
183
|
# @return [Array] with [body, header, status]
|
|
159
184
|
# @author manveru
|
|
160
|
-
def call(env
|
|
161
|
-
|
|
185
|
+
def call(env)
|
|
186
|
+
Innate.app.call(env)
|
|
162
187
|
end
|
|
163
188
|
|
|
164
|
-
|
|
165
|
-
|
|
189
|
+
##
|
|
190
|
+
# Updates `Innate.app` based on the current mode.
|
|
191
|
+
#
|
|
192
|
+
# @param [#to_sym] mode The mode to use.
|
|
193
|
+
#
|
|
194
|
+
def recompile_middleware(mode = options[:mode])
|
|
195
|
+
mode = mode.to_sym
|
|
196
|
+
|
|
197
|
+
if MIDDLEWARE[mode]
|
|
198
|
+
Innate.app = Rack::Builder.new(&MIDDLEWARE[mode])
|
|
199
|
+
end
|
|
166
200
|
end
|
|
167
201
|
|
|
168
|
-
|
|
169
|
-
|
|
202
|
+
##
|
|
203
|
+
# Returns an instance of `Rack::Cascade` for running Innate applications.
|
|
204
|
+
# This method should be called using `Rack::Builder#run`:
|
|
205
|
+
#
|
|
206
|
+
# Innate.middleware(:dev) do
|
|
207
|
+
# run Innate.core
|
|
208
|
+
# end
|
|
209
|
+
#
|
|
210
|
+
# @return [Rack::Cascade]
|
|
211
|
+
#
|
|
212
|
+
def core
|
|
213
|
+
roots, publics = options[:roots], options[:publics]
|
|
214
|
+
|
|
215
|
+
joined = roots.map { |root| publics.map { |p| File.join(root, p) } }
|
|
216
|
+
joined = joined.flatten.map { |p| Rack::File.new(p) }
|
|
217
|
+
current = Current.new(Route.new(DynaMap), Rewrite.new(DynaMap))
|
|
218
|
+
|
|
219
|
+
return Rack::Cascade.new(joined << current, [404, 405])
|
|
170
220
|
end
|
|
171
221
|
|
|
172
|
-
|
|
173
|
-
|
|
222
|
+
##
|
|
223
|
+
# Sets the middleware for the given mode.
|
|
224
|
+
#
|
|
225
|
+
# @example
|
|
226
|
+
# Innate.middleware(:dev) do
|
|
227
|
+
# use Rack::Head
|
|
228
|
+
# use Rack::Reloader
|
|
229
|
+
#
|
|
230
|
+
# run Innate.core
|
|
231
|
+
# end
|
|
232
|
+
#
|
|
233
|
+
# @param [#to_sym] mode The mode that the middleware belong to.
|
|
234
|
+
# @param [Proc] block Block containing the middleware. This block will be
|
|
235
|
+
# passed to an instance of `Rack::Builder` and can thus contain everything
|
|
236
|
+
# this class allows you to use.
|
|
237
|
+
#
|
|
238
|
+
def middleware(mode, &block)
|
|
239
|
+
MIDDLEWARE[mode.to_sym] = block
|
|
240
|
+
|
|
241
|
+
recompile_middleware
|
|
174
242
|
end
|
|
175
243
|
|
|
176
244
|
# @example Innate can be started by:
|
|
@@ -200,71 +268,5 @@ module Innate
|
|
|
200
268
|
|
|
201
269
|
extend SingletonMethods
|
|
202
270
|
|
|
203
|
-
|
|
204
|
-
# The Proc to use is determined by the value of options.mode.
|
|
205
|
-
# The Proc value is passed to setup_middleware if no block is given to
|
|
206
|
-
# Innate::start.
|
|
207
|
-
#
|
|
208
|
-
# A quick overview over the middleware used here:
|
|
209
|
-
#
|
|
210
|
-
# * Rack::CommonLogger
|
|
211
|
-
# Logs a line in Apache common log format or <tt>rack.errors</tt>.
|
|
212
|
-
#
|
|
213
|
-
# * Rack::ShowExceptions
|
|
214
|
-
# Catches all exceptions raised from the app it wraps. It shows a useful
|
|
215
|
-
# backtrace with the sourcefile and clickable context, the whole Rack
|
|
216
|
-
# environment and the request data.
|
|
217
|
-
# Be careful when you use this on public-facing sites as it could reveal
|
|
218
|
-
# information helpful to attackers.
|
|
219
|
-
#
|
|
220
|
-
# * Rack::ShowStatus
|
|
221
|
-
# Catches all empty responses the app it wraps and replaces them with a
|
|
222
|
-
# site explaining the error.
|
|
223
|
-
# Additional details can be put into <tt>rack.showstatus.detail</tt> and
|
|
224
|
-
# will be shown as HTML. If such details exist, the error page is always
|
|
225
|
-
# rendered, even if the reply was not empty.
|
|
226
|
-
#
|
|
227
|
-
# * Rack::ConditionalGet
|
|
228
|
-
# Middleware that enables conditional GET using If-None-Match and
|
|
229
|
-
# If-Modified-Since. The application should set either or both of the
|
|
230
|
-
# Last-Modified or Etag response headers according to RFC 2616. When
|
|
231
|
-
# either of the conditions is met, the response body is set to be zero
|
|
232
|
-
# length and the response status is set to 304 Not Modified.
|
|
233
|
-
#
|
|
234
|
-
# * Rack::Head
|
|
235
|
-
# Removes the body of the response for HEAD requests.
|
|
236
|
-
#
|
|
237
|
-
# * Rack::Reloader
|
|
238
|
-
# Pure ruby source reloader, runs on every request with a configurable
|
|
239
|
-
# cooldown period.
|
|
240
|
-
#
|
|
241
|
-
# * Rack::Lint
|
|
242
|
-
# Rack::Lint validates your application and the requests and responses
|
|
243
|
-
# according to the Rack spec.
|
|
244
|
-
#
|
|
245
|
-
# Note that `m.innate` takes away most of the boring part and leaves it up to
|
|
246
|
-
# you to select your middleware in your application.
|
|
247
|
-
#
|
|
248
|
-
# `m.innate` expands to:
|
|
249
|
-
#
|
|
250
|
-
# use Rack::Cascade.new([
|
|
251
|
-
# Rack::File.new('public'),
|
|
252
|
-
# Innate::Current.new(
|
|
253
|
-
# Rack::Cascade.new([
|
|
254
|
-
# Innate::Rewrite.new(Innate::DynaMap),
|
|
255
|
-
# Innate::Route.new(Innate::DynaMap)]))])
|
|
256
|
-
#
|
|
257
|
-
# @see Rack::MiddlewareCompiler
|
|
258
|
-
middleware :dev do |m|
|
|
259
|
-
m.apps(Rack::Lint, Rack::Head, Rack::ContentLength, Rack::CommonLogger,
|
|
260
|
-
Rack::ShowExceptions, Rack::ShowStatus, Rack::ConditionalGet)
|
|
261
|
-
m.use(Rack::Reloader, 2)
|
|
262
|
-
m.innate
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
middleware :live do |m|
|
|
266
|
-
m.apps(Rack::Head, Rack::ContentLength, Rack::CommonLogger,
|
|
267
|
-
Rack::ShowStatus, Rack::ConditionalGet)
|
|
268
|
-
m.innate
|
|
269
|
-
end
|
|
271
|
+
require 'innate/default_middleware'
|
|
270
272
|
end
|
data/lib/innate/action.rb
CHANGED
|
@@ -82,12 +82,11 @@ module Innate
|
|
|
82
82
|
|
|
83
83
|
instance.wrap_action_call(self) do
|
|
84
84
|
copy_variables
|
|
85
|
-
self.method_value = instance.__send__(method, *params)
|
|
86
|
-
self.view_value = View.read(view)
|
|
85
|
+
self.method_value = method ? instance.__send__(method, *params) : nil
|
|
86
|
+
self.view_value = view ? View.read(view) : nil
|
|
87
87
|
|
|
88
|
-
body, content_type = wrap_in_layout{
|
|
89
|
-
|
|
90
|
-
options[:content_type] ||= content_type if content_type
|
|
88
|
+
body, content_type = wrap_in_layout{ engine.call(self, view_value || method_value || '') }
|
|
89
|
+
options[:content_type] ||= content_type
|
|
91
90
|
body
|
|
92
91
|
end
|
|
93
92
|
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Innate.middleware(:dev) do
|
|
2
|
+
use Rack::Lint
|
|
3
|
+
use Rack::Head
|
|
4
|
+
use Rack::ContentLength
|
|
5
|
+
use Rack::CommonLogger
|
|
6
|
+
use Rack::ShowExceptions
|
|
7
|
+
use Rack::ShowStatus
|
|
8
|
+
use Rack::ConditionalGet
|
|
9
|
+
use Rack::Reloader, 2
|
|
10
|
+
|
|
11
|
+
run Innate.core
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
Innate.middleware(:live) do
|
|
15
|
+
use Rack::Head
|
|
16
|
+
use Rack::ContentLength
|
|
17
|
+
use Rack::CommonLogger
|
|
18
|
+
use Rack::ShowStatus
|
|
19
|
+
use Rack::ConditionalGet
|
|
20
|
+
|
|
21
|
+
run Innate.core
|
|
22
|
+
end
|
data/lib/innate/helper/aspect.rb
CHANGED
|
@@ -1,12 +1,45 @@
|
|
|
1
1
|
module Innate
|
|
2
2
|
module Helper
|
|
3
|
-
|
|
4
|
-
#
|
|
3
|
+
##
|
|
4
|
+
# The Aspect helper allows you to execute hooks before or after a number of
|
|
5
|
+
# actions.
|
|
6
|
+
#
|
|
7
|
+
# See {Innate::Helper::Aspect::SingletonMethods} for more details on the
|
|
8
|
+
# various hooks available.
|
|
9
|
+
#
|
|
10
|
+
# @example Querying a database before a number of actions.
|
|
11
|
+
# class Posts
|
|
12
|
+
# include Innate::Node
|
|
13
|
+
#
|
|
14
|
+
# map '/'
|
|
15
|
+
# helper :aspect
|
|
16
|
+
#
|
|
17
|
+
# before(:index, :other) do
|
|
18
|
+
# @posts = Post.all
|
|
19
|
+
# end
|
|
20
|
+
#
|
|
21
|
+
# def index
|
|
22
|
+
# return @posts
|
|
23
|
+
# end
|
|
24
|
+
#
|
|
25
|
+
# def other
|
|
26
|
+
# return @posts[0]
|
|
27
|
+
# end
|
|
28
|
+
# end
|
|
5
29
|
#
|
|
6
30
|
# This helper is essential for proper working of {Action#render}.
|
|
31
|
+
#
|
|
7
32
|
module Aspect
|
|
8
|
-
|
|
33
|
+
##
|
|
34
|
+
# Hash containing the various hooks to call for certain actions.
|
|
35
|
+
#
|
|
36
|
+
AOP = Hash.new { |h,k| h[k] = Hash.new { |hh,kk| hh[kk] = {} } }
|
|
9
37
|
|
|
38
|
+
##
|
|
39
|
+
# Called whenever this helper is included into a class.
|
|
40
|
+
#
|
|
41
|
+
# @param [Class] into The class the module was included into.
|
|
42
|
+
#
|
|
10
43
|
def self.included(into)
|
|
11
44
|
into.extend(SingletonMethods)
|
|
12
45
|
into.add_action_wrapper(5.0, :aspect_wrap)
|
|
@@ -15,10 +48,16 @@ module Innate
|
|
|
15
48
|
# Consider objects that have Aspect included
|
|
16
49
|
def self.ancestral_aop(from)
|
|
17
50
|
aop = {}
|
|
18
|
-
from.ancestors.reverse.map{|anc| aop.merge!(AOP[anc]) if anc < Aspect }
|
|
51
|
+
from.ancestors.reverse.map { |anc| aop.merge!(AOP[anc]) if anc < Aspect }
|
|
19
52
|
aop
|
|
20
53
|
end
|
|
21
54
|
|
|
55
|
+
##
|
|
56
|
+
# Calls the aspect for a given position and name.
|
|
57
|
+
#
|
|
58
|
+
# @param [#to_sym] position The position of the hook, e.g. :before_all.
|
|
59
|
+
# @param [#to_sym] name The name of the method for which to call the hook.
|
|
60
|
+
#
|
|
22
61
|
def aspect_call(position, name)
|
|
23
62
|
return unless aop = Aspect.ancestral_aop(self.class)
|
|
24
63
|
return unless block = at_position = aop[position]
|
|
@@ -28,6 +67,11 @@ module Innate
|
|
|
28
67
|
instance_eval(&block) if block
|
|
29
68
|
end
|
|
30
69
|
|
|
70
|
+
##
|
|
71
|
+
# Wraps the specified action between various hooks.
|
|
72
|
+
#
|
|
73
|
+
# @param [Innate::Action] action The action to wrap.
|
|
74
|
+
#
|
|
31
75
|
def aspect_wrap(action)
|
|
32
76
|
return yield unless method = action.name
|
|
33
77
|
|
|
@@ -40,20 +84,21 @@ module Innate
|
|
|
40
84
|
result
|
|
41
85
|
end
|
|
42
86
|
|
|
87
|
+
##
|
|
43
88
|
# This awesome piece of hackery implements action AOP.
|
|
44
89
|
#
|
|
45
90
|
# The so-called aspects are simply methods that may yield the next aspect
|
|
46
|
-
# in the chain, this is similar to racks concept of middleware, but
|
|
47
|
-
# of initializing with an app we simply pass a block that may be
|
|
48
|
-
# with the action being processed.
|
|
91
|
+
# in the chain, this is similar to racks concept of middleware, but
|
|
92
|
+
# instead of initializing with an app we simply pass a block that may be
|
|
93
|
+
# yielded with the action being processed.
|
|
49
94
|
#
|
|
50
|
-
# This gives us things like logging, caching, aspects, authentication,
|
|
95
|
+
# This gives us things like logging, caching, aspects, authentication,
|
|
96
|
+
# etc.
|
|
51
97
|
#
|
|
52
|
-
# Add the name of your method to the trait[:wrap] to add your own method
|
|
53
|
-
# the wrap_action_call chain.
|
|
98
|
+
# Add the name of your method to the trait[:wrap] to add your own method
|
|
99
|
+
# to the wrap_action_call chain.
|
|
54
100
|
#
|
|
55
101
|
# @example adding your method
|
|
56
|
-
#
|
|
57
102
|
# class MyNode
|
|
58
103
|
# Innate.node '/'
|
|
59
104
|
#
|
|
@@ -68,16 +113,17 @@ module Innate
|
|
|
68
113
|
# end
|
|
69
114
|
#
|
|
70
115
|
#
|
|
71
|
-
# methods may register
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
# to continue the chain.
|
|
75
|
-
#
|
|
76
|
-
# @param [Action] action instance that is being passed to every registered method
|
|
77
|
-
# @param [Proc] block contains the instructions to call the action method if any
|
|
116
|
+
# methods may register themself in the trait[:wrap] and will be called in
|
|
117
|
+
# left-to-right order, each being passed the action instance and a block
|
|
118
|
+
# that they have to yield to continue the chain.
|
|
78
119
|
#
|
|
120
|
+
# @param [Action] action instance that is being passed to every registered
|
|
121
|
+
# method
|
|
122
|
+
# @param [Proc] block contains the instructions to call the action method
|
|
123
|
+
# if any
|
|
79
124
|
# @see Action#render
|
|
80
125
|
# @author manveru
|
|
126
|
+
#
|
|
81
127
|
def wrap_action_call(action, &block)
|
|
82
128
|
return yield if action.options[:is_layout]
|
|
83
129
|
wrap = SortedSet.new
|
|
@@ -88,25 +134,142 @@ module Innate
|
|
|
88
134
|
__send__(head, action, &combined)
|
|
89
135
|
end
|
|
90
136
|
|
|
137
|
+
##
|
|
138
|
+
# Module containing various methods that will be made available as class
|
|
139
|
+
# methods to the class that included {Innate::Helper::Aspect}.
|
|
140
|
+
#
|
|
91
141
|
module SingletonMethods
|
|
92
142
|
include Traited
|
|
93
143
|
|
|
144
|
+
##
|
|
145
|
+
# Hook that is called before all the actions in a node.
|
|
146
|
+
#
|
|
147
|
+
# @example
|
|
148
|
+
# class MainController
|
|
149
|
+
# include Innate::Node
|
|
150
|
+
#
|
|
151
|
+
# map '/'
|
|
152
|
+
#
|
|
153
|
+
# helper :aspect
|
|
154
|
+
#
|
|
155
|
+
# before_all do
|
|
156
|
+
# puts 'Executed before all actions'
|
|
157
|
+
# end
|
|
158
|
+
#
|
|
159
|
+
# def index
|
|
160
|
+
# return 'Hello, Innate!'
|
|
161
|
+
# end
|
|
162
|
+
# end
|
|
163
|
+
#
|
|
94
164
|
def before_all(&block)
|
|
95
165
|
AOP[self][:before_all] = block
|
|
96
166
|
end
|
|
97
167
|
|
|
168
|
+
##
|
|
169
|
+
# Hook that is called before a specific list of actions.
|
|
170
|
+
#
|
|
171
|
+
# @example
|
|
172
|
+
# class MainController
|
|
173
|
+
# include Innate::Node
|
|
174
|
+
#
|
|
175
|
+
# map '/'
|
|
176
|
+
#
|
|
177
|
+
# helper :aspect
|
|
178
|
+
#
|
|
179
|
+
# before(:index, :other) do
|
|
180
|
+
# puts 'Executed before specific actions only.'
|
|
181
|
+
# end
|
|
182
|
+
#
|
|
183
|
+
# def index
|
|
184
|
+
# return 'Hello, Innate!'
|
|
185
|
+
# end
|
|
186
|
+
#
|
|
187
|
+
# def other
|
|
188
|
+
# return 'Other method'
|
|
189
|
+
# end
|
|
190
|
+
# end
|
|
191
|
+
#
|
|
98
192
|
def before(*names, &block)
|
|
99
193
|
names.each{|name| AOP[self][:before][name] = block }
|
|
100
194
|
end
|
|
101
195
|
|
|
196
|
+
##
|
|
197
|
+
# Hook that is called after all the actions in a node.
|
|
198
|
+
#
|
|
199
|
+
# @example
|
|
200
|
+
# class MainController
|
|
201
|
+
# include Innate::Node
|
|
202
|
+
#
|
|
203
|
+
# map '/'
|
|
204
|
+
#
|
|
205
|
+
# helper :aspect
|
|
206
|
+
#
|
|
207
|
+
# after_all do
|
|
208
|
+
# puts 'Executed after all actions'
|
|
209
|
+
# end
|
|
210
|
+
#
|
|
211
|
+
# def index
|
|
212
|
+
# return 'Hello, Innate!'
|
|
213
|
+
# end
|
|
214
|
+
# end
|
|
215
|
+
#
|
|
102
216
|
def after_all(&block)
|
|
103
217
|
AOP[self][:after_all] = block
|
|
104
218
|
end
|
|
105
219
|
|
|
220
|
+
##
|
|
221
|
+
# Hook that is called after a specific list of actions.
|
|
222
|
+
#
|
|
223
|
+
# @example
|
|
224
|
+
# class MainController
|
|
225
|
+
# include Innate::Node
|
|
226
|
+
#
|
|
227
|
+
# map '/'
|
|
228
|
+
#
|
|
229
|
+
# helper :aspect
|
|
230
|
+
#
|
|
231
|
+
# after(:index, :other) do
|
|
232
|
+
# puts 'Executed after specific actions only.'
|
|
233
|
+
# end
|
|
234
|
+
#
|
|
235
|
+
# def index
|
|
236
|
+
# return 'Hello, Innate!'
|
|
237
|
+
# end
|
|
238
|
+
#
|
|
239
|
+
# def other
|
|
240
|
+
# return 'Other method'
|
|
241
|
+
# end
|
|
242
|
+
# end
|
|
243
|
+
#
|
|
106
244
|
def after(*names, &block)
|
|
107
245
|
names.each{|name| AOP[self][:after][name] = block }
|
|
108
246
|
end
|
|
109
247
|
|
|
248
|
+
##
|
|
249
|
+
# Wraps the block around the list of actions resulting in the block
|
|
250
|
+
# being called both before and after each action.
|
|
251
|
+
#
|
|
252
|
+
# @example
|
|
253
|
+
# class MainController
|
|
254
|
+
# include Innate::Node
|
|
255
|
+
#
|
|
256
|
+
# map '/'
|
|
257
|
+
#
|
|
258
|
+
# helper :aspect
|
|
259
|
+
#
|
|
260
|
+
# wrap(:index) do
|
|
261
|
+
# puts 'Wrapped around the index method'
|
|
262
|
+
# end
|
|
263
|
+
#
|
|
264
|
+
# def index
|
|
265
|
+
# return 'Hello, Innate!'
|
|
266
|
+
# end
|
|
267
|
+
#
|
|
268
|
+
# def other
|
|
269
|
+
# return 'Other method'
|
|
270
|
+
# end
|
|
271
|
+
# end
|
|
272
|
+
#
|
|
110
273
|
def wrap(*names, &block)
|
|
111
274
|
before(*names, &block)
|
|
112
275
|
after(*names, &block)
|
|
@@ -119,7 +282,7 @@ module Innate
|
|
|
119
282
|
trait :wrap => SortedSet[[order, method_name.to_s]]
|
|
120
283
|
end
|
|
121
284
|
end
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
285
|
+
end # SingletonMethods
|
|
286
|
+
end # Aspect
|
|
287
|
+
end # Helper
|
|
288
|
+
end # Innate
|