rack-steady_etag 0.2.2 → 0.3.1

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: 8caa8d352b72433a6659f50b6c9216cf03b265b19016134fa259719d24c46b4e
4
- data.tar.gz: 74f01fc86755933b87361615bd6cb62568e44bfa404565261c0c180dcd5b399c
3
+ metadata.gz: 7d2e8f19f09cac1377380b52aaac1c09e39bb565af7976863cab2c0f6ec303fe
4
+ data.tar.gz: 84aeee379982cce1a96fc25600b60a4b4bd01ab4a3699792ce821a57bf70ca31
5
5
  SHA512:
6
- metadata.gz: 3cbd8de00297924f758d0c32151d17991fe8e235d943969544cdad632f50cca43eba12ef133c1a7690d91def4d8f997ab48535417457f62c8cb9d36a07a7e9d9
7
- data.tar.gz: c2df595d03a3e3f46b2be21f4da14f76460556a0b8e6628959d7156d1a5285c79eb9c1a45415ad343904ed388c4645320ddc94a2422184727798d4b432eecd2e
6
+ metadata.gz: 0d16e5141ab9794dcf6cf751ac150aaec48e058fd9acce6ae4ea11011ac3d79a9a65ff0d07abfbe8d9df797f6677cf2688613094975a67a78fe726b86c9a66b1
7
+ data.tar.gz: 508c64a1acc11988a64d498d05c26d707e6eee0626d0d656bc05823e8c63c30775056325874f1bff4c87b1335a44c054e05f40db8e7aa3abd7e258663abc3d30
data/CHANGELOG.md CHANGED
@@ -5,6 +5,19 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 0.3.1 - 2022-07-19
9
+
10
+ - Fix a bug where we would not strip HTML responses with an embedded charset (e.g. `text/html; charset=utf-8`).
11
+
12
+ ## 0.3.0 - 2022-05-13
13
+
14
+ - Support for old Rack 1.4.7 (last version supported by Rails 3.2)
15
+ - No longer depends on activesupport.
16
+
17
+ ## 0.2.3 - 2022-05-12
18
+
19
+ - Don't depend on `byebug` being in the user bundle.
20
+
8
21
  ## 0.2.2 - 2022-05-12
9
22
 
10
23
  - Don't raise an error when processing binary content.
data/Gemfile CHANGED
@@ -5,8 +5,7 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in rack-steady-etag.gemspec
6
6
  gemspec
7
7
 
8
+ gem "rack", "~> 2.0"
8
9
  gem "rake", "~> 13.0"
9
-
10
10
  gem "rspec", "~> 3.0"
11
-
12
11
  gem 'byebug'
data/Gemfile.lock CHANGED
@@ -1,24 +1,14 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rack-steady_etag (0.2.2)
5
- activesupport (>= 3.2)
6
- rack (~> 2.0)
4
+ rack-steady_etag (0.3.1)
5
+ rack (>= 1.4.7, < 3)
7
6
 
8
7
  GEM
9
8
  remote: https://rubygems.org/
10
9
  specs:
11
- activesupport (7.0.1)
12
- concurrent-ruby (~> 1.0, >= 1.0.2)
13
- i18n (>= 1.6, < 2)
14
- minitest (>= 5.1)
15
- tzinfo (~> 2.0)
16
10
  byebug (11.1.3)
17
- concurrent-ruby (1.1.10)
18
11
  diff-lcs (1.4.4)
19
- i18n (1.10.0)
20
- concurrent-ruby (~> 1.0)
21
- minitest (5.15.0)
22
12
  rack (2.2.3)
23
13
  rake (13.0.6)
24
14
  rspec (3.10.0)
@@ -34,14 +24,13 @@ GEM
34
24
  diff-lcs (>= 1.2.0, < 2.0)
35
25
  rspec-support (~> 3.10.0)
36
26
  rspec-support (3.10.3)
37
- tzinfo (2.0.4)
38
- concurrent-ruby (~> 1.0)
39
27
 
40
28
  PLATFORMS
41
29
  x86_64-linux
42
30
 
43
31
  DEPENDENCIES
44
32
  byebug
33
+ rack (~> 2.0)
45
34
  rack-steady_etag!
46
35
  rake (~> 13.0)
47
36
  rspec (~> 3.0)
data/Gemfile.rack1 ADDED
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ # Specify your gem's dependencies in rack-steady-etag.gemspec
6
+ gemspec
7
+
8
+ gem "rack", "= 1.4.7"
9
+ gem "rake", "~> 13.0"
10
+ gem "rspec", "~> 3.0"
11
+ gem 'byebug'
@@ -0,0 +1,39 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-steady_etag (0.3.0)
5
+ rack (>= 1.4.7, < 3)
6
+
7
+ GEM
8
+ remote: https://rubygems.org/
9
+ specs:
10
+ byebug (11.1.3)
11
+ diff-lcs (1.4.4)
12
+ rack (1.4.7)
13
+ rake (13.0.6)
14
+ rspec (3.10.0)
15
+ rspec-core (~> 3.10.0)
16
+ rspec-expectations (~> 3.10.0)
17
+ rspec-mocks (~> 3.10.0)
18
+ rspec-core (3.10.1)
19
+ rspec-support (~> 3.10.0)
20
+ rspec-expectations (3.10.1)
21
+ diff-lcs (>= 1.2.0, < 2.0)
22
+ rspec-support (~> 3.10.0)
23
+ rspec-mocks (3.10.2)
24
+ diff-lcs (>= 1.2.0, < 2.0)
25
+ rspec-support (~> 3.10.0)
26
+ rspec-support (3.10.3)
27
+
28
+ PLATFORMS
29
+ x86_64-linux
30
+
31
+ DEPENDENCIES
32
+ byebug
33
+ rack (= 1.4.7)
34
+ rack-steady_etag!
35
+ rake (~> 13.0)
36
+ rspec (~> 3.0)
37
+
38
+ BUNDLED WITH
39
+ 2.2.32
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rack::SteadyETag
2
2
 
3
- `Rack::SteadyTag` is a Rack middleware that generates the same default [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) for responses that only differ in CSRF tokens or CSP nonces.
3
+ `Rack::SteadyETag` is a Rack middleware that generates the same default [`ETag`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag) for responses that only differ in CSRF tokens or CSP nonces.
4
4
 
5
5
  By default Rails uses [`Rack::ETag`](https://rdoc.info/github/rack/rack/Rack/ETag) to generate `ETag` headers by hashing the response body. In theory this would [enable caching](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match) for multiple requests to the same resource. However, since most Rails application layouts insert randomly rotating CSRF tokens and CSP nonces into the HTML, two requests for the same content and user will never produce the same response bytes. This means `Rack::ETag` will never send the same ETag twice, causing responses to [never hit a cache](https://github.com/rails/rails/issues/29889).
6
6
 
@@ -65,10 +65,10 @@ And then execute:
65
65
  bundle install
66
66
  ```
67
67
 
68
- In your `config/application.rb`:
68
+ Make an initializer `config/initializer/etags.rb`:
69
69
 
70
70
  ```ruby
71
- config.middleware.swap Rack::ETag, Rack::SteadyETag, 'no-cache'
71
+ Rails.application.config.middleware.swap Rack::ETag, Rack::SteadyETag, 'no-cache'
72
72
  ```
73
73
 
74
74
  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.
@@ -78,6 +78,7 @@ The `'no-cache'` argument is the default `Cache-Control` for responses that cann
78
78
 
79
79
  - After checking out the repo, run `bin/setup` to install dependencies.
80
80
  - Run `bundle exec rspec` to run the tests.
81
+ - Run `BUNDLE_GEMFILE=Gemfile.rack1 bundle exec rspec` to run tests for old Rack 1.
81
82
  - You can also run `bin/console` for an interactive prompt that will allow you to experiment.
82
83
  - To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
83
84
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class SteadyEtag
5
- VERSION = "0.2.2"
5
+ VERSION = "0.3.1"
6
6
  end
7
7
  end
@@ -1,7 +1,5 @@
1
- require 'byebug'
1
+ require "rack"
2
2
  require 'digest/sha2'
3
- require "active_support/all"
4
- require_relative "steady_etag"
5
3
  require_relative "steady_etag/version"
6
4
 
7
5
  module Rack
@@ -43,8 +41,8 @@ module Rack
43
41
 
44
42
  def call(env)
45
43
  status, headers, body = @app.call(env)
46
- headers = Utils::HeaderHash[headers]
47
- session = env[RACK_SESSION]
44
+ headers = case_insensitive_headers(headers)
45
+ session = env['rack.session']
48
46
 
49
47
  if etag_status?(status) && etag_body?(body) && !skip_caching?(headers)
50
48
  original_body = body
@@ -52,7 +50,7 @@ module Rack
52
50
  body = Rack::BodyProxy.new(new_body) do
53
51
  original_body.close if original_body.respond_to?(:close)
54
52
  end
55
- headers[ETAG] = %(W/"#{digest}") if digest
53
+ headers['ETag'] = %(W/"#{digest}") if digest
56
54
  end
57
55
 
58
56
  # It would make more sense to only set a Cache-Control for responses that we process.
@@ -72,12 +70,25 @@ module Rack
72
70
 
73
71
  private
74
72
 
73
+ # HTTP headers are case-insensitive.
74
+ # Wrap hedders into a hash with case-insensitive keys
75
+ def case_insensitive_headers(headers)
76
+ case Rack.release[0]
77
+ when '1'
78
+ Utils::HeaderHash.new(headers)
79
+ when '2'
80
+ Utils::HeaderHash[headers]
81
+ when '3'
82
+ raise "HeaderHash will be removed in Rack 3. Probably switch to new Headers."
83
+ end
84
+ end
85
+
75
86
  def set_cache_control_with_digest(headers)
76
- headers[CACHE_CONTROL] ||= @digest_cache_control if @digest_cache_control
87
+ headers['Cache-Control'] ||= @digest_cache_control if @digest_cache_control
77
88
  end
78
89
 
79
90
  def set_cache_control_without_digest(headers)
80
- headers[CACHE_CONTROL] ||= @no_digest_cache_control if @no_digest_cache_control
91
+ headers['Cache-Control'] ||= @no_digest_cache_control if @no_digest_cache_control
81
92
  end
82
93
 
83
94
  def etag_status?(status)
@@ -92,14 +103,14 @@ module Rack
92
103
  end
93
104
 
94
105
  def skip_caching?(headers)
95
- headers.key?(ETAG) || headers.key?('Last-Modified')
106
+ headers.key?('ETag') || headers.key?('Last-Modified')
96
107
  end
97
108
 
98
109
  def digest_body(body, headers, session)
99
110
  parts = []
100
111
  digest = nil
101
112
 
102
- strippable_response = STRIP_CONTENT_TYPES.include?(headers['Content-Type'])
113
+ strippable_response = strippable_response?(headers)
103
114
 
104
115
  body.each do |part|
105
116
  parts << part
@@ -142,5 +153,16 @@ module Rack
142
153
  html
143
154
  end
144
155
 
156
+ private
157
+
158
+ def strippable_response?(headers)
159
+ content_type = headers['Content-Type']
160
+ return false unless content_type
161
+
162
+ # Convert "text/tml; charset=utf-8" to just "text/html"
163
+ content_type = content_type.split(/\s*;\s*/)[0]
164
+ STRIP_CONTENT_TYPES.include?(content_type)
165
+ end
166
+
145
167
  end
146
168
  end
@@ -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
+ # Rack 1.4.7 is the last version compatible with Rails 3.2.
35
+ #
34
36
  # I expect Rack 3 to have a new ETag middleware to no longer buffer
35
37
  # streaming responses: https://github.com/rack/rack/issues/1619
36
38
  # Once Rack 3 is out we should release a new version of this gem.
37
- spec.add_dependency "rack", '~>2.0'
38
-
39
- spec.add_dependency 'activesupport', '>= 3.2'
39
+ spec.add_dependency "rack", '>=1.4.7', '<3'
40
40
  end
metadata CHANGED
@@ -1,43 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-steady_etag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.1
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-05-12 00:00:00.000000000 Z
11
+ date: 2022-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '2.0'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '2.0'
27
- - !ruby/object:Gem::Dependency
28
- name: activesupport
29
15
  requirement: !ruby/object:Gem::Requirement
30
16
  requirements:
31
17
  - - ">="
32
18
  - !ruby/object:Gem::Version
33
- version: '3.2'
19
+ version: 1.4.7
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '3'
34
23
  type: :runtime
35
24
  prerelease: false
36
25
  version_requirements: !ruby/object:Gem::Requirement
37
26
  requirements:
38
27
  - - ">="
39
28
  - !ruby/object:Gem::Version
40
- version: '3.2'
29
+ version: 1.4.7
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '3'
41
33
  description: Rack Middleware that produces the same ETag for responses that only differ
42
34
  in CSRF tokens or CSP nonce
43
35
  email:
@@ -51,6 +43,8 @@ files:
51
43
  - CHANGELOG.md
52
44
  - Gemfile
53
45
  - Gemfile.lock
46
+ - Gemfile.rack1
47
+ - Gemfile.rack1.lock
54
48
  - LICENSE.txt
55
49
  - README.md
56
50
  - Rakefile