padrino-cache 0.18.0 → 0.18.1
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/lib/padrino-cache/helpers/page.rb +23 -11
- data/test/test_padrino_cache.rb +144 -0
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ba34b4d72a0a4f039038801633b094117edb2548332855bfe6348700c1c4ed4f
|
|
4
|
+
data.tar.gz: 3f6382fa84609a885528064148e3b77674745bb2e14c3ed4f40f34da6972ef8b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 36573ec3921e7ff49e5cdeaddf9cd98eecd60e70272c51247821015e5115ebcea88a79de2ba954a599386cb0df32b00fd34b1afd537103565a18ddd7365bbaf9
|
|
7
|
+
data.tar.gz: 8bb374c1341562a7dcc2101e2e28bb38fe2eb76efa8c6cc6cf017c5d1855510cac823671f70218089846239f7fc633e7005b2d9199e5de526a154d82752f0869
|
|
@@ -60,7 +60,7 @@ module Padrino
|
|
|
60
60
|
#
|
|
61
61
|
# @api public
|
|
62
62
|
def expires(time)
|
|
63
|
-
@
|
|
63
|
+
@_cache_expires = time
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
##
|
|
@@ -89,7 +89,11 @@ module Padrino
|
|
|
89
89
|
#
|
|
90
90
|
def cache_key(name = nil, &block)
|
|
91
91
|
raise 'Can not provide both cache_key and a block' if name && block
|
|
92
|
-
|
|
92
|
+
|
|
93
|
+
@_cache_key = name || block
|
|
94
|
+
# A Symbol or a block is the same for every request, so later requests can look it up before the
|
|
95
|
+
# handler runs. Any other key (a String built from params) belongs to this request only.
|
|
96
|
+
@route.cache_key = @_cache_key if @_cache_key.is_a?(Symbol) || @_cache_key.is_a?(Proc)
|
|
93
97
|
end
|
|
94
98
|
|
|
95
99
|
CACHED_VERBS = { 'GET' => true, 'HEAD' => true }.freeze
|
|
@@ -97,21 +101,29 @@ module Padrino
|
|
|
97
101
|
def self.padrino_route_added(route, verb, *)
|
|
98
102
|
return unless route.cache && CACHED_VERBS[verb]
|
|
99
103
|
|
|
100
|
-
route
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
end
|
|
104
|
+
# Remember the key and expiry set before this route (by an app-level before filter), so a route
|
|
105
|
+
# reached through pass starts from them rather than from this route's.
|
|
106
|
+
route.before_filters { @_cache_outer = [@_cache_key, @_cache_expires] }
|
|
107
|
+
# The lookup is the route's last condition: it runs after every before filter and condition, so
|
|
108
|
+
# access checks written there apply to cached pages too.
|
|
109
|
+
route.custom_conditions << instance_method(:serve_cached_response)
|
|
107
110
|
|
|
108
111
|
route.after_filters do
|
|
109
|
-
save_cached_response(route.cache_expires) if settings.caching?
|
|
112
|
+
save_cached_response(@_cache_expires.nil? ? route.cache_expires : @_cache_expires) if settings.caching?
|
|
113
|
+
@_cache_key, @_cache_expires = @_cache_outer
|
|
110
114
|
end
|
|
111
115
|
end
|
|
112
116
|
|
|
113
117
|
private
|
|
114
118
|
|
|
119
|
+
def serve_cached_response
|
|
120
|
+
if settings.caching? && (cached_response = load_cached_response)
|
|
121
|
+
content_type cached_response[:content_type]
|
|
122
|
+
halt 200, cached_response[:body]
|
|
123
|
+
end
|
|
124
|
+
true
|
|
125
|
+
end
|
|
126
|
+
|
|
115
127
|
def load_cached_response
|
|
116
128
|
began_at = Time.now
|
|
117
129
|
route_cache_key = resolve_cache_key || env['PATH_INFO']
|
|
@@ -142,7 +154,7 @@ module Padrino
|
|
|
142
154
|
# Resolve the cache_key when it's a block in the correct context.
|
|
143
155
|
#
|
|
144
156
|
def resolve_cache_key
|
|
145
|
-
key = @route.cache_key
|
|
157
|
+
key = @_cache_key || @route.cache_key
|
|
146
158
|
key.is_a?(Proc) ? instance_eval(&key) : key
|
|
147
159
|
end
|
|
148
160
|
|
data/test/test_padrino_cache.rb
CHANGED
|
@@ -381,6 +381,150 @@ describe 'PadrinoCache' do
|
|
|
381
381
|
assert_equal 2, call_count
|
|
382
382
|
end
|
|
383
383
|
|
|
384
|
+
it 'should not reuse a string cache key from another request' do
|
|
385
|
+
mock_app do
|
|
386
|
+
register Padrino::Cache
|
|
387
|
+
enable :caching
|
|
388
|
+
get '/post/:id', cache: true do
|
|
389
|
+
cache_key "post-#{params[:id]}"
|
|
390
|
+
"post #{params[:id]}"
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
get '/post/1'
|
|
395
|
+
assert_equal 'post 1', body
|
|
396
|
+
get '/post/2'
|
|
397
|
+
assert_equal 'post 2', body
|
|
398
|
+
get '/post/1'
|
|
399
|
+
assert_equal 'post 1', body
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it 'should run controller before filters on a cached response' do
|
|
403
|
+
mock_app do
|
|
404
|
+
register Padrino::Cache
|
|
405
|
+
enable :caching
|
|
406
|
+
controller :secret, cache: true do
|
|
407
|
+
before { halt 403, 'denied' unless params[:ok] }
|
|
408
|
+
get(:index) { 'secret page' }
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
get '/secret?ok=1'
|
|
413
|
+
assert_equal 'secret page', body
|
|
414
|
+
get '/secret'
|
|
415
|
+
assert_equal 403, status
|
|
416
|
+
assert_equal 'denied', body
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it 'should use a cache key set in a controller before filter for the lookup' do
|
|
420
|
+
calls = 0
|
|
421
|
+
mock_app do
|
|
422
|
+
register Padrino::Cache
|
|
423
|
+
enable :caching
|
|
424
|
+
controller :users, cache: true do
|
|
425
|
+
before { cache_key "user-#{params[:u]}" }
|
|
426
|
+
get(:show, with: :u) { calls += 1; "user #{params[:u]}" }
|
|
427
|
+
end
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
get '/users/show/a'
|
|
431
|
+
get '/users/show/b'
|
|
432
|
+
get '/users/show/a'
|
|
433
|
+
assert_equal 'user a', body
|
|
434
|
+
assert_equal 2, calls
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
it 'should not apply a cache key to the next route after pass' do
|
|
438
|
+
mock_app do
|
|
439
|
+
register Padrino::Cache
|
|
440
|
+
enable :caching
|
|
441
|
+
get '/x/:id', cache: true do
|
|
442
|
+
cache_key :shared
|
|
443
|
+
pass if params[:id] == 'skip'
|
|
444
|
+
"A #{params[:id]}"
|
|
445
|
+
end
|
|
446
|
+
get('/x/:id', cache: true) { "B #{params[:id]}" }
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
get '/x/skip'
|
|
450
|
+
assert_equal 'B skip', body
|
|
451
|
+
get '/x/1'
|
|
452
|
+
assert_equal 'A 1', body
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
it 'should check route conditions on a cached response' do
|
|
456
|
+
mock_app do
|
|
457
|
+
register Padrino::Cache
|
|
458
|
+
enable :caching
|
|
459
|
+
def self.protect(protected)
|
|
460
|
+
condition { halt 403, 'No secrets for you!' unless params[:key] == 's3cr3t' } if protected
|
|
461
|
+
end
|
|
462
|
+
controller cache: true, conditions: { protect: true } do
|
|
463
|
+
get('/private') { 'secret stuff' }
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
get '/private?key=s3cr3t'
|
|
468
|
+
assert_equal 'secret stuff', body
|
|
469
|
+
get '/private'
|
|
470
|
+
assert_equal 403, status
|
|
471
|
+
assert_equal 'No secrets for you!', body
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
it 'should keep a cache key from an app-level before filter for the route reached through pass' do
|
|
475
|
+
mock_app do
|
|
476
|
+
register Padrino::Cache
|
|
477
|
+
enable :caching
|
|
478
|
+
before { cache_key "u-#{params[:u]}" }
|
|
479
|
+
get('/z', cache: true) { pass }
|
|
480
|
+
get('/z', cache: true) { "B for #{params[:u]}" }
|
|
481
|
+
end
|
|
482
|
+
|
|
483
|
+
get '/z?u=alice'
|
|
484
|
+
assert_equal 'B for alice', body
|
|
485
|
+
get '/z?u=bob'
|
|
486
|
+
assert_equal 'B for bob', body
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
it 'should keep expires to the request that set it' do
|
|
490
|
+
stored = []
|
|
491
|
+
store = Object.new
|
|
492
|
+
store.define_singleton_method(:[]) { |_key| nil }
|
|
493
|
+
store.define_singleton_method(:store) { |key, _value, options| stored << [key, options[:expires]] }
|
|
494
|
+
mock_app do
|
|
495
|
+
register Padrino::Cache
|
|
496
|
+
enable :caching
|
|
497
|
+
set :cache, store
|
|
498
|
+
get '/foo', cache: true do
|
|
499
|
+
expires 100 if params[:long]
|
|
500
|
+
'foo'
|
|
501
|
+
end
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
get '/foo?long=1'
|
|
505
|
+
get '/foo'
|
|
506
|
+
assert_equal [['/foo', 100], ['/foo', nil]], stored
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
it 'should let expires false in a handler override the route expiry' do
|
|
510
|
+
stored = []
|
|
511
|
+
store = Object.new
|
|
512
|
+
store.define_singleton_method(:[]) { |_key| nil }
|
|
513
|
+
store.define_singleton_method(:store) { |key, _value, options| stored << [key, options[:expires]] }
|
|
514
|
+
mock_app do
|
|
515
|
+
register Padrino::Cache
|
|
516
|
+
enable :caching
|
|
517
|
+
set :cache, store
|
|
518
|
+
get '/ef', cache: true, expires: 60 do
|
|
519
|
+
expires false
|
|
520
|
+
'ef'
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
get '/ef'
|
|
525
|
+
assert_equal [['/ef', false]], stored
|
|
526
|
+
end
|
|
527
|
+
|
|
384
528
|
it 'should resolve block cache keys' do
|
|
385
529
|
call_count = 0
|
|
386
530
|
mock_app do
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: padrino-cache
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.18.
|
|
4
|
+
version: 0.18.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Padrino Team
|
|
@@ -19,28 +19,28 @@ dependencies:
|
|
|
19
19
|
requirements:
|
|
20
20
|
- - '='
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: 0.18.
|
|
22
|
+
version: 0.18.1
|
|
23
23
|
type: :runtime
|
|
24
24
|
prerelease: false
|
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
|
26
26
|
requirements:
|
|
27
27
|
- - '='
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: 0.18.
|
|
29
|
+
version: 0.18.1
|
|
30
30
|
- !ruby/object:Gem::Dependency
|
|
31
31
|
name: padrino-helpers
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
|
33
33
|
requirements:
|
|
34
34
|
- - '='
|
|
35
35
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: 0.18.
|
|
36
|
+
version: 0.18.1
|
|
37
37
|
type: :runtime
|
|
38
38
|
prerelease: false
|
|
39
39
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
40
|
requirements:
|
|
41
41
|
- - '='
|
|
42
42
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: 0.18.
|
|
43
|
+
version: 0.18.1
|
|
44
44
|
- !ruby/object:Gem::Dependency
|
|
45
45
|
name: moneta
|
|
46
46
|
requirement: !ruby/object:Gem::Requirement
|