Class: Rack::SteadyETag
- Inherits:
-
Object
- Object
- Rack::SteadyETag
- Defined in:
- lib/rack/steady_etag.rb
Overview
Based on Rack::Etag from rack 2.2.3 github.com/rack/rack/blob/v2.2.3/lib/rack/etag.rb
Automatically sets the ETag header on all String bodies.
The ETag header is skipped if ETag or Last-Modified headers are sent or if a sendfile body (body.responds_to :to_path) is given (since such cases should be handled by apache/nginx).
Constant Summary collapse
- DEFAULT_CACHE_CONTROL =
Yes, Rack::ETag sets a default Cache-Control for responses that it can digest.
"max-age=0, private, must-revalidate"- STRIP_PATTERNS =
[ /<meta\b[^>]*\bname=(["'])csrf-token\1[^>]+>/i, /<meta\b[^>]*\bname=(["'])csp-nonce\1[^>]+>/i, /<input\b[^>]*\bname=(["'])authenticity_token\1[^>]+>/i, lambda { |string| string.gsub(/(<script\b[^>]*)\bnonce=(["'])[^"']+\2+/i, '\1') } ]
- STRIP_CONTENT_TYPES =
%w[ text/html application/xhtml+xml ]
Instance Method Summary collapse
- #call(env) ⇒ Object
-
#initialize(app, no_digest_cache_control = nil, digest_cache_control = DEFAULT_CACHE_CONTROL) ⇒ SteadyETag
constructor
A new instance of SteadyETag.
Constructor Details
#initialize(app, no_digest_cache_control = nil, digest_cache_control = DEFAULT_CACHE_CONTROL) ⇒ SteadyETag
Returns a new instance of SteadyETag.
32 33 34 35 36 37 38 39 40 |
# File 'lib/rack/steady_etag.rb', line 32 def initialize(app, no_digest_cache_control = nil, digest_cache_control = DEFAULT_CACHE_CONTROL) @app = app @digest_cache_control = digest_cache_control # Rails sets a default `Cache-Control: no-cache` for responses that we cannot digest. # See https://github.com/rails/rails/blob/d96609505511a76c618dc3adfa3ca4679317d008/railties/lib/rails/application/default_middleware_stack.rb#L81 @no_digest_cache_control = no_digest_cache_control end |
Instance Method Details
#call(env) ⇒ Object
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/rack/steady_etag.rb', line 42 def call(env) status, headers, body = @app.call(env) headers = case_insensitive_headers(headers) session = env['rack.session'] if etag_status?(status) && etag_body?(body) && !skip_caching?(headers) original_body = body digest, new_body = digest_body(body, headers, session) body = Rack::BodyProxy.new(new_body) do original_body.close if original_body.respond_to?(:close) end headers['ETag'] = %(W/"#{digest}") if digest end # It would make more sense to only set a Cache-Control for responses that we process. # However, the original Rack::ETag sets Cache-Control: @no_digest_cache_control # for all responses, even responses that we don't otherwise modify. # Hence if we move this code into the `if` above we would remove Rails' default # Cache-Control headers for non-digestable responses, which would be a considerable # change in behavior. if digest set_cache_control_with_digest(headers) else set_cache_control_without_digest(headers) end [status, headers, body] end |