forked from rails/sprockets-rails
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't serve up assets without digests in development
If config.assets.digest = true and config.assets.raise_runtime_errors = true, only serve an asset if the request has a digest. Here are the different cases: - If the asset request has a digest and it matches the asset's digest, we serve the asset. - If the asset request has a digest and it does not match the asset's digest, we redirect to the asset. - If the asset request does not have a digest, we raise a NoDigestError. Fixes rails#117
- Loading branch information
Dan Kang
committed
May 16, 2014
1 parent
94a0332
commit 6e5b82f
Showing
7 changed files
with
170 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
require 'sprockets' | ||
require 'sprockets/rails/helper' | ||
|
||
module Sprockets | ||
module Rails | ||
class Environment < Sprockets::Environment | ||
class NoDigestError < StandardError | ||
def initialize(asset) | ||
msg = "Assets should not be requested directly without their digests: " << | ||
"Use the helpers in ActionView::Helpers to request #{asset}" | ||
super(msg) | ||
end | ||
end | ||
|
||
def call(env) | ||
if Sprockets::Rails::Helper.raise_runtime_errors && context_class.digest_assets | ||
path = unescape(env['PATH_INFO'].to_s.sub(/^\//, '')) | ||
|
||
if fingerprint = path_fingerprint(path) | ||
path = path.sub("-#{fingerprint}", '') | ||
else | ||
raise NoDigestError.new(path) | ||
end | ||
|
||
asset = find_asset(path) | ||
if asset && asset.digest != fingerprint | ||
asset_path = File.join(context_class.assets_prefix || "/", asset.digest_path) | ||
asset_path += '?' + env['QUERY_STRING'] if env['QUERY_STRING'] | ||
[302, {"Location" => asset_path}, []] | ||
else | ||
super(env) | ||
end | ||
else | ||
super(env) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
require 'minitest/autorun' | ||
|
||
require 'rack/test' | ||
require 'sprockets/rails/environment' | ||
require 'sprockets/rails/helper' | ||
|
||
Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test) | ||
|
||
class EnvironmentTest < Minitest::Test | ||
include Rack::Test::Methods | ||
|
||
FIXTURES_PATH = File.expand_path("../fixtures", __FILE__) | ||
|
||
def setup | ||
@assets = Sprockets::Rails::Environment.new | ||
@assets.append_path FIXTURES_PATH | ||
@assets.context_class.class_eval do | ||
include ::Sprockets::Rails::Helper | ||
end | ||
@assets.context_class.assets_prefix = "/assets" | ||
@assets.context_class.digest_assets = true | ||
|
||
@foo_js_digest = @assets['foo.js'].digest | ||
|
||
Sprockets::Rails::Helper.raise_runtime_errors = true | ||
end | ||
|
||
def default_app | ||
env = @assets | ||
|
||
Rack::Builder.new do | ||
map "/assets" do | ||
run env | ||
end | ||
end | ||
end | ||
|
||
def app | ||
@app ||= default_app | ||
end | ||
end | ||
|
||
class DigestTest < EnvironmentTest | ||
def setup | ||
super | ||
@assets.context_class.digest_assets = true | ||
end | ||
|
||
def test_assets_with_digest | ||
get "/assets/foo-#{@foo_js_digest}.js" | ||
assert_equal 200, last_response.status | ||
end | ||
|
||
def test_assets_with_no_digest | ||
assert_raises(Sprockets::Rails::Environment::NoDigestError) do | ||
get "/assets/foo.js" | ||
end | ||
end | ||
|
||
def test_assets_with_wrong_digest | ||
wrong_digest = "0" * 32 | ||
get "/assets/foo-#{wrong_digest}.js" | ||
assert_equal 302, last_response.status | ||
|
||
follow_redirect! | ||
assert_equal "/assets/foo-#{@foo_js_digest}.js", last_request.path | ||
assert_equal 200, last_response.status | ||
end | ||
|
||
def test_assets_with_wrong_digest_with_query_parameters | ||
wrong_digest = "0" * 32 | ||
get "/assets/foo-#{wrong_digest}.js?body=1" | ||
assert_equal 302, last_response.status | ||
|
||
follow_redirect! | ||
assert_equal "/assets/foo-#{@foo_js_digest}.js", last_request.path | ||
assert_equal "body=1", last_request.query_string | ||
assert_equal 200, last_response.status | ||
end | ||
end | ||
|
||
class NoDigestTest < EnvironmentTest | ||
def setup | ||
super | ||
@assets.context_class.digest_assets = false | ||
end | ||
|
||
def test_assets_with_digest | ||
get "/assets/foo-#{@foo_js_digest}.js" | ||
assert_equal 200, last_response.status | ||
end | ||
|
||
def test_assets_with_no_digest | ||
get "/assets/foo.js" | ||
assert_equal 200, last_response.status | ||
end | ||
end | ||
|
||
class NoRuntimeErrorTest < EnvironmentTest | ||
def setup | ||
super | ||
Sprockets::Rails::Helper.raise_runtime_errors = false | ||
end | ||
|
||
def test_assets_with_digest | ||
get "/assets/foo-#{@foo_js_digest}.js" | ||
assert_equal 200, last_response.status | ||
end | ||
|
||
def test_assets_with_no_digest | ||
get "/assets/foo.js" | ||
assert_equal 200, last_response.status | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters