syro 3.0.1 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +84 -6
- data/lib/syro.rb +60 -3
- data/syro.gemspec +1 -1
- data/test/all.rb +46 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 585d2fe3559bfaa4cc09f2a6b25efac445ca739b
|
4
|
+
data.tar.gz: 99a97c194e80a465474f2439a7f80e938f6e69c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23adfa66e18f592c65688248b8f9c4f625c988c8a6392e84ea578cc2263396ef5170b1cde6a27132aa43b3139679f1e523ddfd38d07cf4ddb7fa09fd0f3a7804
|
7
|
+
data.tar.gz: e1ae691f6c4d9fee2aaaec0c814519bc0bb4cd6a765dea46b63e978564426bd9763b946e8e203e2ad8b0f64f55a766c2ad4be667a171180d85bacb08db9e6c3d
|
data/README.md
CHANGED
@@ -48,10 +48,10 @@ end
|
|
48
48
|
|
49
49
|
The block is evaluated in a sandbox where the following methods are
|
50
50
|
available: `env`, `req`, `res`, `path`, `inbox`, `call`, `run`,
|
51
|
-
`halt`, `consume`, `capture`, `root?` `match`,
|
52
|
-
`root`,`get`, `put`, `head`, `post`, `patch`,
|
53
|
-
Three other methods are available for
|
54
|
-
`request_class` and `response_class`.
|
51
|
+
`halt`, `handle`, `finish!`, `consume`, `capture`, `root?` `match`,
|
52
|
+
`default`, `on`, `root`,`get`, `put`, `head`, `post`, `patch`,
|
53
|
+
`delete` and `options`. Three other methods are available for
|
54
|
+
customizations: `default_headers`, `request_class` and `response_class`.
|
55
55
|
|
56
56
|
As a recommendation, user created variables should be instance
|
57
57
|
variables. That way they won't mix with the API methods defined in
|
@@ -83,6 +83,12 @@ argument.
|
|
83
83
|
`halt`: Terminates the request. It receives an array with the
|
84
84
|
response as per Rack's specification.
|
85
85
|
|
86
|
+
`handle`: Installs a handler for a given status code. It receives
|
87
|
+
a status code and a block that will be executed from `finish!`.
|
88
|
+
|
89
|
+
`finish!`: Terminates the request by executing any installed handlers
|
90
|
+
and then halting with the current value of `res.finish`.
|
91
|
+
|
86
92
|
`consume`: Match and consume a path segment.
|
87
93
|
|
88
94
|
`capture`: Match and capture a path segment. The value is stored in
|
@@ -254,6 +260,78 @@ post do
|
|
254
260
|
end
|
255
261
|
```
|
256
262
|
|
263
|
+
Handlers
|
264
|
+
--------
|
265
|
+
|
266
|
+
Status code handlers can be installed with the `handle` command,
|
267
|
+
which receives a status code and a block to be executed just before
|
268
|
+
finishing the request.
|
269
|
+
|
270
|
+
By default, if there are no matches in a Syro application the
|
271
|
+
response is a `404` with an empty body. If we decide to handle the
|
272
|
+
`404` requests and return a string, we can do as follows:
|
273
|
+
|
274
|
+
```ruby
|
275
|
+
App = Syro.new do
|
276
|
+
handle 404 do
|
277
|
+
res.text "Not found!"
|
278
|
+
end
|
279
|
+
|
280
|
+
get do
|
281
|
+
res.text "Found!
|
282
|
+
end
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
In this example, a `GET` request to `"/"` will return a status `200`
|
287
|
+
with the body `"Found!"`. Any other request will return a `404`
|
288
|
+
with the body `"Not found!"`.
|
289
|
+
|
290
|
+
If a new handler is installed for the same status code, the previous
|
291
|
+
handler is overwritten. A handler is valid in the current scope and
|
292
|
+
in all its nested branches. Blocks that end before the handler is
|
293
|
+
installed are not affected.
|
294
|
+
|
295
|
+
This is a contrived example that shows some edge cases when using handlers:
|
296
|
+
|
297
|
+
```ruby
|
298
|
+
App = Syro.new do
|
299
|
+
on "foo" do
|
300
|
+
# 404, empty body
|
301
|
+
end
|
302
|
+
|
303
|
+
handle 404 do
|
304
|
+
res.text "Not found!"
|
305
|
+
end
|
306
|
+
|
307
|
+
on "bar" do
|
308
|
+
# 404, body is "Not found!"
|
309
|
+
end
|
310
|
+
|
311
|
+
on "baz" do
|
312
|
+
# 404, body is "Couldn't find baz"
|
313
|
+
|
314
|
+
handle 404 do
|
315
|
+
res.text "Couldn't find baz"
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
```
|
320
|
+
|
321
|
+
A request to `"/foo"` will return a `404`, because the request
|
322
|
+
method was not matched. But as the `on "foo"` block ends before the
|
323
|
+
handler is installed, the result will be a blank screen. On the
|
324
|
+
other hand, a request to `"/bar"` will return a `404` with the plain
|
325
|
+
text `"Not found!"`.
|
326
|
+
|
327
|
+
Finally, a request to `"/baz"` will return a `404` with the plain text
|
328
|
+
`"Couldn't find baz"`, because by the time the `on "baz"` block ends
|
329
|
+
a new handler is installed, and thus the previous one is overwritten.
|
330
|
+
|
331
|
+
Any status code can be handled this way, even status `200`. In that
|
332
|
+
case the handler will behave as a filter to be run after each
|
333
|
+
successful request.
|
334
|
+
|
257
335
|
Content type
|
258
336
|
------------
|
259
337
|
|
@@ -317,11 +395,11 @@ just use `Rack::Builder`:
|
|
317
395
|
App = Rack::Builder.new do
|
318
396
|
use Rack::Session::Cookie, secret: "..."
|
319
397
|
|
320
|
-
run Syro.new
|
398
|
+
run Syro.new {
|
321
399
|
get do
|
322
400
|
res.write("Hello, world")
|
323
401
|
end
|
324
|
-
|
402
|
+
}
|
325
403
|
end
|
326
404
|
```
|
327
405
|
|
data/lib/syro.rb
CHANGED
@@ -269,8 +269,7 @@ class Syro
|
|
269
269
|
|
270
270
|
catch(:halt) do
|
271
271
|
instance_eval(&@syro_code)
|
272
|
-
|
273
|
-
@syro_res.finish
|
272
|
+
finish!
|
274
273
|
end
|
275
274
|
end
|
276
275
|
|
@@ -297,6 +296,64 @@ class Syro
|
|
297
296
|
throw(:halt, response)
|
298
297
|
end
|
299
298
|
|
299
|
+
# Install a handler for a given status code. Once a handler is
|
300
|
+
# installed, it will be called by Syro before halting the
|
301
|
+
# request.
|
302
|
+
#
|
303
|
+
# handle 404 do
|
304
|
+
# res.text "Not found!"
|
305
|
+
# end
|
306
|
+
#
|
307
|
+
# If a new handler is installed for the same status code, the
|
308
|
+
# previous handler is overwritten. A handler is valid in the
|
309
|
+
# current scope and in all its nested branches. Blocks that end
|
310
|
+
# before the handler is installed are not affected.
|
311
|
+
#
|
312
|
+
# For example:
|
313
|
+
#
|
314
|
+
# on "foo" do
|
315
|
+
# # Not found
|
316
|
+
# end
|
317
|
+
#
|
318
|
+
# handle 404 do
|
319
|
+
# res.text "Not found!"
|
320
|
+
# end
|
321
|
+
#
|
322
|
+
# on "bar" do
|
323
|
+
# # Not found
|
324
|
+
# end
|
325
|
+
#
|
326
|
+
# on "baz" do
|
327
|
+
# # Not found
|
328
|
+
#
|
329
|
+
# handle 404 do
|
330
|
+
# res.text "Couldn't find baz"
|
331
|
+
# end
|
332
|
+
# end
|
333
|
+
#
|
334
|
+
# A request to "/foo" will return a 404, because the request
|
335
|
+
# method was not matched. But as the `on "foo"` block ends
|
336
|
+
# before the handler is installed, the result will be a blank
|
337
|
+
# screen. On the other hand, a request to "/bar" will return a
|
338
|
+
# 404 with the plain text "Not found!".
|
339
|
+
#
|
340
|
+
# Finally, a request to "/baz" will return a 404 with the plain text
|
341
|
+
# "Couldn't find baz", because by the time the `on "baz"` block ends
|
342
|
+
# a new handler is installed, and thus the previous one is overwritten.
|
343
|
+
#
|
344
|
+
# Any status code can be handled this way, even status `200`.
|
345
|
+
# In that case the handler will behave as a filter to be run
|
346
|
+
# after each successful request.
|
347
|
+
#
|
348
|
+
def handle(status, &block)
|
349
|
+
inbox[status] = block
|
350
|
+
end
|
351
|
+
|
352
|
+
def finish!
|
353
|
+
inbox[res.status]&.call
|
354
|
+
halt(res.finish)
|
355
|
+
end
|
356
|
+
|
300
357
|
def consume(arg)
|
301
358
|
@syro_path.consume(arg)
|
302
359
|
end
|
@@ -319,7 +376,7 @@ class Syro
|
|
319
376
|
end
|
320
377
|
|
321
378
|
def default
|
322
|
-
yield;
|
379
|
+
yield; finish!
|
323
380
|
end
|
324
381
|
|
325
382
|
def on(arg)
|
data/syro.gemspec
CHANGED
data/test/all.rb
CHANGED
@@ -79,6 +79,26 @@ comments = Syro.new do
|
|
79
79
|
end
|
80
80
|
end
|
81
81
|
|
82
|
+
handlers = Syro.new do
|
83
|
+
on "without_handler" do
|
84
|
+
# Not found
|
85
|
+
end
|
86
|
+
|
87
|
+
handle(404) do
|
88
|
+
res.text "Not found!"
|
89
|
+
end
|
90
|
+
|
91
|
+
on "with_handler" do
|
92
|
+
# Not found
|
93
|
+
end
|
94
|
+
|
95
|
+
on "with_local_handler" do
|
96
|
+
handle(404) do
|
97
|
+
res.text "Also not found!"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
82
102
|
app = Syro.new do
|
83
103
|
get do
|
84
104
|
res.write "GET /"
|
@@ -194,6 +214,10 @@ app = Syro.new do
|
|
194
214
|
run(json)
|
195
215
|
end
|
196
216
|
|
217
|
+
on "handlers" do
|
218
|
+
run(handlers)
|
219
|
+
end
|
220
|
+
|
197
221
|
on "private" do
|
198
222
|
res.status = 401
|
199
223
|
res.write("Unauthorized")
|
@@ -369,3 +393,25 @@ test "content type" do |f|
|
|
369
393
|
f.get("/json")
|
370
394
|
assert_equal "application/json", f.last_response.headers["Content-Type"]
|
371
395
|
end
|
396
|
+
|
397
|
+
test "status code handling" do |f|
|
398
|
+
f.get("/handlers")
|
399
|
+
assert_equal 404, f.last_response.status
|
400
|
+
assert_equal "text/plain", f.last_response.headers["Content-Type"]
|
401
|
+
assert_equal "Not found!", f.last_response.body
|
402
|
+
|
403
|
+
f.get("/handlers/without_handler")
|
404
|
+
assert_equal 404, f.last_response.status
|
405
|
+
assert_equal nil, f.last_response.headers["Content-Type"]
|
406
|
+
assert_equal "", f.last_response.body
|
407
|
+
|
408
|
+
f.get("/handlers/with_handler")
|
409
|
+
assert_equal 404, f.last_response.status
|
410
|
+
assert_equal "text/plain", f.last_response.headers["Content-Type"]
|
411
|
+
assert_equal "Not found!", f.last_response.body
|
412
|
+
|
413
|
+
f.get("/handlers/with_local_handler")
|
414
|
+
assert_equal 404, f.last_response.status
|
415
|
+
assert_equal "text/plain", f.last_response.headers["Content-Type"]
|
416
|
+
assert_equal "Also not found!", f.last_response.body
|
417
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: syro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michel Martens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: seg
|
@@ -103,7 +103,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
103
103
|
version: '0'
|
104
104
|
requirements: []
|
105
105
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.
|
106
|
+
rubygems_version: 2.6.11
|
107
107
|
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: Simple router
|