Class: Philiprehberger::Etag::Middleware

Inherits:
Object
  • Object
show all
Defined in:
lib/philiprehberger/etag/middleware.rb

Overview

Rack middleware that automatically adds ETag headers to responses and returns 304 Not Modified when the client’s cached version matches. The ETag is computed from the raw response body before any Content-Encoding is applied, ensuring consistent hashing regardless of compression.

Instance Method Summary collapse

Constructor Details

#initialize(app) ⇒ Middleware

Returns a new instance of Middleware.

Parameters:

  • app (#call)

    the Rack application



11
12
13
# File 'lib/philiprehberger/etag/middleware.rb', line 11

def initialize(app)
  @app = app
end

Instance Method Details

#call(env) ⇒ Array

Processes a Rack request. Computes an ETag from the response body, adds the ETag header, and returns 304 if If-None-Match matches.

Parameters:

  • env (Hash)

    the Rack environment

Returns:

  • (Array)

    a Rack response triplet [status, headers, body]



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/philiprehberger/etag/middleware.rb', line 20

def call(env)
  status, headers, body = @app.call(env)

  return [status, headers, body] unless etag_eligible?(status, headers)

  response_body = extract_body(body)
  etag = Generator.strong(response_body)
  headers['ETag'] = etag

  if_none_match = env['HTTP_IF_NONE_MATCH']
  if if_none_match && Matcher.match?(etag, if_none_match)
    body.close if body.respond_to?(:close)
    [304, headers, []]
  else
    [status, headers, body]
  end
end