roda-cj 0.9.1 → 0.9.2
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 +2 -0
- data/lib/roda/plugins/halt.rb +3 -3
- data/lib/roda/version.rb +1 -1
- data/lib/roda.rb +90 -31
- 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: 2f2740123aa0c6fafe4c1665f9c83e408cef9105
|
4
|
+
data.tar.gz: 74ec8c03a23405c2ac18eb23ceea5ccb3f4813c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 876514335f729d2beeea7b218bc14d7cac1772f5b568a4a985457b01321c16ef33116bb3dd605e218d3512185d34dffaca426b9e803d0e860c56619eb2838359
|
7
|
+
data.tar.gz: d046733fe6737ccabc612523c7812b1be778cea3675223a1a5bc3c202a91fad2da26e2fac842789542368fcb95e0b8d201cff9235de3410c3e1e5e414314f1f0
|
data/CHANGELOG
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
= HEAD
|
2
2
|
|
3
|
+
* Optimize matching by caching consume regexp for strings, regexp, symbol, and :extension matchers (jeremyevans)
|
4
|
+
|
3
5
|
* Add r.root for matching root (path "/"), for easier to read version of r.is "" (jeremyevans)
|
4
6
|
|
5
7
|
* Optimize r.is terminal matcher, remove :term hash matcher (jeremyevans)
|
data/lib/roda/plugins/halt.rb
CHANGED
@@ -22,19 +22,19 @@ class Roda
|
|
22
22
|
# Or set the response body and return:
|
23
23
|
#
|
24
24
|
# route do |r|
|
25
|
-
# r.halt(
|
25
|
+
# r.halt('body')
|
26
26
|
# end
|
27
27
|
#
|
28
28
|
# Or set both:
|
29
29
|
#
|
30
30
|
# route do |r|
|
31
|
-
# r.halt(403,
|
31
|
+
# r.halt(403, 'body')
|
32
32
|
# end
|
33
33
|
#
|
34
34
|
# Or set response status, headers, and body:
|
35
35
|
#
|
36
36
|
# route do |r|
|
37
|
-
# r.halt(403, {'Content-Type'=>'text/csv'},
|
37
|
+
# r.halt(403, {'Content-Type'=>'text/csv'}, 'body')
|
38
38
|
# end
|
39
39
|
#
|
40
40
|
# Note that there is a difference between provide status, headers, and body as separate
|
data/lib/roda/version.rb
CHANGED
data/lib/roda.rb
CHANGED
@@ -14,6 +14,43 @@ class Roda
|
|
14
14
|
# only contains the class methods.
|
15
15
|
class RodaRequest < ::Rack::Request;
|
16
16
|
@roda_class = ::Roda
|
17
|
+
@match_pattern_cache = {}
|
18
|
+
|
19
|
+
if defined?(RUBY_ENGINE) && RUBY_ENGINE != 'ruby'
|
20
|
+
# :nocov:
|
21
|
+
@match_pattern_mutex = Mutex.new
|
22
|
+
|
23
|
+
def self.cached_matcher(obj)
|
24
|
+
unless pattern = @match_pattern_mutex.synchronize{@match_pattern_cache[obj]}
|
25
|
+
pattern = consume_pattern(yield)
|
26
|
+
@match_pattern_mutex.synchronize{@match_pattern_cache[obj] = pattern}
|
27
|
+
end
|
28
|
+
pattern
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.inherited(subclass)
|
32
|
+
super
|
33
|
+
subclass.instance_variable_set(:@match_pattern_cache, {})
|
34
|
+
subclass.instance_variable_set(:@match_pattern_mutex, Mutex.new)
|
35
|
+
end
|
36
|
+
# :nocov:
|
37
|
+
else
|
38
|
+
# Return the cached pattern for the given object. If the object is
|
39
|
+
# not already cached, yield to get the basic pattern, and convert the
|
40
|
+
# basic pattern to a pattern that does not partial segments.
|
41
|
+
def self.cached_matcher(obj)
|
42
|
+
unless pattern = @match_pattern_cache[obj]
|
43
|
+
pattern = @match_pattern_cache[obj] = consume_pattern(yield)
|
44
|
+
end
|
45
|
+
pattern
|
46
|
+
end
|
47
|
+
|
48
|
+
# Initialize the match_pattern cache in the subclass.
|
49
|
+
def self.inherited(subclass)
|
50
|
+
super
|
51
|
+
subclass.instance_variable_set(:@match_pattern_cache, {})
|
52
|
+
end
|
53
|
+
end
|
17
54
|
|
18
55
|
class << self
|
19
56
|
# Reference to the Roda class related to this request class.
|
@@ -25,6 +62,15 @@ class Roda
|
|
25
62
|
def inspect
|
26
63
|
"#{roda_class.inspect}::RodaRequest"
|
27
64
|
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
# The pattern to use for consuming, based on the given argument. The returned
|
69
|
+
# pattern requires the path starts with a string and does not match partial
|
70
|
+
# segments.
|
71
|
+
def consume_pattern(pattern)
|
72
|
+
/\A(\/(?:#{pattern}))(\/|\z)/
|
73
|
+
end
|
28
74
|
end
|
29
75
|
end
|
30
76
|
|
@@ -390,12 +436,49 @@ class Roda
|
|
390
436
|
throw :halt, response
|
391
437
|
end
|
392
438
|
|
439
|
+
# Match any of the elements in the given array. Return at the
|
440
|
+
# first match without evaluating future matches. Returns false
|
441
|
+
# if no elements in the array match.
|
442
|
+
def _match_array(matcher)
|
443
|
+
matcher.any? do |m|
|
444
|
+
if matched = match(m)
|
445
|
+
if m.is_a?(String)
|
446
|
+
captures.push(m)
|
447
|
+
end
|
448
|
+
end
|
449
|
+
|
450
|
+
matched
|
451
|
+
end
|
452
|
+
end
|
453
|
+
|
454
|
+
# Match the given regexp exactly if it matches a full segment.
|
455
|
+
def _match_regexp(re)
|
456
|
+
consume(self.class.cached_matcher(re){re})
|
457
|
+
end
|
458
|
+
|
459
|
+
# Match the given hash if all hash matchers match.
|
460
|
+
def _match_hash(hash)
|
461
|
+
hash.all?{|k,v| send("match_#{k}", v)}
|
462
|
+
end
|
463
|
+
|
464
|
+
# Match the given string to the request path. Regexp escapes the
|
465
|
+
# string so that regexp metacharacters are not matched, and recognizes
|
466
|
+
# colon tokens for placeholders.
|
467
|
+
def _match_string(str)
|
468
|
+
consume(self.class.cached_matcher(str){Regexp.escape(str).gsub(/:\w+/, SEGMENT)})
|
469
|
+
end
|
470
|
+
|
471
|
+
# Match the given symbol if any segment matches.
|
472
|
+
def _match_symbol(sym)
|
473
|
+
consume(self.class.cached_matcher(sym){SEGMENT})
|
474
|
+
end
|
475
|
+
|
393
476
|
# Attempts to match the pattern to the current path. If there is no
|
394
477
|
# match, returns false without changes. Otherwise, modifies
|
395
478
|
# SCRIPT_NAME to include the matched path, removes the matched
|
396
479
|
# path from PATH_INFO, and updates captures with any regex captures.
|
397
480
|
def consume(pattern)
|
398
|
-
matchdata = env[PATH_INFO].match(
|
481
|
+
matchdata = env[PATH_INFO].match(pattern)
|
399
482
|
|
400
483
|
return false unless matchdata
|
401
484
|
|
@@ -423,17 +506,17 @@ class Roda
|
|
423
506
|
def match(matcher)
|
424
507
|
case matcher
|
425
508
|
when String
|
426
|
-
|
509
|
+
_match_string(matcher)
|
427
510
|
when Regexp
|
428
|
-
|
511
|
+
_match_regexp(matcher)
|
429
512
|
when Symbol
|
430
|
-
|
513
|
+
_match_symbol(matcher)
|
431
514
|
when TERM
|
432
515
|
env[PATH_INFO] == EMPTY_STRING
|
433
516
|
when Hash
|
434
|
-
matcher
|
517
|
+
_match_hash(matcher)
|
435
518
|
when Array
|
436
|
-
|
519
|
+
_match_array(matcher)
|
437
520
|
when Proc
|
438
521
|
matcher.call
|
439
522
|
else
|
@@ -441,25 +524,10 @@ class Roda
|
|
441
524
|
end
|
442
525
|
end
|
443
526
|
|
444
|
-
# Match any of the elements in the given array. Return at the
|
445
|
-
# first match without evaluating future matches. Returns false
|
446
|
-
# if no elements in the array match.
|
447
|
-
def match_array(matcher)
|
448
|
-
matcher.any? do |m|
|
449
|
-
if matched = match(m)
|
450
|
-
if m.is_a?(String)
|
451
|
-
captures.push(m)
|
452
|
-
end
|
453
|
-
end
|
454
|
-
|
455
|
-
matched
|
456
|
-
end
|
457
|
-
end
|
458
|
-
|
459
527
|
# Match files with the given extension. Requires that the
|
460
528
|
# request path end with the extension.
|
461
529
|
def match_extension(ext)
|
462
|
-
consume("([^\\/]+?)\.#{ext}\\z")
|
530
|
+
consume(self.class.cached_matcher(ext){"([^\\/]+?)\.#{ext}\\z"})
|
463
531
|
end
|
464
532
|
|
465
533
|
# Match by request method. This can be an array if you want
|
@@ -488,15 +556,6 @@ class Roda
|
|
488
556
|
end
|
489
557
|
end
|
490
558
|
|
491
|
-
# Match the given string to the request path. Regexp escapes the
|
492
|
-
# string so that regexp metacharacters are not matched, and recognizes
|
493
|
-
# colon tokens for placeholders.
|
494
|
-
def match_string(str)
|
495
|
-
str = Regexp.escape(str)
|
496
|
-
str.gsub!(/:\w+/, SEGMENT)
|
497
|
-
consume(str)
|
498
|
-
end
|
499
|
-
|
500
559
|
# Yield to the given block, clearing any captures before
|
501
560
|
# yielding and restoring the SCRIPT_NAME and PATH_INFO on exit.
|
502
561
|
def try
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: roda-cj
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeremy Evans
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-08-
|
11
|
+
date: 2014-08-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|