rocketio 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/lib/rocketio.rb +6 -3
- data/lib/rocketio/application.rb +3 -7
- data/lib/rocketio/controller.rb +62 -90
- data/lib/rocketio/controller/authentication.rb +38 -44
- data/lib/rocketio/controller/authorization.rb +8 -4
- data/lib/rocketio/controller/error_handlers.rb +12 -8
- data/lib/rocketio/controller/filters.rb +14 -19
- data/lib/rocketio/controller/helpers.rb +1 -1
- data/lib/rocketio/controller/middleware.rb +1 -1
- data/lib/rocketio/controller/render/engine.rb +3 -3
- data/lib/rocketio/controller/render/layout.rb +1 -1
- data/lib/rocketio/controller/render/layouts.rb +6 -6
- data/lib/rocketio/controller/render/template_vars.rb +3 -3
- data/lib/rocketio/controller/render/templates.rb +6 -6
- data/lib/rocketio/controller/sessions.rb +1 -1
- data/lib/rocketio/error_templates/409.html +11 -7
- data/lib/rocketio/error_templates/501.html +4 -4
- data/lib/rocketio/router.rb +35 -21
- data/lib/rocketio/version.rb +1 -1
- data/rocketio.gemspec +2 -0
- data/test/aliases_test.rb +2 -2
- data/test/api_test.rb +24 -117
- data/test/authentication_test.rb +96 -60
- data/test/authorization_test.rb +28 -17
- data/test/cache_control_test.rb +12 -12
- data/test/content_type_test.rb +7 -7
- data/test/cookies_test.rb +4 -4
- data/test/error_handlers_test.rb +14 -12
- data/test/etag_test.rb +32 -32
- data/test/filters_test.rb +96 -79
- data/test/halt_test.rb +1 -1
- data/test/helpers_test.rb +6 -6
- data/test/middleware_test.rb +4 -4
- data/test/redirect_test.rb +6 -7
- data/test/render/{post.erb → b.erb} +0 -0
- data/test/render/{put.erb → c.erb} +0 -0
- data/test/render/engine_test.rb +5 -5
- data/test/render/{get.erb → index.erb} +0 -0
- data/test/render/layout_test.rb +21 -17
- data/test/render/layouts_test.rb +14 -14
- data/test/render/render_test.rb +17 -14
- data/test/render/template_vars_test.rb +9 -9
- data/test/render/templates_test.rb +16 -16
- data/test/response_test.rb +4 -4
- data/test/routes_test.rb +21 -42
- data/test/sendfile_test.rb +8 -8
- data/test/sessions_test.rb +27 -27
- data/test/setup.rb +2 -0
- metadata +34 -6
@@ -13,8 +13,8 @@ module RocketIO
|
|
13
13
|
#
|
14
14
|
def self.token_auth *args, &block
|
15
15
|
opts = args.last.is_a?(Hash) ? args.pop : {}
|
16
|
-
(args.any? ? args.map
|
17
|
-
(@__token_auth__ ||= {})[
|
16
|
+
(args.any? ? args.map(&:to_sym) : [:*]).each do |method|
|
17
|
+
(@__token_auth__ ||= {})[method] = {
|
18
18
|
realm: opts[:realm] || RocketIO::DEFAULT_TOKEN_AUTH_REALM.freeze,
|
19
19
|
block: block
|
20
20
|
}
|
@@ -25,13 +25,13 @@ module RocketIO
|
|
25
25
|
def self.define_token_auth_methods source = self
|
26
26
|
prompts = allocate.token_auth.merge(source.instance_variable_get(:@__token_auth__) || {}).freeze
|
27
27
|
return if prompts.empty?
|
28
|
-
|
28
|
+
api.delete define_method(:token_auth) {prompts}
|
29
29
|
end
|
30
30
|
|
31
31
|
def token_auth; RocketIO::EMPTY_HASH end
|
32
32
|
|
33
33
|
def validate_or_request_authorization_if_needed
|
34
|
-
return unless auth =
|
34
|
+
return unless auth = authorization_required?
|
35
35
|
return if validate_token_auth(&auth[:block])
|
36
36
|
throw(:__response__, request_token_auth(auth[:realm]))
|
37
37
|
end
|
@@ -47,5 +47,9 @@ module RocketIO
|
|
47
47
|
def request_token_auth realm = RocketIO::DEFAULT_TOKEN_AUTH_REALM
|
48
48
|
RocketIO::TokenAuth.authentication_request(realm)
|
49
49
|
end
|
50
|
+
|
51
|
+
def authorization_required?
|
52
|
+
token_auth[requested_method] || token_auth[:*]
|
53
|
+
end
|
50
54
|
end
|
51
55
|
end
|
@@ -38,12 +38,12 @@ module RocketIO
|
|
38
38
|
def self.define_error_handlers_methods source = self
|
39
39
|
handlers = (source.instance_variable_get(:@__error_handlers__) || {}).each_with_object({}) do |(code,block),o|
|
40
40
|
o[code] = :"__#{code}_error_handler__"
|
41
|
-
|
41
|
+
api.delete define_method(o[code], &block)
|
42
42
|
end
|
43
43
|
handlers.update(allocate.error_handlers)
|
44
44
|
return if handlers.empty?
|
45
45
|
handlers.freeze
|
46
|
-
|
46
|
+
api.delete define_method(:error_handlers) {handlers}
|
47
47
|
end
|
48
48
|
|
49
49
|
def error_handlers; RocketIO::EMPTY_HASH end
|
@@ -76,17 +76,21 @@ module RocketIO
|
|
76
76
|
# 409: Wrong number of arguments received
|
77
77
|
error 409 do
|
78
78
|
RocketIO.error_renderer(409, xhr?, {
|
79
|
-
|
80
|
-
controller: self.class,
|
81
|
-
|
82
|
-
|
83
|
-
|
79
|
+
url: url,
|
80
|
+
controller: self.class.to_s,
|
81
|
+
requested_method: requested_method,
|
82
|
+
expected: api[requested_method][:parameters_policy],
|
83
|
+
received: path_params_array
|
84
84
|
})
|
85
85
|
end
|
86
86
|
|
87
87
|
# 501: Not Implemented
|
88
88
|
error 501 do
|
89
|
-
RocketIO.error_renderer(501, xhr?,
|
89
|
+
RocketIO.error_renderer(501, xhr?, {
|
90
|
+
url: url,
|
91
|
+
controller: self.class.to_s,
|
92
|
+
requested_method: requested_method
|
93
|
+
})
|
90
94
|
end
|
91
95
|
end
|
92
96
|
end
|
@@ -11,47 +11,42 @@ module RocketIO
|
|
11
11
|
# and can override them selectively, by name
|
12
12
|
#
|
13
13
|
# @note wildcard filters will run before/around/after any methods,
|
14
|
-
# that's it, if defining `before {}` and `before(:
|
15
|
-
# `
|
14
|
+
# that's it, if defining `before {}` and `before(:index) {}` filters
|
15
|
+
# `index` method will run `before` filter then `before(:index)`
|
16
16
|
#
|
17
|
-
# @example run before any
|
17
|
+
# @example run before any method
|
18
18
|
# before do
|
19
19
|
# # some logic here
|
20
20
|
# end
|
21
21
|
#
|
22
|
-
# @example run only before
|
23
|
-
# before :
|
22
|
+
# @example run only before :create
|
23
|
+
# before :create do
|
24
24
|
# # some logic here
|
25
25
|
# end
|
26
26
|
#
|
27
|
-
# @example run only around
|
28
|
-
# around :
|
27
|
+
# @example run only around :create and :edit
|
28
|
+
# around :create, :edit do |app|
|
29
29
|
# # some logic here
|
30
30
|
# app.call
|
31
31
|
# end
|
32
32
|
#
|
33
|
-
# @example run only after :register websocket call
|
34
|
-
# after :register do
|
35
|
-
# # some logic here
|
36
|
-
# end
|
37
|
-
#
|
38
33
|
# @example define a filter that does nothing. useful to override inherited filters.
|
39
|
-
# before
|
34
|
+
# before {}
|
40
35
|
#
|
41
|
-
# @example run 2 blocks before
|
36
|
+
# @example run 2 blocks before :create
|
42
37
|
# before do # wildcard filter, will run before any method
|
43
38
|
# @user = User.find...
|
44
39
|
# end
|
45
40
|
#
|
46
|
-
# before :
|
41
|
+
# before :create do # named filter, will run only before `create`
|
47
42
|
# # wildcard filter already executed so we have `@user` variable here
|
48
43
|
# @photo = @user.photos.find...
|
49
44
|
# end
|
50
45
|
#
|
51
|
-
# #
|
46
|
+
# # at the moment we call :create two filters was executed:
|
52
47
|
# # - wildcard one
|
53
48
|
# # - named one
|
54
|
-
# def
|
49
|
+
# def create
|
55
50
|
# # both @user and @photo variables available here
|
56
51
|
# end
|
57
52
|
#
|
@@ -75,12 +70,12 @@ module RocketIO
|
|
75
70
|
define_singleton_method define_methods do |source = self|
|
76
71
|
filters = (source.instance_variable_get(var) || {}).each_with_object({}) do |(meth,block),o|
|
77
72
|
o[meth] = :"__#{filter}_#{meth}__"
|
78
|
-
|
73
|
+
api.delete define_method(o[meth], &block)
|
79
74
|
end
|
80
75
|
filters.update(allocate.__send__(filter))
|
81
76
|
return unless filters.any?
|
82
77
|
filters.freeze
|
83
|
-
|
78
|
+
api.delete define_method(filter) {filters}
|
84
79
|
end
|
85
80
|
end
|
86
81
|
|
@@ -83,7 +83,7 @@ module RocketIO
|
|
83
83
|
# pass User, :bob, :bobsen
|
84
84
|
#
|
85
85
|
def pass controller, *args
|
86
|
-
halt controller.
|
86
|
+
halt controller.new(requested_method, args).call(env)
|
87
87
|
end
|
88
88
|
|
89
89
|
# stop executing any code and send response to browser.
|
@@ -24,7 +24,7 @@ module RocketIO
|
|
24
24
|
def self.define_middleware_methods source = self
|
25
25
|
middleware = ((source.instance_variable_get(:@__middleware__) || []) + allocate.middleware).uniq.freeze
|
26
26
|
return if middleware.empty?
|
27
|
-
|
27
|
+
api.delete define_method(:middleware) {middleware}
|
28
28
|
end
|
29
29
|
|
30
30
|
def middleware; RocketIO::EMPTY_ARRAY end
|
@@ -60,14 +60,14 @@ module RocketIO
|
|
60
60
|
return unless engine = source.instance_variable_get(:@__engine__)
|
61
61
|
if Proc === engine
|
62
62
|
selfengine = allocate.engine
|
63
|
-
|
64
|
-
|
63
|
+
api.delete define_method(:__rocketio_engine__, &engine)
|
64
|
+
api.delete define_method(:engine) {
|
65
65
|
engine, *engine_options = __rocketio_engine__
|
66
66
|
return selfengine unless engine
|
67
67
|
[RocketIO.engine_class(engine), engine_options.freeze].freeze
|
68
68
|
}
|
69
69
|
else
|
70
|
-
|
70
|
+
api.delete define_method(:engine) {engine}
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
@@ -17,7 +17,7 @@ module RocketIO
|
|
17
17
|
def self.define_layout_methods source = self
|
18
18
|
return unless source.instance_variables.include?(:@__layout__)
|
19
19
|
layout = source.instance_variable_get(:@__layout__)
|
20
|
-
|
20
|
+
api.delete define_method(:layout) {layout}
|
21
21
|
end
|
22
22
|
|
23
23
|
# by default no layout used, so this method returns nil.
|
@@ -59,25 +59,25 @@ module RocketIO
|
|
59
59
|
o[name] = :"__#{name}_layout__"
|
60
60
|
if setup[:block]
|
61
61
|
# block given, do not search for file, use returned value instead
|
62
|
-
|
62
|
+
api.delete define_method(o[name], &setup[:block])
|
63
63
|
elsif setup[:file]
|
64
64
|
# file given, search the file in original controller dirname
|
65
|
-
|
65
|
+
meth_name = :"__#{name}_layout_file__"
|
66
66
|
meth_proc = setup[:file].is_a?(::Proc) ? setup[:file] : -> {setup[:file]}
|
67
|
-
|
68
|
-
|
67
|
+
api.delete define_method(meth_name, &meth_proc)
|
68
|
+
api.delete define_method(o[name]) {
|
69
69
|
engine, * = resolve_engine
|
70
70
|
read_template(find_template(setup[:root], __send__(meth_name), engine))
|
71
71
|
}
|
72
72
|
else
|
73
73
|
# only name given, search for a file with same name in controller's dirname
|
74
|
-
|
74
|
+
api.delete define_method(o[name]) {
|
75
75
|
engine, * = resolve_engine
|
76
76
|
read_template(find_template(self.dirname, setup[:name], engine))
|
77
77
|
}
|
78
78
|
end
|
79
79
|
end.freeze
|
80
|
-
|
80
|
+
api.delete define_method(:layouts) {layouts}
|
81
81
|
end
|
82
82
|
|
83
83
|
def layouts; RocketIO::EMPTY_HASH end
|
@@ -17,12 +17,12 @@ module RocketIO
|
|
17
17
|
vars = source.instance_variable_get(:@__template_vars__).each_with_object(allocate.__template_vars__.dup) do |(name,value),o|
|
18
18
|
o[name] = :"__#{name}_template_var__"
|
19
19
|
if value.is_a?(Proc)
|
20
|
-
|
20
|
+
api.delete define_method(o[name], &value)
|
21
21
|
else
|
22
|
-
|
22
|
+
api.delete define_method(o[name]) {value}
|
23
23
|
end
|
24
24
|
end.freeze
|
25
|
-
|
25
|
+
api.delete define_method(:__template_vars__) {vars}
|
26
26
|
end
|
27
27
|
|
28
28
|
def __template_vars__; RocketIO::EMPTY_HASH end
|
@@ -57,25 +57,25 @@ module RocketIO
|
|
57
57
|
o[name] = :"__#{name}_template__"
|
58
58
|
if setup[:block]
|
59
59
|
# block given, do not search for file, use returned value instead
|
60
|
-
|
60
|
+
api.delete define_method(o[name], &setup[:block])
|
61
61
|
elsif setup[:file]
|
62
62
|
# file given, search the file in original controller dirname
|
63
|
-
|
63
|
+
meth_name = :"__#{name}_template_file__"
|
64
64
|
meth_proc = setup[:file].is_a?(Proc) ? setup[:file] : -> {setup[:file]}
|
65
|
-
|
66
|
-
|
65
|
+
api.delete define_method(meth_name, &meth_proc)
|
66
|
+
api.delete define_method(o[name]) {
|
67
67
|
engine, * = resolve_engine
|
68
68
|
read_template(find_template(setup[:root], __send__(meth_name), engine))
|
69
69
|
}
|
70
70
|
else
|
71
71
|
# only name given, search for a file with same name in controller's dirname
|
72
|
-
|
72
|
+
api.delete define_method(o[name]) {
|
73
73
|
engine, * = resolve_engine
|
74
74
|
read_template(find_template(self.dirname, setup[:name], engine))
|
75
75
|
}
|
76
76
|
end
|
77
77
|
end.freeze
|
78
|
-
|
78
|
+
api.delete define_method(:templates) {templates}
|
79
79
|
end
|
80
80
|
|
81
81
|
def templates; RocketIO::EMPTY_HASH end
|
@@ -56,7 +56,7 @@ module RocketIO
|
|
56
56
|
def self.define_sessions_methods source = self
|
57
57
|
return unless source.instance_variables.include?(:@__sessions__)
|
58
58
|
sessions = source.instance_variable_get(:@__sessions__)
|
59
|
-
|
59
|
+
api.delete define_method(:sessions) {sessions}
|
60
60
|
end
|
61
61
|
|
62
62
|
def sessions; end
|
@@ -1,7 +1,11 @@
|
|
1
|
-
<h1>Wrong
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
</
|
1
|
+
<h1>409: Wrong arguments</h1>
|
2
|
+
<h3>
|
3
|
+
<b>{{url}}</b> URL resolved to <b>{{controller}}#{{requested_method}}</b> method
|
4
|
+
but it was called with wrong arguments.
|
5
|
+
<div>
|
6
|
+
Expected: {min: {{expected.min}}, max: {{expected.max}}}
|
7
|
+
</div>
|
8
|
+
<div>
|
9
|
+
Received: {{received}}
|
10
|
+
</div>
|
11
|
+
</h3>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<h1>501: Not Implemented</h1>
|
2
2
|
<hr>
|
3
|
-
<
|
4
|
-
|
5
|
-
but it
|
6
|
-
</
|
3
|
+
<h3>
|
4
|
+
<b>{{url}}</b> URL resolved to <b>{{controller}}</b> controller
|
5
|
+
but it does not respond to <b>{{requested_method}}</b> method
|
6
|
+
</h3>
|
data/lib/rocketio/router.rb
CHANGED
@@ -1,26 +1,42 @@
|
|
1
1
|
module RocketIO
|
2
2
|
class Router
|
3
|
-
|
3
|
+
|
4
|
+
ROOT_PATH_PIECES = [EMPTY_STRING].freeze
|
5
|
+
PATH_SPLITTER = /\/+/.freeze
|
6
|
+
|
4
7
|
attr_reader :controllers, :routes
|
5
8
|
|
6
9
|
def initialize *controllers
|
7
10
|
@controllers = controllers.flatten.compact.uniq
|
8
|
-
@
|
11
|
+
@controller_routes = controller_routes()
|
9
12
|
freeze!
|
10
13
|
end
|
11
14
|
|
15
|
+
# fully traversing the tree and use the last matched controller
|
12
16
|
def resolve_path path
|
13
|
-
|
17
|
+
controller_routes = @controller_routes
|
14
18
|
pieces = path_pieces(path)
|
15
|
-
depth
|
16
|
-
controller
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
controller
|
21
|
-
|
19
|
+
depth = -1
|
20
|
+
controller = nil
|
21
|
+
path_params = []
|
22
|
+
|
23
|
+
while controller_routes = controller_routes[pieces[depth += 1]]
|
24
|
+
# do not use `next unless controller = controller_routes[0]` here
|
25
|
+
# cause this may override earlier found controller.
|
26
|
+
next unless controller_routes[0]
|
27
|
+
controller = controller_routes[0]
|
28
|
+
path_params = pieces[ (depth + 1) .. -1 ]
|
22
29
|
end
|
23
|
-
|
30
|
+
|
31
|
+
return EMPTY_ARRAY unless controller
|
32
|
+
|
33
|
+
method = if path_params.any? && controller.api[path_params[0].to_sym]
|
34
|
+
path_params.slice!(0).to_sym
|
35
|
+
else
|
36
|
+
INDEX_METHOD
|
37
|
+
end
|
38
|
+
|
39
|
+
[controller, method, path_params]
|
24
40
|
end
|
25
41
|
|
26
42
|
private
|
@@ -34,30 +50,28 @@ module RocketIO
|
|
34
50
|
#
|
35
51
|
def path_pieces path
|
36
52
|
return ROOT_PATH_PIECES if path == SLASH # that's root path, /
|
37
|
-
path.to_s.split(
|
53
|
+
path.to_s.split(PATH_SPLITTER)
|
38
54
|
end
|
39
55
|
|
40
56
|
# building a routing tree
|
41
57
|
#
|
42
58
|
# @return [Hash]
|
43
59
|
#
|
44
|
-
def
|
45
|
-
|
46
|
-
@controllers.each do |controller|
|
60
|
+
def controller_routes
|
61
|
+
controllers.each_with_object({}) do |controller,map|
|
47
62
|
[controller.url, *controller.aliases].each do |url|
|
48
63
|
depth = 0
|
49
64
|
pieces = path_pieces(url)
|
50
|
-
pieces.
|
51
|
-
|
52
|
-
|
53
|
-
|
65
|
+
pieces.reduce(map) do |pieces_map,chunk|
|
66
|
+
pieces_map[chunk] ||= {}
|
67
|
+
pieces_map[chunk][0] = controller if pieces.size == (depth += 1)
|
68
|
+
pieces_map[chunk]
|
54
69
|
end
|
55
70
|
end
|
56
71
|
end
|
57
|
-
map
|
58
72
|
end
|
59
73
|
|
60
|
-
# freezing the
|
74
|
+
# freezing the router cause modifying it at runtime may blow the universe
|
61
75
|
def freeze!
|
62
76
|
self.freeze
|
63
77
|
end
|
data/lib/rocketio/version.rb
CHANGED
data/rocketio.gemspec
CHANGED
@@ -24,4 +24,6 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency 'rake', '~> 10.0'
|
25
25
|
spec.add_development_dependency 'tokyo', '~> 0'
|
26
26
|
spec.add_development_dependency 'rack-radar', '~> 0'
|
27
|
+
spec.add_development_dependency 'pry', '~> 0'
|
28
|
+
spec.add_development_dependency 'pry-byebug', '~> 3'
|
27
29
|
end
|
data/test/aliases_test.rb
CHANGED