rack-steady_etag 0.1.1 → 0.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bbaf5489b11a9fe181a1f92469ebaebafaa41bb11d911f8fb0f0ee0589fb7f15
4
- data.tar.gz: ff4685ce1f6215217bfadeb9cd3d02fc750b84b9aa74b1d2deb6186c8ed7da89
3
+ metadata.gz: 4e9c4ec38a103ceb321da1a48a78a09872e7d47875fbd0fa1e15814116f79e64
4
+ data.tar.gz: cb4abb1d12ac1c2a06427f7e6f63de34c4d8b99c56248287470f2c4aa3be655a
5
5
  SHA512:
6
- metadata.gz: 4004ed7d3b297299c3bfb343c15053548957afe60835804e087a71cf6b94558ef3dfbdb41918d54034b8fd5a464142fe137ef9a535f5f28a3ddcc9e3330c95c2
7
- data.tar.gz: ec21028482dc4c0da1a4534d0c322ab012a21b988df7ffda07764f7cb66063c0606b4656707149307ac94ea8c301c27e20fce4e7d71ac88093f75a1c36f7d3de
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
- ### Breaking changes
8
+ ## 0.2.0 - 2022-05-12
9
9
 
10
- ### Compatible changes
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.1.1)
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 (6.1.4.1)
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.14.4)
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
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class SteadyEtag
5
- VERSION = "0.1.1"
5
+ VERSION = "0.2.0"
6
6
  end
7
7
  end
@@ -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/master/lib/rack/etag.rb
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: nil, digest_cache_control: DEFAULT_CACHE_CONTROL, ignore_patterns: IGNORE_PATTERNS.dup)
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
- set_cache_control_with_digest(headers)
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
- @ignore_patterns.each do |ignore_pattern|
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
@@ -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
- # Uncomment to register a new dependency of your gem
35
- spec.add_dependency "rack"
36
- spec.add_dependency 'activesupport', '>= 3.2'
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
- # For more information and examples about making a new gem, checkout our
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.1.1
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-03-16 00:00:00.000000000 Z
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.1.4
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