syntropy 0.27.8 → 0.27.9
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/CHANGELOG.md +4 -0
- data/lib/syntropy/app.rb +32 -1
- data/lib/syntropy/errors.rb +13 -5
- data/lib/syntropy/version.rb +1 -1
- data/test/test_app.rb +10 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 65c26fb1d6424b5b628e3002cdfca2df7a01b33702111f33df20d3dc430181e5
|
|
4
|
+
data.tar.gz: 3f79c53dd131676541097ac806d8aeecf5c7b5a08ef17445ae6f1e57dca49d70
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 6405e81b4d65b01bca5cac90586bd184eebedb3120463862eb1db5e60437ece323b563f847902b12a6b7231bfc511d2ed8818c97b1feb179d97853506156453a
|
|
7
|
+
data.tar.gz: b290f23967e92db10addd23af8e712e305c7ff816d9ce02d438b9902810e79db93e57bb6c4b28e92d9e454dd27d7518b02e9d42320c4b1c64ca69e21b8347b85
|
data/CHANGELOG.md
CHANGED
data/lib/syntropy/app.rb
CHANGED
|
@@ -68,9 +68,10 @@ module Syntropy
|
|
|
68
68
|
route = @router_proc.(path, req.route_params)
|
|
69
69
|
if !route
|
|
70
70
|
if (m = path.match(/^(.+)\/$/))
|
|
71
|
+
# redirect on trailing slash
|
|
71
72
|
return req.redirect(m[1], Qeweney::Status::MOVED_PERMANENTLY)
|
|
72
73
|
end
|
|
73
|
-
|
|
74
|
+
handle_not_found(req)
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
req.route = route
|
|
@@ -104,6 +105,30 @@ module Syntropy
|
|
|
104
105
|
|
|
105
106
|
private
|
|
106
107
|
|
|
108
|
+
# Handles a not found error, taking into account hooks up the tree from the
|
|
109
|
+
# request path.
|
|
110
|
+
#
|
|
111
|
+
# @param req [Qeweney::Reqest] request
|
|
112
|
+
# @return [void]
|
|
113
|
+
def handle_not_found(req)
|
|
114
|
+
closest_uptree_route = find_first_uptree_route(File.dirname(req.path))
|
|
115
|
+
if closest_uptree_route
|
|
116
|
+
proc = route_not_found_proc(closest_uptree_route)
|
|
117
|
+
proc.(req)
|
|
118
|
+
else
|
|
119
|
+
raise Syntropy::Error.not_found('Not found')
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Returns the find
|
|
124
|
+
def find_first_uptree_route(path)
|
|
125
|
+
route = @router_proc.(path, {})
|
|
126
|
+
if !route && path != '/'
|
|
127
|
+
route = @router_proc.(File.dirname(path), {})
|
|
128
|
+
end
|
|
129
|
+
route
|
|
130
|
+
end
|
|
131
|
+
|
|
107
132
|
# Instantiates a routing tree with the app settings, and generates a router
|
|
108
133
|
# proc.
|
|
109
134
|
#
|
|
@@ -125,6 +150,12 @@ module Syntropy
|
|
|
125
150
|
@routing_tree.mount_applet(path, @builtin_applet)
|
|
126
151
|
end
|
|
127
152
|
|
|
153
|
+
def route_not_found_proc(route)
|
|
154
|
+
route[:not_found_proc] ||= compose_up_tree_hooks(route, ->(req) {
|
|
155
|
+
raise Syntropy::Error.not_found('Not found')
|
|
156
|
+
})
|
|
157
|
+
end
|
|
158
|
+
|
|
128
159
|
# Computes the route proc for the given route, wrapping it in hooks found up
|
|
129
160
|
# the routing tree.
|
|
130
161
|
#
|
data/lib/syntropy/errors.rb
CHANGED
|
@@ -7,10 +7,10 @@ module Syntropy
|
|
|
7
7
|
class Error < StandardError
|
|
8
8
|
Status = Qeweney::Status
|
|
9
9
|
|
|
10
|
-
# By default, the HTTP status for errors is 500 Internal Server Error
|
|
10
|
+
# By default, the HTTP status for errors is 500 Internal Server Error.
|
|
11
11
|
DEFAULT_STATUS = Status::INTERNAL_SERVER_ERROR
|
|
12
12
|
|
|
13
|
-
# Returns the HTTP status for the given exception
|
|
13
|
+
# Returns the HTTP status for the given exception.
|
|
14
14
|
#
|
|
15
15
|
# @param err [Exception] exception
|
|
16
16
|
# @return [Integer, String] HTTP status
|
|
@@ -18,22 +18,30 @@ module Syntropy
|
|
|
18
18
|
err.respond_to?(:http_status) ? err.http_status : DEFAULT_STATUS
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
+
# Returns true if the error should be logged. Currently all errors are
|
|
22
|
+
# logged except for NOT FOUND errors.
|
|
23
|
+
#
|
|
24
|
+
# @param err [Exception] error
|
|
25
|
+
# @return [bool]
|
|
21
26
|
def self.log_error?(err)
|
|
22
27
|
http_status(err) != Status::NOT_FOUND
|
|
23
28
|
end
|
|
24
29
|
|
|
25
|
-
# Creates an error with status 404 Not Found
|
|
30
|
+
# Creates an error with status 404 Not Found.
|
|
26
31
|
#
|
|
32
|
+
# @param msg [String] error message
|
|
27
33
|
# @return [Syntropy::Error]
|
|
28
34
|
def self.not_found(msg = 'Not found') = new(msg, Status::NOT_FOUND)
|
|
29
35
|
|
|
30
|
-
# Creates an error with status 405 Method Not Allowed
|
|
36
|
+
# Creates an error with status 405 Method Not Allowed.
|
|
31
37
|
#
|
|
38
|
+
# @param msg [String] error message
|
|
32
39
|
# @return [Syntropy::Error]
|
|
33
40
|
def self.method_not_allowed(msg = 'Method not allowed') = new(msg, Status::METHOD_NOT_ALLOWED)
|
|
34
41
|
|
|
35
|
-
# Creates an error with status 418 I'm a teapot
|
|
42
|
+
# Creates an error with status 418 I'm a teapot.
|
|
36
43
|
#
|
|
44
|
+
# @param msg [String] error message
|
|
37
45
|
# @return [Syntropy::Error]
|
|
38
46
|
def self.teapot(msg = 'I\'m a teapot') = new(msg, Status::TEAPOT)
|
|
39
47
|
|
data/lib/syntropy/version.rb
CHANGED
data/test/test_app.rb
CHANGED
|
@@ -155,6 +155,16 @@ class AppTest < Minitest::Test
|
|
|
155
155
|
assert_equal '<h1>Raised error</h1>', req.response_body
|
|
156
156
|
assert_equal '43', req.ctx[:foo]
|
|
157
157
|
end
|
|
158
|
+
|
|
159
|
+
def test_middleware_invocation_on_404
|
|
160
|
+
req = make_request(':method' => 'HEAD', ':path' => '/azerty?foo=bar')
|
|
161
|
+
assert_equal Status::NOT_FOUND, req.response_status
|
|
162
|
+
assert_nil req.ctx[:foo]
|
|
163
|
+
|
|
164
|
+
req = make_request(':method' => 'HEAD', ':path' => '/test/azerty?foo=bar')
|
|
165
|
+
assert_equal Status::NOT_FOUND, req.response_status
|
|
166
|
+
assert_equal 'bar', req.ctx[:foo]
|
|
167
|
+
end
|
|
158
168
|
end
|
|
159
169
|
|
|
160
170
|
class CustomAppTest < Minitest::Test
|