From 4795c175c83d588571aba53c63246c914ddce280 Mon Sep 17 00:00:00 2001 From: Theodor Tonum Date: Thu, 16 Sep 2021 21:38:49 +0200 Subject: [PATCH] Improve serving of prehashed assets See https://github.com/rails/jsbundling-rails/pull/21 --- CHANGELOG.md | 1 + lib/sprockets/server.rb | 12 +++++++++++- ...hed-988881adc9fc3655077dc2d4d757d480b5ea0e11.js | 1 + test/test_server.rb | 14 ++++++++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 test/fixtures/server/app/javascripts/prehashed-988881adc9fc3655077dc2d4d757d480b5ea0e11.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ec6ca810..72574d902 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprocket ## Master +- Allow assets already fingerprinted to be served through `Sprockets::Server` - Do not fingerprint files that already contain a valid digest in their name - Remove remaining support for Ruby < 2.4.[#672](https://github.com/rails/sprockets/pull/672) diff --git a/lib/sprockets/server.rb b/lib/sprockets/server.rb index 7ed0d416b..ce425a322 100644 --- a/lib/sprockets/server.rb +++ b/lib/sprockets/server.rb @@ -35,7 +35,8 @@ def call(env) msg = "Served asset #{env['PATH_INFO']} -" # Extract the path from everything after the leading slash - path = Rack::Utils.unescape(env['PATH_INFO'].to_s.sub(/^\//, '')) + full_path = Rack::Utils.unescape(env['PATH_INFO'].to_s.sub(/^\//, '')) + path = full_path unless path.valid_encoding? return bad_request_response(env) @@ -64,6 +65,15 @@ def call(env) # Look up the asset. asset = find_asset(path) + # Fallback to looking up the asset with the full path. + # This will make assets that are hashed with webpack or + # other js bundlers work consistently between production + # and development pipelines. + if asset.nil? && (asset = find_asset(full_path)) + if_match = asset.etag if fingerprint + fingerprint = asset.etag + end + if asset.nil? status = :not_found elsif fingerprint && asset.etag != fingerprint diff --git a/test/fixtures/server/app/javascripts/prehashed-988881adc9fc3655077dc2d4d757d480b5ea0e11.js b/test/fixtures/server/app/javascripts/prehashed-988881adc9fc3655077dc2d4d757d480b5ea0e11.js new file mode 100644 index 000000000..b336b22ec --- /dev/null +++ b/test/fixtures/server/app/javascripts/prehashed-988881adc9fc3655077dc2d4d757d480b5ea0e11.js @@ -0,0 +1 @@ +console.log("I was already hashed!"); \ No newline at end of file diff --git a/test/test_server.rb b/test/test_server.rb index b65ad809d..40b63c3c9 100644 --- a/test/test_server.rb +++ b/test/test_server.rb @@ -129,6 +129,16 @@ def app assert_equal 304, last_response.status end + test "200 response for prehashed asset with etag digest by sprockets" do + get "/assets/prehashed-988881adc9fc3655077dc2d4d757d480b5ea0e11.js" + assert_equal 200, last_response.status + + etag = last_response.headers['ETag'] + digest = etag[/"(.+)"/, 1] + + assert_equal 'edabfd0f1ac5fcdae82cc7d92d1c52abb671797a3948fa9040aec1db8e61c327', digest + end + test "ok response with fingerprint and if-nonematch etags don't match" do get "/assets/application.js" assert_equal 200, last_response.status @@ -298,7 +308,7 @@ def app sandbox filename do get "/assets/tree.js" - assert_equal "var foo;\n\n(function() {\n application.boot();\n})();\nvar bar;\nvar japanese = \"日本語\";\n", last_response.body + assert_equal %[var foo;\n\n(function() {\n application.boot();\n})();\nvar bar;\nconsole.log("I was already hashed!");\nvar japanese = \"日本語\";\n], last_response.body File.open(filename, "w") do |f| f.write "var baz;\n" @@ -309,7 +319,7 @@ def app File.utime(mtime, mtime, path) get "/assets/tree.js" - assert_equal "var foo;\n\n(function() {\n application.boot();\n})();\nvar bar;\nvar baz;\nvar japanese = \"日本語\";\n", last_response.body + assert_equal %[var foo;\n\n(function() {\n application.boot();\n})();\nvar bar;\nvar baz;\nconsole.log("I was already hashed!");\nvar japanese = \"日本語\";\n], last_response.body end end