rack-cache 1.8.0 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a52edf08cd4dca09954d3269805b240539a240f89df89e2bdda063077a4f826f
4
- data.tar.gz: 3474fecb6a64d70e47531d5c9978673cf0c67a5d276aa7ccb35d5368d9be0960
3
+ metadata.gz: bb5dc6e1debaa841064dcf380a8015f6f63568187fda3ede9da81ed8d84041ec
4
+ data.tar.gz: 96c26c225e307ddaeaf6f8cbd5d219b0dacdcf18d9b36b11282af98a458af8be
5
5
  SHA512:
6
- metadata.gz: 3e83d8956c8c5e25a8c4f0109e50a39f7175b46edda89e41b9d62939779439c0880b7f17fcd9aae63c47e2a4715ce7ea0678d7231135f009cffbe6b588c772af
7
- data.tar.gz: 4351bd9ae5eb974590e8d39b8328a083a9bd2be4456d6966e2d0c12b35d3c28a7c367b8335296827e6490c3513cffc5b2b45b9231ec45b93f541ed61a9676c57
6
+ metadata.gz: b28a19dbb93f8eddce6bc7ab9e8307c9222c21131e5340db30b132c119ac8dbfd7079801365dbf987c68676f7605b26daab9bb03f996d2128c4ee9153a10006b
7
+ data.tar.gz: 4b810c3911b1e37dba674188165553c179da277f1ef0a7dd804afa8bc037f956f00322cfab0ab2d22a0e30e7ce44fb5eb1d07401c64b8b8c91f760c0a3c12b2c
data/CHANGES CHANGED
@@ -1,4 +1,25 @@
1
- ## next
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
+
18
+ ## 1.9.0
19
+
20
+ * make purge not raise when not implemented
21
+
22
+ ## 1.8.0
2
23
 
3
24
  * Meta stores will purge keys when no entity store entries are found
4
25
 
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
- http://rtomayko.github.com/rack-cache/
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](http://snippets.aktagon.com/snippets/302-how-to-setup-and-use-rack-cache-with-rails)
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).
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
-
@@ -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
- # request to the backend. When a matching cache entry is found but is
165
- # stale, attempt to #validate the entry with the backend using conditional
166
- # GET. When no matching cache entry is found, trigger #miss processing.
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
- validate(entry)
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
 
@@ -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
- map { |p| p.split('=', 2).map{ |s| unescape(s) } }.
47
- sort.
48
- map { |k,v| "#{escape(k)}=#{escape(v)}" }.
49
- join('&')
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
@@ -43,7 +43,15 @@ module Rack::Cache
43
43
  else
44
44
  # the metastore referenced an entity that doesn't exist in
45
45
  # the entitystore, purge the entry from the meta-store
46
- purge(key)
46
+ begin
47
+ purge(key)
48
+ rescue NotImplementedError
49
+ @@warned_on_purge ||= begin
50
+ warn "WARNING: Future releases may require purge implementation for #{self.class.name}"
51
+ true
52
+ end
53
+ nil
54
+ end
47
55
  end
48
56
  end
49
57
 
@@ -190,8 +198,9 @@ module Rack::Cache
190
198
  # Concrete MetaStore implementation that uses a simple Hash to store
191
199
  # request/response pairs on the heap.
192
200
  class Heap < MetaStore
193
- def initialize(hash={})
201
+ def initialize(hash={}, options = {})
194
202
  @hash = hash
203
+ @options = options
195
204
  end
196
205
 
197
206
  def read(key)
@@ -215,8 +224,8 @@ module Rack::Cache
215
224
  @hash
216
225
  end
217
226
 
218
- def self.resolve(uri)
219
- new
227
+ def self.resolve(uri, options = {})
228
+ new({}, options)
220
229
  end
221
230
  end
222
231
 
@@ -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
@@ -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.8.0
4
+ version: 1.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Tomayko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-07 00:00:00.000000000 Z
11
+ date: 2020-06-06 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.0.0
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
- rubyforge_project:
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