rack-steady_etag 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -4
- data/Gemfile.lock +4 -6
- data/README.md +4 -2
- data/lib/rack/steady_etag/version.rb +1 -1
- data/lib/rack/steady_etag.rb +26 -16
- data/rack-steady_etag.gemspec +5 -5
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e9c4ec38a103ceb321da1a48a78a09872e7d47875fbd0fa1e15814116f79e64
|
4
|
+
data.tar.gz: cb4abb1d12ac1c2a06427f7e6f63de34c4d8b99c56248287470f2c4aa3be655a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ab95c964994e61c962903a4a395be6715bc2a8d69e1cb66f0eb19371c4691972ff8d2cd76d8740129715652d515f0f0704238afbae5e30be9527065e0b127d59
|
7
|
+
data.tar.gz: f10b144400e01f9587e51f7f20330cb8a3d14381c4183ecfa84f9180d301b01986eeb1df3b1f498115eabab2161763106e8dde26c96e3ce9fc031eb94c56016e
|
data/CHANGELOG.md
CHANGED
@@ -5,14 +5,15 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
5
5
|
|
6
6
|
## Unreleased
|
7
7
|
|
8
|
-
|
8
|
+
## 0.2.0 - 2022-05-12
|
9
9
|
|
10
|
-
|
10
|
+
- Be more compatible with Rack 2.2.2:
|
11
|
+
- Always set a `Cache-Control` header, even for responses that we don't try to digest.
|
12
|
+
- Strip patterns for responses with `Cache-Control: public`
|
13
|
+
- Requires Rack 2.x (we want to break with Rack 3)
|
11
14
|
|
12
15
|
## 0.1.1 - 2022-05-16
|
13
16
|
|
14
|
-
### Compatible changes
|
15
|
-
|
16
17
|
- Activate rubygems MFA
|
17
18
|
|
18
19
|
## 0.1.0 - 2021-12-01
|
data/Gemfile.lock
CHANGED
@@ -1,25 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rack-steady_etag (0.
|
4
|
+
rack-steady_etag (0.2.0)
|
5
5
|
activesupport (>= 3.2)
|
6
|
-
rack
|
6
|
+
rack (~> 2.0)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activesupport (
|
11
|
+
activesupport (7.0.1)
|
12
12
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
13
13
|
i18n (>= 1.6, < 2)
|
14
14
|
minitest (>= 5.1)
|
15
15
|
tzinfo (~> 2.0)
|
16
|
-
zeitwerk (~> 2.3)
|
17
16
|
byebug (11.1.3)
|
18
17
|
concurrent-ruby (1.1.9)
|
19
18
|
diff-lcs (1.4.4)
|
20
19
|
i18n (1.8.11)
|
21
20
|
concurrent-ruby (~> 1.0)
|
22
|
-
minitest (5.
|
21
|
+
minitest (5.15.0)
|
23
22
|
rack (2.2.3)
|
24
23
|
rake (13.0.6)
|
25
24
|
rspec (3.10.0)
|
@@ -37,7 +36,6 @@ GEM
|
|
37
36
|
rspec-support (3.10.3)
|
38
37
|
tzinfo (2.0.4)
|
39
38
|
concurrent-ruby (~> 1.0)
|
40
|
-
zeitwerk (2.5.1)
|
41
39
|
|
42
40
|
PLATFORMS
|
43
41
|
x86_64-linux
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ Transformations are only applied for the `ETag` hash. The response body will not
|
|
39
39
|
- No `ETag` is generated when the response already has an `Last-Modified` header.
|
40
40
|
|
41
41
|
|
42
|
-
## Installation
|
42
|
+
## Installation in Rails
|
43
43
|
|
44
44
|
Add this line to your application's Gemfile:
|
45
45
|
|
@@ -56,9 +56,11 @@ bundle install
|
|
56
56
|
In your `config/application.rb`:
|
57
57
|
|
58
58
|
```ruby
|
59
|
-
config.middleware.swap Rack::ETag, Rack::SteadyETag
|
59
|
+
config.middleware.swap Rack::ETag, Rack::SteadyETag, 'no-cache'
|
60
60
|
```
|
61
61
|
|
62
|
+
The `'no-cache'` argument is the default `Cache-Control` for responses that cannot be digested. While it may feel surprising that the middleware changes the `Cache-Control` header in such a case, the [Rails default middleware stack](https://github.com/rails/rails/blob/d96609505511a76c618dc3adfa3ca4679317d008/railties/lib/rails/application/default_middleware_stack.rb#L81) configures the same behavior.
|
63
|
+
|
62
64
|
|
63
65
|
## Development
|
64
66
|
|
data/lib/rack/steady_etag.rb
CHANGED
@@ -6,8 +6,8 @@ require_relative "steady_etag/version"
|
|
6
6
|
|
7
7
|
module Rack
|
8
8
|
|
9
|
-
# Based on Rack::Etag
|
10
|
-
# https://github.com/rack/rack/blob/
|
9
|
+
# Based on Rack::Etag from rack 2.2.2
|
10
|
+
# https://github.com/rack/rack/blob/v2.2.2/lib/rack/etag.rb
|
11
11
|
#
|
12
12
|
# Automatically sets the ETag header on all String bodies.
|
13
13
|
#
|
@@ -15,6 +15,8 @@ module Rack
|
|
15
15
|
# a sendfile body (body.responds_to :to_path) is given (since such cases
|
16
16
|
# should be handled by apache/nginx).
|
17
17
|
class SteadyETag
|
18
|
+
|
19
|
+
# Yes, Rack::ETag sets a default Cache-Control for responses that it can digest.
|
18
20
|
DEFAULT_CACHE_CONTROL = "max-age=0, private, must-revalidate"
|
19
21
|
|
20
22
|
IGNORE_PATTERNS = [
|
@@ -24,11 +26,14 @@ module Rack
|
|
24
26
|
lambda { |string| string.gsub(/(<script\b[^>]*)\bnonce=(["'])[^"']+\2+/i, '\1') }
|
25
27
|
]
|
26
28
|
|
27
|
-
def initialize(app, no_digest_cache_control
|
29
|
+
def initialize(app, no_digest_cache_control = nil, digest_cache_control = DEFAULT_CACHE_CONTROL)
|
28
30
|
@app = app
|
31
|
+
|
29
32
|
@digest_cache_control = digest_cache_control
|
33
|
+
|
34
|
+
# Rails sets a default `Cache-Control: no-cache` for responses that
|
35
|
+
# we cannot digest.
|
30
36
|
@no_digest_cache_control = no_digest_cache_control
|
31
|
-
@ignore_patterns = ignore_patterns
|
32
37
|
end
|
33
38
|
|
34
39
|
def call(env)
|
@@ -45,6 +50,18 @@ module Rack
|
|
45
50
|
headers[ETAG] = %(W/"#{digest}") if digest
|
46
51
|
end
|
47
52
|
|
53
|
+
# It would make more sense to only set a Cache-Control for responses that we process.
|
54
|
+
# However, the original Rack::ETag sets Cache-Control: @no_digest_cache_control
|
55
|
+
# for all responses, even responses that we don't otherwise modify.
|
56
|
+
# Hence if we move this code into the `if` above we would remove Rails' default
|
57
|
+
# Cache-Control headers for non-digestable responses, which would be a considerable
|
58
|
+
# change in behavior.
|
59
|
+
if digest
|
60
|
+
set_cache_control_with_digest(headers)
|
61
|
+
else
|
62
|
+
set_cache_control_without_digest(headers)
|
63
|
+
end
|
64
|
+
|
48
65
|
[status, headers, body]
|
49
66
|
end
|
50
67
|
|
@@ -63,6 +80,9 @@ module Rack
|
|
63
80
|
end
|
64
81
|
|
65
82
|
def etag_body?(body)
|
83
|
+
# Rack main branch checks for `:to_ary` here to exclude streaming responses,
|
84
|
+
# but that had other issues for me in testing. Maybe recheck when there is a
|
85
|
+
# new Rack release after 2.2.2.
|
66
86
|
!body.respond_to?(:to_path)
|
67
87
|
end
|
68
88
|
|
@@ -70,10 +90,6 @@ module Rack
|
|
70
90
|
headers.key?(ETAG) || headers.key?('Last-Modified')
|
71
91
|
end
|
72
92
|
|
73
|
-
def cache_control_private?(headers)
|
74
|
-
headers[CACHE_CONTROL] && headers[CACHE_CONTROL] =~ /\bprivate\b/
|
75
|
-
end
|
76
|
-
|
77
93
|
def digest_body(body, headers, session)
|
78
94
|
parts = []
|
79
95
|
digest = nil
|
@@ -82,11 +98,7 @@ module Rack
|
|
82
98
|
parts << part
|
83
99
|
|
84
100
|
if part.present?
|
85
|
-
|
86
|
-
|
87
|
-
if cache_control_private?(headers)
|
88
|
-
part = strip_ignore_patterns(part)
|
89
|
-
end
|
101
|
+
part = strip_ignore_patterns(part)
|
90
102
|
|
91
103
|
unless digest
|
92
104
|
digest = Digest::SHA256.new
|
@@ -102,15 +114,13 @@ module Rack
|
|
102
114
|
|
103
115
|
if digest
|
104
116
|
digest = digest.hexdigest.byteslice(0,32)
|
105
|
-
else
|
106
|
-
set_cache_control_without_digest(headers)
|
107
117
|
end
|
108
118
|
|
109
119
|
[digest, parts]
|
110
120
|
end
|
111
121
|
|
112
122
|
def strip_ignore_patterns(html)
|
113
|
-
|
123
|
+
IGNORE_PATTERNS.each do |ignore_pattern|
|
114
124
|
if ignore_pattern.respond_to?(:call)
|
115
125
|
html = ignore_pattern.call(html)
|
116
126
|
else
|
data/rack-steady_etag.gemspec
CHANGED
@@ -31,10 +31,10 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
32
32
|
spec.require_paths = ["lib"]
|
33
33
|
|
34
|
-
#
|
35
|
-
|
36
|
-
|
34
|
+
# I expect Rack 3 to have a new ETag middleware to no longer buffer
|
35
|
+
# streaming responses: https://github.com/rack/rack/issues/1619
|
36
|
+
# Once Rack 3 is out we should release a new version of this gem.
|
37
|
+
spec.add_dependency "rack", '~>2.0'
|
37
38
|
|
38
|
-
|
39
|
-
# guide at: https://bundler.io/guides/creating_gem.html
|
39
|
+
spec.add_dependency 'activesupport', '>= 3.2'
|
40
40
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-steady_etag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Henning Koch
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '2.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0'
|
26
|
+
version: '2.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -83,7 +83,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
83
83
|
- !ruby/object:Gem::Version
|
84
84
|
version: '0'
|
85
85
|
requirements: []
|
86
|
-
rubygems_version: 3.
|
86
|
+
rubygems_version: 3.2.6
|
87
87
|
signing_key:
|
88
88
|
specification_version: 4
|
89
89
|
summary: Rack Middleware that produces the same ETag for responses that only differ
|