Class: SmartAssets::Rack

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

Instance Method Summary collapse

Constructor Details

#initialize(app, prefix, cache_control) ⇒ Rack

Returns a new instance of Rack.



6
7
8
9
10
# File 'lib/smart_assets/rack.rb', line 6

def initialize(app, prefix, cache_control)
  @app = app
  @prefix = prefix
  @cache_control = cache_control
end

Instance Method Details

#base_path(env) ⇒ Object



48
49
50
# File 'lib/smart_assets/rack.rb', line 48

def base_path(env)
  env['PATH_INFO'].sub(%r{^#{@prefix}/}, '')
end

#call(env) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/smart_assets/rack.rb', line 12

def call(env)
  unless is_asset?(env) && (digest_asset=digest_name(env))
    return @app.call(env)
  end

  digest_path = File.join(manifest.dir, digest_asset)
  if File.exist?(digest_path)
    env['PATH_INFO'] = "#{@prefix}/#{digest_asset}"
  end
  status, headers, body = @app.call(env)
  if [200, 206].include?(status)
    # rack 2 expects Mixed-Case headers, while rack 3 expects lower-case. rails doesn't ensure
    # either one. normal controller actions use ActionDispatch::Response::Headers, which maps
    # to rack 2's HeaderHash or rack 3's Headers, both of which are case-insensitive extensions
    # to Hash. however, some responses (ActionDispatch::Static among them), just use Hash.
    # more, Static relies on the user-configurable public_file_server.headers setting, which
    # may have unpredictable casing regardless of the rails or rack version.
    headers = ActionDispatch::Response::Headers[headers] if defined? ActionDispatch::Response::Headers

    # keep Mixed-Case as long as supporting rails <= 7.0 or rack 2
    headers['Cache-Control'] = @cache_control
    headers['ETag'] ||= %("#{digest(digest_asset)}")
  end
  [status, headers, body]
end

#digest(name) ⇒ Object



56
57
58
# File 'lib/smart_assets/rack.rb', line 56

def digest(name)
  manifest.files[name]['digest']
end

#digest_name(env) ⇒ Object



52
53
54
# File 'lib/smart_assets/rack.rb', line 52

def digest_name(env)
  manifest.assets[base_path(env)]
end

#is_asset?(env) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
# File 'lib/smart_assets/rack.rb', line 39

def is_asset?(env)
  case env['REQUEST_METHOD']
  when 'GET', 'HEAD'
    env['PATH_INFO'].start_with?(@prefix)
  else
    false
  end
end

#manifestObject



60
61
62
# File 'lib/smart_assets/rack.rb', line 60

def manifest
  ActionView::Base.assets_manifest
end