rack-cache 1.9.0 → 1.12.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES +17 -0
- data/README.md +16 -4
- data/lib/rack/cache/context.rb +25 -7
- data/lib/rack/cache/entity_store.rb +4 -4
- data/lib/rack/cache/key.rb +21 -5
- data/lib/rack/cache/meta_store.rb +4 -3
- data/lib/rack/cache/options.rb +5 -0
- data/lib/rack/cache/response.rb +1 -0
- data/lib/rack/cache/storage.rb +7 -6
- metadata +4 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: faa3fda2990457be314ac3643ed59e28487459ed4022c6ef1682c4922389dee7
|
4
|
+
data.tar.gz: baf2634fa406e4c6da7e17339b4309217ba5ad99cda998fc67a0eeff369b513c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91d096f1cd9808a4d7983175af2549bc900a2b6ce3547799b30c11c8f9b233d874f0f1c6e64a36dbefda3161d12df50c696ba32e05f85ec7c34a825183499c01
|
7
|
+
data.tar.gz: 510a3c91dc5b06a6f87985f846a001ab543679e909902cdef7a2ebf96bd3efdedfc9e2b778d959e51b379dddf5fbb8d3ae4adac085a18228af2694c285327df7
|
data/CHANGES
CHANGED
@@ -1,3 +1,20 @@
|
|
1
|
+
## 1.12.0
|
2
|
+
|
3
|
+
* Add a fault_tolerant flag to fail-over to stale cache
|
4
|
+
|
5
|
+
## 1.11.1
|
6
|
+
|
7
|
+
* when ignoring parts of the query, remove query in key when all params are ignored
|
8
|
+
|
9
|
+
## 1.11.0
|
10
|
+
|
11
|
+
* Add a proc to allow ignoring parts of the query string in the key
|
12
|
+
|
13
|
+
## 1.10.0
|
14
|
+
|
15
|
+
* Pass Options To Underlying Storage Driver
|
16
|
+
* bump required ruby version to 2.3
|
17
|
+
|
1
18
|
## 1.9.0
|
2
19
|
|
3
20
|
* make purge not raise when not implemented
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ validation (Last-Modified, ETag) information:
|
|
16
16
|
|
17
17
|
For more information about Rack::Cache features and usage, see:
|
18
18
|
|
19
|
-
|
19
|
+
https://rtomayko.github.com/rack-cache/
|
20
20
|
|
21
21
|
Rack::Cache is not overly optimized for performance. The main goal of the
|
22
22
|
project is to provide a portable, easy-to-configure, and standards-based
|
@@ -70,7 +70,7 @@ You should now see `Rack::Cache` listed in the middleware pipeline:
|
|
70
70
|
|
71
71
|
rake middleware
|
72
72
|
|
73
|
-
[more information](
|
73
|
+
[more information](https://snippets.aktagon.com/snippets/302-how-to-setup-and-use-rack-cache-with-rails)
|
74
74
|
|
75
75
|
Using with Dalli
|
76
76
|
----------------
|
@@ -97,7 +97,7 @@ Does not persist response bodies (no disk/memory used).<br/>
|
|
97
97
|
Responses from the cache will have an empty body.<br/>
|
98
98
|
Clients must ignore these empty cached response (check for X-Rack-Cache response header).<br/>
|
99
99
|
Atm cannot handle streamed responses, patch needed.
|
100
|
-
|
100
|
+
|
101
101
|
```Ruby
|
102
102
|
require 'rack/cache'
|
103
103
|
|
@@ -109,6 +109,18 @@ use Rack::Cache,
|
|
109
109
|
run app
|
110
110
|
```
|
111
111
|
|
112
|
+
Ignoring tracking parameters in cache keys
|
113
|
+
-----------------
|
114
|
+
|
115
|
+
It's fairly common to include tracking parameters which don't affect the content
|
116
|
+
of the page. Since Rack::Cache uses the full URL as part of the cache key, this
|
117
|
+
can cause unneeded churn in your cache. If you're using the default key class
|
118
|
+
`Rack::Cache::Key`, you can configure a proc to ignore certain keys/values like
|
119
|
+
so:
|
120
|
+
|
121
|
+
```Ruby
|
122
|
+
Rack::Cache::Key.query_string_ignore = proc { |k, v| k =~ /^(trk|utm)_/ }
|
123
|
+
```
|
124
|
+
|
112
125
|
License: MIT<br/>
|
113
126
|
[![Build Status](https://travis-ci.org/rtomayko/rack-cache.svg)](https://travis-ci.org/rtomayko/rack-cache)
|
114
|
-
|
data/lib/rack/cache/context.rb
CHANGED
@@ -19,6 +19,7 @@ module Rack::Cache
|
|
19
19
|
@backend = backend
|
20
20
|
@trace = []
|
21
21
|
@env = nil
|
22
|
+
@options = options
|
22
23
|
|
23
24
|
initialize_options options
|
24
25
|
yield self if block_given?
|
@@ -31,14 +32,14 @@ module Rack::Cache
|
|
31
32
|
# value effects the result of this method immediately.
|
32
33
|
def metastore
|
33
34
|
uri = options['rack-cache.metastore']
|
34
|
-
storage.resolve_metastore_uri(uri)
|
35
|
+
storage.resolve_metastore_uri(uri, @options)
|
35
36
|
end
|
36
37
|
|
37
38
|
# The configured EntityStore instance. Changing the rack-cache.entitystore
|
38
39
|
# value effects the result of this method immediately.
|
39
40
|
def entitystore
|
40
41
|
uri = options['rack-cache.entitystore']
|
41
|
-
storage.resolve_entitystore_uri(uri)
|
42
|
+
storage.resolve_entitystore_uri(uri, @options)
|
42
43
|
end
|
43
44
|
|
44
45
|
# The Rack call interface. The receiver acts as a prototype and runs
|
@@ -160,10 +161,12 @@ module Rack::Cache
|
|
160
161
|
end
|
161
162
|
|
162
163
|
# Try to serve the response from cache. When a matching cache entry is
|
163
|
-
# found and is fresh, use it as the response without forwarding any
|
164
|
-
#
|
165
|
-
#
|
166
|
-
#
|
164
|
+
# found and is fresh, use it as the response without forwarding any request
|
165
|
+
# to the backend. When a matching cache entry is found but is stale, attempt
|
166
|
+
# to #validate the entry with the backend using conditional GET.
|
167
|
+
# If validation raises an exception and fault tolerant caching is enabled,
|
168
|
+
# serve the stale cache entry.
|
169
|
+
# When no matching cache entry is found, trigger miss processing.
|
167
170
|
def lookup
|
168
171
|
if @request.no_cache? && allow_reload?
|
169
172
|
record :reload
|
@@ -182,7 +185,11 @@ module Rack::Cache
|
|
182
185
|
entry
|
183
186
|
else
|
184
187
|
record :stale
|
185
|
-
|
188
|
+
if fault_tolerant?
|
189
|
+
validate_with_stale_cache_failover(entry)
|
190
|
+
else
|
191
|
+
validate(entry)
|
192
|
+
end
|
186
193
|
end
|
187
194
|
else
|
188
195
|
record :miss
|
@@ -191,6 +198,17 @@ module Rack::Cache
|
|
191
198
|
end
|
192
199
|
end
|
193
200
|
|
201
|
+
# Returns stale cache on exception.
|
202
|
+
def validate_with_stale_cache_failover(entry)
|
203
|
+
validate(entry)
|
204
|
+
rescue => e
|
205
|
+
record :connnection_failed
|
206
|
+
age = entry.age.to_s
|
207
|
+
entry.headers['Age'] = age
|
208
|
+
record "Fail-over to stale cache data with age #{age} due to #{e.class.name}: #{e}"
|
209
|
+
entry
|
210
|
+
end
|
211
|
+
|
194
212
|
# Validate that the cache entry is fresh. The original request is used
|
195
213
|
# as a template for a conditional GET request with the backend.
|
196
214
|
def validate(entry)
|
@@ -33,10 +33,10 @@ module Rack::Cache
|
|
33
33
|
|
34
34
|
# Stores entity bodies on the heap using a Hash object.
|
35
35
|
class Heap < EntityStore
|
36
|
-
|
37
36
|
# Create the store with the specified backing Hash.
|
38
|
-
def initialize(hash={})
|
37
|
+
def initialize(hash={}, options = {})
|
39
38
|
@hash = hash
|
39
|
+
@options = options
|
40
40
|
end
|
41
41
|
|
42
42
|
# Determine whether the response body with the specified key (SHA1)
|
@@ -71,8 +71,8 @@ module Rack::Cache
|
|
71
71
|
nil
|
72
72
|
end
|
73
73
|
|
74
|
-
def self.resolve(uri)
|
75
|
-
new
|
74
|
+
def self.resolve(uri, options = {})
|
75
|
+
new({}, options)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
data/lib/rack/cache/key.rb
CHANGED
@@ -4,6 +4,21 @@ module Rack::Cache
|
|
4
4
|
class Key
|
5
5
|
include Rack::Utils
|
6
6
|
|
7
|
+
# A proc for ignoring parts of query strings when generating a key. This is
|
8
|
+
# useful when you have parameters like `utm` or `trk` that don't affect the
|
9
|
+
# content on the page and are unique per-visitor or campaign. Parameters
|
10
|
+
# like these will be part of the key and cause a lot of churn.
|
11
|
+
#
|
12
|
+
# The block will be passed a key and value which are the name and value of
|
13
|
+
# that parameter.
|
14
|
+
#
|
15
|
+
# Example:
|
16
|
+
# `Rack::Cache::Key.query_string_ignore = proc { |k, v| k =~ /^(trk|utm)_/ }`
|
17
|
+
#
|
18
|
+
class << self
|
19
|
+
attr_accessor :query_string_ignore
|
20
|
+
end
|
21
|
+
|
7
22
|
# Implement .call, since it seems like the "Rack-y" thing to do. Plus, it
|
8
23
|
# opens the door for cache key generators to just be blocks.
|
9
24
|
def self.call(request)
|
@@ -42,11 +57,12 @@ module Rack::Cache
|
|
42
57
|
def query_string
|
43
58
|
return nil if @request.query_string.to_s.empty?
|
44
59
|
|
45
|
-
@request.query_string.split(/[&;] */n)
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
60
|
+
parts = @request.query_string.split(/[&;] */n)
|
61
|
+
parts.map! { |p| p.split('=', 2).map!{ |s| unescape(s) } }
|
62
|
+
parts.sort!
|
63
|
+
parts.reject!(&self.class.query_string_ignore)
|
64
|
+
parts.map! { |k,v| "#{escape(k)}=#{escape(v)}" }
|
65
|
+
parts.empty? ? nil : parts.join('&')
|
50
66
|
end
|
51
67
|
end
|
52
68
|
end
|
@@ -198,8 +198,9 @@ module Rack::Cache
|
|
198
198
|
# Concrete MetaStore implementation that uses a simple Hash to store
|
199
199
|
# request/response pairs on the heap.
|
200
200
|
class Heap < MetaStore
|
201
|
-
def initialize(hash={})
|
201
|
+
def initialize(hash={}, options = {})
|
202
202
|
@hash = hash
|
203
|
+
@options = options
|
203
204
|
end
|
204
205
|
|
205
206
|
def read(key)
|
@@ -223,8 +224,8 @@ module Rack::Cache
|
|
223
224
|
@hash
|
224
225
|
end
|
225
226
|
|
226
|
-
def self.resolve(uri)
|
227
|
-
new
|
227
|
+
def self.resolve(uri, options = {})
|
228
|
+
new({}, options)
|
228
229
|
end
|
229
230
|
end
|
230
231
|
|
data/lib/rack/cache/options.rb
CHANGED
@@ -107,6 +107,10 @@ module Rack::Cache
|
|
107
107
|
# be used.
|
108
108
|
option_accessor :use_native_ttl
|
109
109
|
|
110
|
+
# Specifies whether to serve a request from a stale cache entry if
|
111
|
+
# the attempt to revalidate the cache entry raises an exception.
|
112
|
+
option_accessor :fault_tolerant
|
113
|
+
|
110
114
|
# The underlying options Hash. During initialization (or outside of a
|
111
115
|
# request), this is a default values Hash. During a request, this is the
|
112
116
|
# Rack environment Hash. The default values Hash is merged in underneath
|
@@ -149,6 +153,7 @@ module Rack::Cache
|
|
149
153
|
'rack-cache.allow_reload' => false,
|
150
154
|
'rack-cache.allow_revalidate' => false,
|
151
155
|
'rack-cache.use_native_ttl' => false,
|
156
|
+
'rack-cache.fault_tolerant' => false,
|
152
157
|
}
|
153
158
|
self.options = options
|
154
159
|
end
|
data/lib/rack/cache/response.rb
CHANGED
data/lib/rack/cache/storage.rb
CHANGED
@@ -14,12 +14,12 @@ module Rack::Cache
|
|
14
14
|
@entitystores = {}
|
15
15
|
end
|
16
16
|
|
17
|
-
def resolve_metastore_uri(uri)
|
18
|
-
@metastores[uri.to_s] ||= create_store(MetaStore, uri)
|
17
|
+
def resolve_metastore_uri(uri, options = {})
|
18
|
+
@metastores[uri.to_s] ||= create_store(MetaStore, uri, options)
|
19
19
|
end
|
20
20
|
|
21
|
-
def resolve_entitystore_uri(uri)
|
22
|
-
@entitystores[uri.to_s] ||= create_store(EntityStore, uri)
|
21
|
+
def resolve_entitystore_uri(uri, options = {})
|
22
|
+
@entitystores[uri.to_s] ||= create_store(EntityStore, uri, options)
|
23
23
|
end
|
24
24
|
|
25
25
|
def clear
|
@@ -30,12 +30,13 @@ module Rack::Cache
|
|
30
30
|
|
31
31
|
private
|
32
32
|
|
33
|
-
def create_store(type, uri)
|
33
|
+
def create_store(type, uri, options = {})
|
34
34
|
if uri.respond_to?(:scheme) || uri.respond_to?(:to_str)
|
35
35
|
uri = URI.parse(uri) unless uri.respond_to?(:scheme)
|
36
36
|
if type.const_defined?(uri.scheme.upcase)
|
37
37
|
klass = type.const_get(uri.scheme.upcase)
|
38
|
-
klass.resolve(uri)
|
38
|
+
return klass.resolve(uri) if klass.method(:resolve).arity == 1
|
39
|
+
klass.resolve(uri, options)
|
39
40
|
else
|
40
41
|
fail "Unknown storage provider: #{uri.to_s}"
|
41
42
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Tomayko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-10-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -156,15 +156,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements:
|
157
157
|
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
|
-
version: 2.
|
159
|
+
version: 2.3.0
|
160
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
161
|
requirements:
|
162
162
|
- - ">="
|
163
163
|
- !ruby/object:Gem::Version
|
164
164
|
version: '0'
|
165
165
|
requirements: []
|
166
|
-
|
167
|
-
rubygems_version: 2.7.6
|
166
|
+
rubygems_version: 3.1.3
|
168
167
|
signing_key:
|
169
168
|
specification_version: 4
|
170
169
|
summary: HTTP Caching for Rack
|