rack-steady_etag 0.2.1 → 0.3.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: d3047cb500ace97518e12a5667bad5602d27b493f24d6a8a6c8236372fe7ca36
4
- data.tar.gz: d9c3afe27e063227577e1921f6f4ce4e170f7f5627be0126096f1ed846ad7d1e
3
+ metadata.gz: 5aa199f91364859bf016f7eebb34a1e4ec4e43a9e72b2fa7609e7698808028f9
4
+ data.tar.gz: c780345dd1b614794619b52d5d875f43f89a2068f13d103151c32878603c0aba
5
5
  SHA512:
6
- metadata.gz: b86c5ec23d0d27170406530421acea4a54be83caf4c0513de01004136e92d2842aa771927f9ab8074bd918b83f3f10efc651b3e815dc8c5c2036769767c28077
7
- data.tar.gz: b28cddf4577f20d1c0c75cdcf7c58d9ce5765f2148ab6fde4b9c0533725d09aa4c596b1624cab70c4e36a5b909e67153fd14ff95a272e9ef8fa0ee5ac81800c8
6
+ metadata.gz: ea89402781f5ab4444bbd647eb5570174be66930df33f03146ca4e0418675c201d1de712c91f4076f2253c954cd1a959f295e41c2bb783595d6d2f1b27168003
7
+ data.tar.gz: 5d5aaf2aa93ae067516b3a136dc7b691c7dcc409f96581b8c09e38c662d8ba455b36ae27d768c4540628a807c8a3eccf3f2b5cd25ed91c6981e40817c8e300a2
data/CHANGELOG.md CHANGED
@@ -5,13 +5,26 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 0.3.0 - 2022-05-13
9
+
10
+ - Support for old Rack 1.4.7 (last version supported by Rails 3.2)
11
+ - No longer depends on activesupport.
12
+
13
+ ## 0.2.3 - 2022-05-12
14
+
15
+ - Don't depend on `byebug` being in the user bundle.
16
+
17
+ ## 0.2.2 - 2022-05-12
18
+
19
+ - Don't raise an error when processing binary content.
20
+
8
21
  ## 0.2.1 - 2022-05-12
9
22
 
10
23
  - Only strip patterns for HTML and XHTML responses.
11
24
 
12
25
  ## 0.2.0 - 2022-05-12
13
26
 
14
- - Be more compatible with Rack 2.2.2:
27
+ - Be more compatible with Rack 2.2.3:
15
28
  - Always set a `Cache-Control` header, even for responses that we don't try to digest.
16
29
  - Strip patterns for responses with `Cache-Control: public`
17
30
  - Requires Rack 2.x (we want to break with Rack 3)
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.1)
5
- activesupport (>= 3.2)
6
- rack (~> 2.0)
4
+ rack-steady_etag (0.3.0)
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.9)
18
11
  diff-lcs (1.4.4)
19
- i18n (1.8.11)
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
@@ -35,10 +35,12 @@ Transformations are only applied for the `ETag` hash. The response body will not
35
35
 
36
36
  This middleware will process responses that match all of the following:
37
37
 
38
- - Responses with a HTTP status of 200 or 201
39
- - Responses with a `Content-Type` of `text/html` or `application/xhtml+xml`
38
+ - Responses with a HTTP status of 200 or 201.
39
+ - Responses with a `Content-Type` of `text/html` or `application/xhtml+xml`.
40
40
  - Responses with a body.
41
41
 
42
+ Responses should also have an UTF-8 encoding (not checked by the middleware).
43
+
42
44
  This middleware can also add a default `Cache-Control` header for responses it *didn't* process. This is passed as an argument during middleware initialization (see *Installation* below).
43
45
 
44
46
  ## Covered edge cases
@@ -63,10 +65,10 @@ And then execute:
63
65
  bundle install
64
66
  ```
65
67
 
66
- In your `config/application.rb`:
68
+ Make an initializer `config/initializer/etags.rb`:
67
69
 
68
70
  ```ruby
69
- config.middleware.swap Rack::ETag, Rack::SteadyETag, 'no-cache'
71
+ Rails.application.config.middleware.swap Rack::ETag, Rack::SteadyETag, 'no-cache'
70
72
  ```
71
73
 
72
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.
@@ -76,6 +78,7 @@ The `'no-cache'` argument is the default `Cache-Control` for responses that cann
76
78
 
77
79
  - After checking out the repo, run `bin/setup` to install dependencies.
78
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.
79
82
  - You can also run `bin/console` for an interactive prompt that will allow you to experiment.
80
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).
81
84
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Rack
4
4
  class SteadyEtag
5
- VERSION = "0.2.1"
5
+ VERSION = "0.3.0"
6
6
  end
7
7
  end
@@ -1,13 +1,11 @@
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
8
6
 
9
- # Based on Rack::Etag from rack 2.2.2
10
- # https://github.com/rack/rack/blob/v2.2.2/lib/rack/etag.rb
7
+ # Based on Rack::Etag from rack 2.2.3
8
+ # https://github.com/rack/rack/blob/v2.2.3/lib/rack/etag.rb
11
9
  #
12
10
  # Automatically sets the ETag header on all String bodies.
13
11
  #
@@ -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)
@@ -87,12 +98,12 @@ module Rack
87
98
  def etag_body?(body)
88
99
  # Rack main branch checks for `:to_ary` here to exclude streaming responses,
89
100
  # but that had other issues for me in testing. Maybe recheck when there is a
90
- # new Rack release after 2.2.2.
101
+ # new Rack release after 2.2.3.
91
102
  !body.respond_to?(:to_path)
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)
@@ -104,7 +115,10 @@ module Rack
104
115
  body.each do |part|
105
116
  parts << part
106
117
 
107
- if part.present?
118
+ # Note that `part` can be a string with binary data here.
119
+ # It's important to check emptiness with #empty? instead of #blank?, since #blank?
120
+ # internally calls String#match? and that explodes if the string is not valid UTF-8.
121
+ unless part.empty?
108
122
  digest ||= initialize_digest(session)
109
123
  part = strip_patterns(part) if strippable_response
110
124
  digest << part
@@ -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.1
4
+ version: 0.3.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-05-12 00:00:00.000000000 Z
11
+ date: 2022-05-13 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