scorched 0.14 → 0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +4 -0
- data/README.md +4 -4
- data/Rakefile +12 -1
- data/docs/02_fundamentals/03_routing.md +6 -2
- data/examples/test.ru +3 -6
- data/lib/scorched/controller.rb +3 -1
- data/lib/scorched/request.rb +9 -2
- data/lib/scorched/version.rb +1 -1
- data/spec/controller_spec.rb +17 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 252309e125591f6ffd81a1ac36bb79c851aabce8
|
4
|
+
data.tar.gz: 4100f0dc1f942fb4067f32e27f966b8fb327c8d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cda7022f16ff4d70a47552dbb6563f86e8ece672036b221373a639990c48bd12fbedce6e7989eabe0cf9282a08621eec342a129ea9c74dadd66b0b289642b25
|
7
|
+
data.tar.gz: 6dc0e3f1aef90a462a610f33fc7ffc34f087f5426f7919c2ae555f3599aeb048668fb7c72e3e7e39b6ea4664eeb68048b060b255af6ae2687f9c7d578e5678ff
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,10 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
### v0.15
|
5
|
+
* Route DSL methods (`route`, `get`, `post`, ...) now accept an array of patterns as the pattern argument. Each pattern is defined as a separate mapping, sharing the same target proc. This provides a cleaner and more efficient solution to simply wrapping a route definition within a loop.
|
6
|
+
* URI unescaping has been implemented for `Scorched::Request#unmatched_path`. This modification directly affects route matching. Previously, routes were matched against the escaped path, e.g. `/this%20has%20spaces`. Routes are now matched against the unescaped form `/this has spaces`. The only exception is the escaped forward-slash `%2F` and percent sign `%25` which remain unaltered for the fact their unescaped form as special meaning which you wouldn't be able to disambiguate. It's however safe to unescape the path a second time to resolve these characters.
|
7
|
+
|
4
8
|
### v0.14
|
5
9
|
* If a matched mapping _passes_ the request and there are no other matching mappings, a 404 status is now set by default, rather than a 200 status.
|
6
10
|
* Renamed `matched` condition to `handled` to be less ambiguous.
|
data/README.md
CHANGED
@@ -35,13 +35,13 @@ $ rackup hello_world.ru
|
|
35
35
|
|
36
36
|
#### A Note on Requirements
|
37
37
|
|
38
|
-
Scorched requires Ruby 2.0 or above.
|
38
|
+
Scorched requires Ruby 2.0 or above. If you've got Ruby 2.0.0-p195 and newer, you're good. Otherwise, you need to ensure that your version of Ruby 2.0 includes [changeset 39919](http://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39919) in order to avoid suffering from [random segmentation faults](http://bugs.ruby-lang.org/issues/8100).
|
39
39
|
|
40
|
-
The Errors of Our Past
|
40
|
+
The Errors of Our Past (and Present!)
|
41
41
|
----------------------
|
42
|
-
One of the mistakes made by a lot of other Ruby frameworks
|
42
|
+
One of the mistakes made by a lot of other Ruby frameworks is to not leverage the power of the class. The consequences of this have made for some awkwardness. Helpers, for example, are a classical reinvention of what classes and modules are already made to solve. Scorched implements Controllers as classes, which, in addition to having their own DSL, allow you to define and call whatever you need as traditional instance methods. The decision to allow developers to implement helpers and other common functionality as proper methods not only makes Controllers somewhat more predictable and familiar, but also allows for such helpers to be inheritable via plain-old class inheritance.
|
43
43
|
|
44
|
-
Perhaps another design oversight of other frameworks
|
44
|
+
Perhaps another design oversight of other frameworks has been the lack of consideration for the hierarchical nature of websites, and the fact that sub-directories are often expected to inherit attributes of their parents. Scorched supports sub-controllers to any arbitrary depth, with each controller's configuration, filters, route conditions, etc. applied along the way. This can help in many areas of web development, including security, restful interfaces, and interchangeable content types.
|
45
45
|
|
46
46
|
|
47
47
|
Design Philosophy
|
data/Rakefile
CHANGED
@@ -11,8 +11,10 @@ task :test => :spec
|
|
11
11
|
|
12
12
|
RSpec::Core::RakeTask.new(:spec)
|
13
13
|
|
14
|
-
|
14
|
+
desc 'Releases a new version of Scorched.'
|
15
|
+
task :release => [:prerelease, :spec, :'gem:install', :commit_version, :'gem:release', :clean]
|
15
16
|
|
17
|
+
desc 'Commits and tags git repository as new version, pushing up to github'
|
16
18
|
task :commit_version do
|
17
19
|
sh "git commit --allow-empty -a -m 'v#{Scorched::VERSION} release.' &&
|
18
20
|
git tag -a #{Scorched::VERSION} -m 'v#{Scorched::VERSION} release.' &&
|
@@ -20,6 +22,15 @@ task :commit_version do
|
|
20
22
|
git push --tags"
|
21
23
|
end
|
22
24
|
|
25
|
+
desc 'Displays a pre-release message, requiring user input'
|
26
|
+
task :prerelease do
|
27
|
+
puts <<-MSG
|
28
|
+
|
29
|
+
About to release Scorched v#{Scorched::VERSION}. Please ensure CHANGES log is up-to-date, all relevant documentation is updated, and that any new files not under version control have been added/staged. Press any key to continue...
|
30
|
+
MSG
|
31
|
+
STDIN.gets
|
32
|
+
end
|
33
|
+
|
23
34
|
namespace :gem do
|
24
35
|
require "bundler/gem_tasks"
|
25
36
|
end
|
@@ -33,9 +33,9 @@ end
|
|
33
33
|
|
34
34
|
You can see pretty clearly how these examples correspond to the pattern, priority, conditions and target options of a manual mapping. The pattern, priority and conditions behave exactly as they do for a manual mapping, with a couple of exceptions.
|
35
35
|
|
36
|
-
The first exception is that the pattern must match to the end of the request path. This is mentioned in the _pattern matching_ section below.
|
36
|
+
The first exception is that the pattern must match to the end of the request path. This is mentioned in the _pattern matching_ section below. You can also define a route with multiple patterns by using an array. This creates a different mapping for each URL, but using the same proc object and other arguments.
|
37
37
|
|
38
|
-
The other more notable exception is in how the given block is treated. The block given to the route helper is wrapped in another proc. The wrapping proc does a couple of things. It first sends all the captures in the url pattern as
|
38
|
+
The other more notable exception is in how the given block is treated. The block given to the route helper is wrapped in another proc. The wrapping proc does a couple of things. It first sends all the captures in the url pattern as arguments to the given block; this is shown in the example above. The other thing it does is takes care of assigning the return value to the body of the response.
|
39
39
|
|
40
40
|
In the latter of the two examples above, a `:method` condition defines what methods the route is intended to process. The first example has no such condition, so it accepts all HTTP methods. Typically however, a route will handle a single HTTP method, which is why Scorched also provides the convenience helpers: `get`, `post`, `put`, `delete`, `head`, `options`, and `patch`. These methods automatically define the corresponding `:method` condition, with the `get` helper also including `head` as an accepted HTTP method.
|
41
41
|
|
@@ -44,6 +44,10 @@ Pattern Matching
|
|
44
44
|
All patterns attempt to match the remaining unmatched portion of the _request path_; the _request path_ being Rack's
|
45
45
|
`path_info` request variable. The unmatched path will always begin with a forward slash if the previously matched portion of the path ended immediately before, or included as the last character, a forward slash. As an example, if the request was to "/article/21", then both "/article/" => "/21" and "/article" => "/21" would match.
|
46
46
|
|
47
|
+
The `path_info` used to match against is unescaped, meaning percent-codes are resolved, e.g. `%20` resolves to a space. The two exceptions are the escaped forward-slash and percent sign, which remain escaped as `%2F` and `%25` respectively.
|
48
|
+
|
49
|
+
> The forward-slash cannot be automatically escaped as it would make it impossible to disambiguate from an actual forward-slash in the URL (which has special meaning). The encoded percent-sign thus also needs to remain unescaped, otherwise it'd be impossible to safely unescape the escaped forward-slash in your application, if you needed to. If this all sounds very confusing, rest assured you probably won't ever encounter a scenario in which you'd have to think about this.
|
50
|
+
|
47
51
|
All patterns must match from the beginning of the path. So even though the pattern "article" would match "/article/21", it wouldn't count as a match because the match didn't start at a non-zero offset.
|
48
52
|
|
49
53
|
If a pattern contains named captures, unnamed captures will be lost - this is how named regex captures work in Ruby. So if you name one capture, make sure you name any other captures you may want to access.
|
data/examples/test.ru
CHANGED
data/lib/scorched/controller.rb
CHANGED
@@ -170,7 +170,9 @@ module Scorched
|
|
170
170
|
env['scorched.response'].body = instance_exec(*env['scorched.request'].captures, &block)
|
171
171
|
env['scorched.response']
|
172
172
|
end
|
173
|
-
|
173
|
+
[*pattern].compact.each do |pattern|
|
174
|
+
self << {pattern: compile(pattern, true), priority: priority, conditions: conds, target: target}
|
175
|
+
end
|
174
176
|
target
|
175
177
|
end
|
176
178
|
|
data/lib/scorched/request.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'uri'
|
2
|
+
|
1
3
|
module Scorched
|
2
4
|
class Request < Rack::Request
|
3
5
|
# Keeps track of the matched URL portions and what object handled them. Useful for debugging and building
|
@@ -23,11 +25,16 @@ module Scorched
|
|
23
25
|
|
24
26
|
# The remaining portion of the path that has yet to be matched by any mappings.
|
25
27
|
def unmatched_path
|
26
|
-
path =
|
28
|
+
path = unescaped_path.partition(matched_path).last
|
27
29
|
path[0,0] = '/' if path.empty? || matched_path[-1] == '/'
|
28
30
|
path
|
29
31
|
end
|
30
|
-
|
32
|
+
|
33
|
+
# The unescaped URL, excluding the escaped forward-slash and percent. The resulting string will always be safe
|
34
|
+
# to unescape again in situations where the forward-slash or percent are expected and valid characters.
|
35
|
+
def unescaped_path
|
36
|
+
path_info.split(/(%25|%2F)/i).each_slice(2).map { |v, m| URI.unescape(v) << (m || '') }.join('')
|
37
|
+
end
|
31
38
|
private
|
32
39
|
|
33
40
|
# Joins an array of path segments ensuring a single forward slash seperates them.
|
data/lib/scorched/version.rb
CHANGED
data/spec/controller_spec.rb
CHANGED
@@ -72,6 +72,16 @@ module Scorched
|
|
72
72
|
response.status.should == 200
|
73
73
|
end
|
74
74
|
|
75
|
+
it "unescapes all characters except for the forward-slash and percent sign" do
|
76
|
+
app << {pattern: '/a (quite) big fish', target: generic_handler}
|
77
|
+
rt.get('/a%20%28quite%29%20big%20fish').status.should == 200
|
78
|
+
app << {pattern: '/article/100%25 big%2Fsmall', target: generic_handler}
|
79
|
+
rt.get('/article/100%25%20big%2Fsmall').status.should == 200
|
80
|
+
app << {pattern: '/*$', target: generic_handler}
|
81
|
+
rt.get('/page%2Fabout').status.should == 200
|
82
|
+
rt.get('/page/about').status.should == 404
|
83
|
+
end
|
84
|
+
|
75
85
|
it "unmatched path doesn't always begin with a forward slash" do
|
76
86
|
gh = generic_handler
|
77
87
|
app << {pattern: '/ab', target: Class.new(Scorched::Controller) do
|
@@ -238,6 +248,13 @@ module Scorched
|
|
238
248
|
end
|
239
249
|
rt.get('/')
|
240
250
|
end
|
251
|
+
|
252
|
+
it "can take an array of patterns" do
|
253
|
+
app.get(['/', '/dog']) { 'rad' }
|
254
|
+
rt.get('/dog').status.should == 200
|
255
|
+
rt.get('/').status.should == 200
|
256
|
+
rt.get('/cat').status.should == 404
|
257
|
+
end
|
241
258
|
end
|
242
259
|
|
243
260
|
describe "sub-controllers" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: scorched
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.15'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tom Wardrop
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|