Class: Klenod::Rack::AssetApp

Inherits:
Object
  • Object
show all
Defined in:
lib/klenod/rack/asset_app.rb

Constant Summary collapse

CACHE_CONTROL =
"public, max-age=31536000, immutable"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, app: nil, assets_dir: nil, path_prefix: "/assets/") ⇒ AssetApp

Returns a new instance of AssetApp.



22
23
24
25
26
27
# File 'lib/klenod/rack/asset_app.rb', line 22

def initialize(source, app: nil, assets_dir: nil, path_prefix: "/assets/")
  @source = source
  @app = app
  @assets_dir = assets_dir
  @path_prefix = path_prefix
end

Instance Attribute Details

#appObject (readonly)

Returns the value of attribute app.



29
30
31
# File 'lib/klenod/rack/asset_app.rb', line 29

def app
  @app
end

#assets_dirObject (readonly)

Returns the value of attribute assets_dir.



29
30
31
# File 'lib/klenod/rack/asset_app.rb', line 29

def assets_dir
  @assets_dir
end

#path_prefixObject (readonly)

Returns the value of attribute path_prefix.



29
30
31
# File 'lib/klenod/rack/asset_app.rb', line 29

def path_prefix
  @path_prefix
end

#sourceObject (readonly)

Returns the value of attribute source.



29
30
31
# File 'lib/klenod/rack/asset_app.rb', line 29

def source
  @source
end

Instance Method Details

#call(env) ⇒ Object



31
32
33
34
35
36
37
# File 'lib/klenod/rack/asset_app.rb', line 31

def call(env)
  response = response_for(env.fetch("PATH_INFO", ""), env)
  return response.rack_response if response
  return app.call(env) if app

  not_found.rack_response
end

#response_for(path, env = {}) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/klenod/rack/asset_app.rb', line 39

def response_for(path, env = {})
  return nil unless asset_path?(path)

  asset = source.asset(path)
  brotli_available = brotli_asset_available?(asset)
  compressed = brotli_available && accepts_brotli?(env.fetch("HTTP_ACCEPT_ENCODING", ""))
  body = compressed ? brotli_asset_bytes(asset) : asset_bytes(asset)
  headers = {
    "content-type" => asset.content_type,
    "content-length" => body.bytesize.to_s,
    "cache-control" => CACHE_CONTROL
  }
  link = preload_link_header(asset)
  headers["link"] = link if link
  headers["vary"] = "Accept-Encoding" if brotli_available
  if compressed
    headers["content-encoding"] = "br"
  end

  Response.new(
    200,
    headers,
    body
  )
rescue KeyError, Errno::ENOENT
  not_found
end