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 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