scorched 0.16 → 0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +5 -0
- data/lib/scorched/controller.rb +17 -12
- data/lib/scorched/request.rb +3 -2
- data/lib/scorched/version.rb +1 -1
- data/spec/controller_spec.rb +75 -26
- 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: 5ad267343b4c7040dda32f6c394418bf9494dbcf
|
4
|
+
data.tar.gz: e8161cbafa5becf64f73ee970ac247a2ed43ef5f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8184c8ba998ffc82d2292b089fccbb0ce60e9e6c89e35679b0e8a14121ff3da46ad338cb33296b0139a98ba4fe226228d83387f34f1f424567f8620c26a1278
|
7
|
+
data.tar.gz: 723fd6f62103871197a99b39912677ebff7c4bc77d1e3cf707efc842e948da8c79aa4c8806cefe0cdc88d843c6aa9df89ea4e804bb54cf5e54f0c786606db194
|
data/CHANGES.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
### v0.17
|
5
|
+
* Fixes an issue introduced in v0.16 where joining `SCRIPT_NAME` and `PATH_INFO` would sometimes produce a path with two forward slashes, and a related issue where `PATH_INFO` would sometimes be missing a leading forward slash when it should have had one.
|
6
|
+
* Mappings are now sorted by the best matching `media type` in addition to the existing logic that included definition order and priority. This required that mappings be sorted at request-time rather than at the time they're mapped. Note, because of limitations of `rack-accept`, this doesn't completely respect the HTTP spec when it comes to prioritising which media type to serve for a given request. Full support for the HTTP spec is intended for a future release.
|
7
|
+
* File path references to views are now joined to the view directory using #expand_path. This allows views to be specified with an absolute path (effectively ignoring the view directory), and better support for relative paths.
|
8
|
+
|
4
9
|
### v0.16
|
5
10
|
* A copy of the Rack env hash is now handed off to sub-controllers and other Rack-callable objects, with `PATH_INFO` and `SCRIPT_NAME` now set to appropriate values, bring Scorched inline with the Rack specification. This differs from the original behaviour which was to just forward on the original env hash unmodified.
|
6
11
|
* URL helper method `absolute` and `url` now use the new env property `scorched.root_path` as their base path, rather than `SCRIPT_NAME`.
|
data/lib/scorched/controller.rb
CHANGED
@@ -72,7 +72,7 @@ module Scorched
|
|
72
72
|
handled: proc { |bool|
|
73
73
|
@_handled == bool
|
74
74
|
},
|
75
|
-
proc: proc {
|
75
|
+
proc: proc { |blocks|
|
76
76
|
[*blocks].all? { |b| instance_exec(&b) }
|
77
77
|
},
|
78
78
|
user_agent: proc { |user_agent|
|
@@ -127,14 +127,12 @@ module Scorched
|
|
127
127
|
# Raises ArgumentError if required key values are not provided.
|
128
128
|
def map(pattern: nil, priority: nil, conditions: {}, target: nil)
|
129
129
|
raise ArgumentError, "Mapping must specify url pattern and target" unless pattern && target
|
130
|
-
|
131
|
-
insert_pos = mappings.take_while { |v| priority <= v[:priority] }.length
|
132
|
-
mappings.insert(insert_pos, {
|
130
|
+
mappings << {
|
133
131
|
pattern: compile(pattern),
|
134
|
-
priority: priority,
|
132
|
+
priority: priority.to_i,
|
135
133
|
conditions: conditions,
|
136
134
|
target: target
|
137
|
-
}
|
135
|
+
}
|
138
136
|
end
|
139
137
|
alias :<< :map
|
140
138
|
|
@@ -242,8 +240,6 @@ module Scorched
|
|
242
240
|
env
|
243
241
|
end
|
244
242
|
env['scorched.root_path'] ||= env['SCRIPT_NAME']
|
245
|
-
env['scorched.path_info'] ||= env['PATH_INFO']
|
246
|
-
env['scorched.script_name'] ||= env['SCRIPT_NAME']
|
247
243
|
@request = Request.new(env)
|
248
244
|
@response = Response.new
|
249
245
|
end
|
@@ -267,7 +263,16 @@ module Scorched
|
|
267
263
|
pass if config[:auto_pass] && eligable_matches.empty?
|
268
264
|
run_filters(:before)
|
269
265
|
begin
|
270
|
-
|
266
|
+
# Re-order matches based on media_type, ensuring priority and definition order are respected appropriately.
|
267
|
+
eligable_matches.each_with_index.sort_by { |m,idx|
|
268
|
+
[
|
269
|
+
m.mapping[:priority] || 0,
|
270
|
+
[*m.mapping[:conditions][:media_type]].map { |type|
|
271
|
+
env['rack-accept.request'].media_type.qvalue(type)
|
272
|
+
}.max || 0,
|
273
|
+
-idx
|
274
|
+
]
|
275
|
+
}.reverse.each { |match,|
|
271
276
|
request.breadcrumb << match
|
272
277
|
break if catch(:pass) {
|
273
278
|
target = match.mapping[:target]
|
@@ -276,8 +281,8 @@ module Scorched
|
|
276
281
|
instance_exec(&target)
|
277
282
|
else
|
278
283
|
target.call(env.merge(
|
279
|
-
'SCRIPT_NAME' => request.matched_path,
|
280
|
-
'PATH_INFO' => request.unmatched_path[match.path.length..-1]
|
284
|
+
'SCRIPT_NAME' => request.matched_path.chomp('/'),
|
285
|
+
'PATH_INFO' => request.unmatched_path[match.path.chomp('/').length..-1]
|
281
286
|
))
|
282
287
|
end
|
283
288
|
end
|
@@ -431,7 +436,7 @@ module Scorched
|
|
431
436
|
template = if Symbol === string_or_file
|
432
437
|
file = string_or_file.to_s
|
433
438
|
file = file << ".#{engine}" unless derived_engine
|
434
|
-
file = File.
|
439
|
+
file = File.expand_path(file, dir) if dir
|
435
440
|
# Tilt still has unresolved file encoding issues. Until that's fixed, we read the file manually.
|
436
441
|
template_cache.fetch(:file, tilt_engine, file, tilt_options) do
|
437
442
|
tilt_engine.new(file, nil, tilt_options)
|
data/lib/scorched/request.rb
CHANGED
@@ -5,7 +5,7 @@ module Scorched
|
|
5
5
|
# Keeps track of the matched URL portions and what object handled them. Useful for debugging and building
|
6
6
|
# breadcrumb navigation.
|
7
7
|
def breadcrumb
|
8
|
-
env['breadcrumb'] ||= []
|
8
|
+
env['scorched.breadcrumb'] ||= []
|
9
9
|
end
|
10
10
|
|
11
11
|
# Returns a hash of captured strings from the last matched URL in the breadcrumb.
|
@@ -25,7 +25,7 @@ module Scorched
|
|
25
25
|
|
26
26
|
# The remaining portion of the path that has yet to be matched by any mappings.
|
27
27
|
def unmatched_path
|
28
|
-
path = unescaped_path
|
28
|
+
path = unescaped_path
|
29
29
|
path[0,0] = '/' if (path[0] != '/' && matched_path[-1] == '/') || path.empty?
|
30
30
|
path
|
31
31
|
end
|
@@ -35,6 +35,7 @@ module Scorched
|
|
35
35
|
def unescaped_path
|
36
36
|
path_info.split(/(%25|%2F)/i).each_slice(2).map { |v, m| URI.unescape(v) << (m || '') }.join('')
|
37
37
|
end
|
38
|
+
|
38
39
|
private
|
39
40
|
|
40
41
|
# 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
@@ -159,14 +159,29 @@ module Scorched
|
|
159
159
|
end
|
160
160
|
|
161
161
|
it "matches routes based on priority, otherwise giving precedence to those defined first" do
|
162
|
-
|
163
|
-
app << {pattern: '/', target: proc { |env|
|
164
|
-
app << {pattern: '/', target: proc { |env|
|
165
|
-
app << {pattern: '/',
|
166
|
-
|
167
|
-
rt.get('/').body.should == '
|
168
|
-
|
169
|
-
|
162
|
+
order = []
|
163
|
+
app << {pattern: '/', priority: -1, target: proc { |env| order << 'four'; [200, {}, ['ok']] }}
|
164
|
+
app << {pattern: '/', target: proc { |env| order << 'two'; throw :pass }}
|
165
|
+
app << {pattern: '/', target: proc { |env| order << 'three'; throw :pass }}
|
166
|
+
app << {pattern: '/', priority: 2, target: proc { |env| order << 'one'; throw :pass }}
|
167
|
+
rt.get('/').body.should == 'ok'
|
168
|
+
order.should == %w{one two three four}
|
169
|
+
end
|
170
|
+
|
171
|
+
it "finds the best match for media type whilst respecting priority and definition order" do
|
172
|
+
app << {pattern: '/', conditions: {media_type: 'text/html'}, target: proc { |env|
|
173
|
+
[200, {}, ['text/html']]
|
174
|
+
}}
|
175
|
+
app << {pattern: '/', conditions: {media_type: 'application/json'}, target: proc { |env|
|
176
|
+
[200, {}, ['application/json']]
|
177
|
+
}}
|
178
|
+
app << {pattern: '/', priority: 1, target: proc { |env|
|
179
|
+
[200, {}, ['anything']]
|
180
|
+
}}
|
181
|
+
rt.get('/', media_type: 'application/json, */*;q=0.5').body.should == 'anything'
|
182
|
+
app.mappings.pop
|
183
|
+
rt.get('/', {}, 'HTTP_ACCEPT' => 'text/html;q=0.5, application/json').body.should == 'application/json'
|
184
|
+
rt.get('/', {}, 'HTTP_ACCEPT' => 'text/html, */*;q=0.5').body.should == 'text/html'
|
170
185
|
end
|
171
186
|
end
|
172
187
|
|
@@ -267,24 +282,37 @@ module Scorched
|
|
267
282
|
rt.get('/article/hello-world').body.should == 'hello-world'
|
268
283
|
end
|
269
284
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
rt.get('/article/name').body.should == '/article/name'
|
277
|
-
end
|
278
|
-
|
279
|
-
it "propagates correclty mangles escaped PATH_INFO before passing to sub-controller" do
|
280
|
-
app << {pattern: '/:category', target: Class.new(Scorched::Controller) do
|
281
|
-
get('/:name') {
|
285
|
+
it "copies env, modifying PATH_INFO and SCRIPT_NAME, before passing onto Rack-callable object" do
|
286
|
+
inner_env, outer_env = nil, nil
|
287
|
+
app.before { outer_env = env }
|
288
|
+
app.controller '/article' do
|
289
|
+
get '/name' do
|
290
|
+
inner_env = env
|
282
291
|
'hello'
|
283
|
-
|
284
|
-
end
|
285
|
-
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
resp = rt.get('/article/name')
|
286
296
|
resp.status.should == 200
|
287
|
-
|
297
|
+
outer_env['SCRIPT_NAME'].should == ''
|
298
|
+
outer_env['PATH_INFO'].should == '/article/name'
|
299
|
+
inner_env['SCRIPT_NAME'].should == '/article'
|
300
|
+
inner_env['PATH_INFO'].should == '/name'
|
301
|
+
end
|
302
|
+
|
303
|
+
example "PATH_INFO and SCRIPT_NAME joined, should produce a full path" do
|
304
|
+
app.controller '/article/' do
|
305
|
+
get '/name' do
|
306
|
+
env['SCRIPT_NAME'] + env['PATH_INFO']
|
307
|
+
end
|
308
|
+
end
|
309
|
+
app.controller '/blah' do
|
310
|
+
get '/baz' do
|
311
|
+
env['SCRIPT_NAME'] + env['PATH_INFO']
|
312
|
+
end
|
313
|
+
end
|
314
|
+
rt.get('/article/name').body.should == '/article/name'
|
315
|
+
rt.get('/blah/baz').body.should == '/blah/baz'
|
288
316
|
end
|
289
317
|
|
290
318
|
describe "controller helper" do
|
@@ -895,7 +923,7 @@ module Scorched
|
|
895
923
|
app.render_defaults.each { |k,v| app.render_defaults[k] = nil }
|
896
924
|
end
|
897
925
|
|
898
|
-
it "can render a file, relative to the
|
926
|
+
it "can render a file, relative to the working directory" do
|
899
927
|
app.get('/') do
|
900
928
|
render(:'views/main.erb').should == "3 for me"
|
901
929
|
end
|
@@ -909,12 +937,24 @@ module Scorched
|
|
909
937
|
rt.get('/')
|
910
938
|
end
|
911
939
|
|
912
|
-
it "takes an optional view directory, relative to the
|
940
|
+
it "takes an optional view directory, relative to the working directory" do
|
913
941
|
app.get('/') do
|
914
942
|
render(:'main.erb', dir: 'views').should == "3 for me"
|
915
943
|
end
|
916
944
|
rt.get('/')
|
917
945
|
end
|
946
|
+
|
947
|
+
it "properly respects absolute and relative file paths in respect to the view directory" do
|
948
|
+
app.get('/relative') do
|
949
|
+
render(:'../views/main.erb', dir: 'views')
|
950
|
+
end
|
951
|
+
app.get('/absolute') do
|
952
|
+
File.dirname(__FILE__)
|
953
|
+
render(:"#{File.dirname(__FILE__)}/views/main.erb", dir: 'views')
|
954
|
+
end
|
955
|
+
rt.get('/relative').body.should == "3 for me"
|
956
|
+
rt.get('/absolute').body.should == "3 for me"
|
957
|
+
end
|
918
958
|
|
919
959
|
it "takes an optional block to be yielded by the view" do
|
920
960
|
app.get('/') do
|
@@ -1014,6 +1054,15 @@ module Scorched
|
|
1014
1054
|
builder.to_app
|
1015
1055
|
end
|
1016
1056
|
|
1057
|
+
it "can determine the root path of the current Scorched application" do
|
1058
|
+
my_app.controller '/article' do
|
1059
|
+
get '/name' do
|
1060
|
+
env['scorched.root_path']
|
1061
|
+
end
|
1062
|
+
end
|
1063
|
+
rt.get('/myapp/article/name').body.should == '/myapp'
|
1064
|
+
end
|
1065
|
+
|
1017
1066
|
describe "url" do
|
1018
1067
|
it "returns the fully qualified URL" do
|
1019
1068
|
my_app.get('/') { url }
|
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.17'
|
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-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|