From 2279c4208e89a7824ad82b6d5936ad35ce4e7843 Mon Sep 17 00:00:00 2001 From: Juan Pablo Balarini Date: Wed, 9 Nov 2022 16:56:57 -0300 Subject: [PATCH 1/4] Update assets.rb typo in comment Saw a bad typo in a comment in the asset.rb file and this commit fix this. --- lib/sprockets/asset.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sprockets/asset.rb b/lib/sprockets/asset.rb index ef7e17a4f..439ebca54 100644 --- a/lib/sprockets/asset.rb +++ b/lib/sprockets/asset.rb @@ -137,7 +137,7 @@ def hexdigest DigestUtils.pack_hexdigest(digest) end - # Pubic: ETag String of Asset. + # Public: ETag String of Asset. def etag version = environment_version From 33b0ade807c7b8d303cb1e05ea62426819256b14 Mon Sep 17 00:00:00 2001 From: Juan Pablo Balarini Date: Wed, 9 Nov 2022 17:04:49 -0300 Subject: [PATCH 2/4] Update Changelog file Update changelog with proposed changes for #768 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fe4f33cc..f1c8d7349 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 - Add support for Rack 3.0. Headers set by sprockets will now be lower case. [#758](https://github.com/rails/sprockets/pull/758) - Make `Sprockets::Utils.module_include` thread safe on JRuby. [#759](https://github.com/rails/sprockets/pull/759) +- Fix typo in `asset.rb` file. [#768](https://github.com/rails/sprockets/pull/768) ## 4.1.0 From 4be779f5f73bcf808fe26d4e8968b3f34f96d3a2 Mon Sep 17 00:00:00 2001 From: Hartley McGuire Date: Sat, 29 Jul 2023 18:28:17 -0400 Subject: [PATCH 3/4] Fix Minitest constant name in tests Minitest 5.19.0 removed the "ancient MiniTest compatibility layer" that aliased `Minitest` as `MiniTest`. CI runs without a lock file so tests are failing due to this new release. This commit renames all of the tests to the correct `Minitest` constant --- test/sprockets_test.rb | 2 +- test/test_babel_processor.rb | 2 +- test/test_cache_store.rb | 10 +++++----- test/test_closure_compressor.rb | 2 +- test/test_coffee_script_processor.rb | 2 +- test/test_digest_utils.rb | 2 +- test/test_eco_processor.rb | 2 +- test/test_ejs_processor.rb | 2 +- test/test_encoding_utils.rb | 2 +- test/test_erb_processor.rb | 2 +- test/test_http_utils.rb | 2 +- test/test_jsminc_compressor.rb | 2 +- test/test_jst_processor.rb | 2 +- test/test_manifest_utils.rb | 2 +- test/test_path_dependency_utils.rb | 2 +- test/test_path_digest_utils.rb | 2 +- test/test_path_utils.rb | 2 +- test/test_processor_utils.rb | 2 +- test/test_require.rb | 2 +- test/test_source_map_utils.rb | 2 +- test/test_uglifier_compressor.rb | 2 +- test/test_uri_utils.rb | 2 +- test/test_utils.rb | 2 +- test/test_yui_compressor.rb | 2 +- 24 files changed, 28 insertions(+), 28 deletions(-) diff --git a/test/sprockets_test.rb b/test/sprockets_test.rb index 8b45d0aa1..f6da782b0 100644 --- a/test/sprockets_test.rb +++ b/test/sprockets_test.rb @@ -93,7 +93,7 @@ def test(name, &block) end end -class Sprockets::TestCase < MiniTest::Test +class Sprockets::TestCase < Minitest::Test extend Sprockets::TestDefinition FIXTURE_ROOT = File.join(__dir__, "fixtures") diff --git a/test/test_babel_processor.rb b/test/test_babel_processor.rb index 93cc1a166..bdabbaeaa 100644 --- a/test/test_babel_processor.rb +++ b/test/test_babel_processor.rb @@ -4,7 +4,7 @@ require 'sprockets/cache' require 'sprockets/babel_processor' -class TestBabelProcessor < MiniTest::Test +class TestBabelProcessor < Minitest::Test def setup @env = Sprockets::Environment.new @env.append_path File.expand_path("../fixtures", __FILE__) diff --git a/test/test_cache_store.rb b/test/test_cache_store.rb index f4ed3ccc5..bbaa18867 100644 --- a/test/test_cache_store.rb +++ b/test/test_cache_store.rb @@ -85,7 +85,7 @@ def test_clear end end -class TestNullStore < MiniTest::Test +class TestNullStore < Minitest::Test def setup @_store = Sprockets::Cache::NullStore.new @store = Sprockets::Cache.new(Sprockets::Cache::NullStore.new) @@ -99,7 +99,7 @@ def test_inspect include CacheStoreNullTests end -class TestMemoryStore < MiniTest::Test +class TestMemoryStore < Minitest::Test def setup @_store = Sprockets::Cache::MemoryStore.new @store = Sprockets::Cache.new(@_store) @@ -132,7 +132,7 @@ def test_set_with_lru end end -class TestZeroMemoryStore < MiniTest::Test +class TestZeroMemoryStore < Minitest::Test def setup @_store = Sprockets::Cache::MemoryStore.new(0) @store = Sprockets::Cache.new(@_store) @@ -145,7 +145,7 @@ def test_inspect include CacheStoreNullTests end -class TestFileStore < MiniTest::Test +class TestFileStore < Minitest::Test def setup @root = Dir::mktmpdir "sprockets-file-store" @_store = Sprockets::Cache::FileStore.new(@root) @@ -180,7 +180,7 @@ def test_clear_store_dir_not_exist include CacheStoreTests end -class TestZeroFileStore < MiniTest::Test +class TestZeroFileStore < Minitest::Test def setup @tmpdir = Dir::mktmpdir "sprockets-file-store-zero" @_store = Sprockets::Cache::FileStore.new(@tmpdir, 0) diff --git a/test/test_closure_compressor.rb b/test/test_closure_compressor.rb index fe39c2a0c..fd73a8944 100644 --- a/test/test_closure_compressor.rb +++ b/test/test_closure_compressor.rb @@ -3,7 +3,7 @@ require 'sprockets/cache' require 'sprockets/closure_compressor' -class TestClosureCompressor < MiniTest::Test +class TestClosureCompressor < Minitest::Test def test_compress_javascript input = { data: "function foo() {\n return true;\n}", diff --git a/test/test_coffee_script_processor.rb b/test/test_coffee_script_processor.rb index 614460ebd..e5496ef16 100644 --- a/test/test_coffee_script_processor.rb +++ b/test/test_coffee_script_processor.rb @@ -5,7 +5,7 @@ require 'sprockets/coffee_script_processor' require 'sprockets/source_map_utils' -class TestCoffeeScriptProcessor < MiniTest::Test +class TestCoffeeScriptProcessor < Minitest::Test def setup @env = Sprockets::Environment.new @env.append_path File.expand_path("../fixtures", __FILE__) diff --git a/test/test_digest_utils.rb b/test/test_digest_utils.rb index c0548070b..246afbd09 100644 --- a/test/test_digest_utils.rb +++ b/test/test_digest_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/digest_utils' -class TestDigestUtils < MiniTest::Test +class TestDigestUtils < Minitest::Test include Sprockets::DigestUtils def test_detect_digest_class diff --git a/test/test_eco_processor.rb b/test/test_eco_processor.rb index 85b606481..d6903902d 100644 --- a/test/test_eco_processor.rb +++ b/test/test_eco_processor.rb @@ -3,7 +3,7 @@ require 'sprockets/cache' require 'sprockets/eco_processor' -class TestEcoProcessor < MiniTest::Test +class TestEcoProcessor < Minitest::Test def test_compile_eco_template_to_js input = { content_type: 'application/javascript', diff --git a/test/test_ejs_processor.rb b/test/test_ejs_processor.rb index 4c306d001..99e72b051 100644 --- a/test/test_ejs_processor.rb +++ b/test/test_ejs_processor.rb @@ -3,7 +3,7 @@ require 'sprockets/cache' require 'sprockets/ejs_processor' -class TestEjsProcessor < MiniTest::Test +class TestEjsProcessor < Minitest::Test def test_compile_ejs_template_to_js input = { content_type: 'application/javascript', diff --git a/test/test_encoding_utils.rb b/test/test_encoding_utils.rb index e276e2e3b..724d923ff 100644 --- a/test/test_encoding_utils.rb +++ b/test/test_encoding_utils.rb @@ -3,7 +3,7 @@ require 'minitest/autorun' require 'sprockets/encoding_utils' -class TestDigestUtils < MiniTest::Test +class TestDigestUtils < Minitest::Test include Sprockets::EncodingUtils def test_deflate diff --git a/test/test_erb_processor.rb b/test/test_erb_processor.rb index 7ab0a88cb..d82127f1d 100644 --- a/test/test_erb_processor.rb +++ b/test/test_erb_processor.rb @@ -5,7 +5,7 @@ require 'sprockets/erb_processor' require 'sass' -class TestERBProcessor < MiniTest::Test +class TestERBProcessor < Minitest::Test def uri_path(path) path = '/' + path if path[1] == ':' # Windows path / drive letter diff --git a/test/test_http_utils.rb b/test/test_http_utils.rb index b476dc568..9a042d32f 100644 --- a/test/test_http_utils.rb +++ b/test/test_http_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/http_utils' -class TestHTTPUtils < MiniTest::Test +class TestHTTPUtils < Minitest::Test include Sprockets::HTTPUtils def test_match_mime_type diff --git a/test/test_jsminc_compressor.rb b/test/test_jsminc_compressor.rb index d7cfb6a8a..6e402c791 100644 --- a/test/test_jsminc_compressor.rb +++ b/test/test_jsminc_compressor.rb @@ -4,7 +4,7 @@ unless RUBY_PLATFORM.include?('java') require 'sprockets/jsminc_compressor' - class TestJSMincCompressor < MiniTest::Test + class TestJSMincCompressor < Minitest::Test def test_compress_javascript input = { diff --git a/test/test_jst_processor.rb b/test/test_jst_processor.rb index d9d2e5d54..d7e16a60f 100644 --- a/test/test_jst_processor.rb +++ b/test/test_jst_processor.rb @@ -3,7 +3,7 @@ require 'sprockets/cache' require 'sprockets/jst_processor' -class TestJstProcessor < MiniTest::Test +class TestJstProcessor < Minitest::Test def test_export_js_template_in_JST input = { name: 'users/show', diff --git a/test/test_manifest_utils.rb b/test/test_manifest_utils.rb index 02a1755bb..3f0beeb37 100644 --- a/test/test_manifest_utils.rb +++ b/test/test_manifest_utils.rb @@ -3,7 +3,7 @@ require 'sprockets/manifest_utils' require 'logger' -class TestManifestUtils < MiniTest::Test +class TestManifestUtils < Minitest::Test include Sprockets::ManifestUtils def test_generate_manifest_path diff --git a/test/test_path_dependency_utils.rb b/test/test_path_dependency_utils.rb index 2159af4fa..9dd10f94a 100644 --- a/test/test_path_dependency_utils.rb +++ b/test/test_path_dependency_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/path_dependency_utils' -class TestPathDependencyUtils < MiniTest::Test +class TestPathDependencyUtils < Minitest::Test include Sprockets::PathDependencyUtils def test_entries_with_dependencies diff --git a/test/test_path_digest_utils.rb b/test/test_path_digest_utils.rb index a62d5e550..1e93a1ce3 100644 --- a/test/test_path_digest_utils.rb +++ b/test/test_path_digest_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/path_digest_utils' -class TestPathDigestUtils < MiniTest::Test +class TestPathDigestUtils < Minitest::Test include Sprockets::PathDigestUtils def test_file_stat_digest diff --git a/test/test_path_utils.rb b/test/test_path_utils.rb index 0464247ee..3e7c6dc93 100644 --- a/test/test_path_utils.rb +++ b/test/test_path_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/path_utils' -class TestPathUtils < MiniTest::Test +class TestPathUtils < Minitest::Test include Sprockets::PathUtils DOSISH = File::ALT_SEPARATOR != nil diff --git a/test/test_processor_utils.rb b/test/test_processor_utils.rb index 01f92ae21..775d45e6f 100644 --- a/test/test_processor_utils.rb +++ b/test/test_processor_utils.rb @@ -37,7 +37,7 @@ def test_charset_supersedes_default end end -class TestProcessorUtils < MiniTest::Test +class TestProcessorUtils < Minitest::Test include Sprockets::ProcessorUtils class Processor diff --git a/test/test_require.rb b/test/test_require.rb index f356a718f..cfe110fba 100644 --- a/test/test_require.rb +++ b/test/test_require.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'minitest/autorun' -class TestRequire < MiniTest::Test +class TestRequire < Minitest::Test parallelize_me! ROOT = File.expand_path("../..", __FILE__) diff --git a/test/test_source_map_utils.rb b/test/test_source_map_utils.rb index 1fff15d7a..6ab0d2a2e 100644 --- a/test/test_source_map_utils.rb +++ b/test/test_source_map_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/source_map_utils' -class TestSourceMapUtils < MiniTest::Test +class TestSourceMapUtils < Minitest::Test def deep_dup(object) Marshal.load( Marshal.dump(object) ) diff --git a/test/test_uglifier_compressor.rb b/test/test_uglifier_compressor.rb index 0c4de5763..8c120b53e 100644 --- a/test/test_uglifier_compressor.rb +++ b/test/test_uglifier_compressor.rb @@ -4,7 +4,7 @@ require 'sprockets/cache' require 'sprockets/uglifier_compressor' -class TestUglifierCompressor < MiniTest::Test +class TestUglifierCompressor < Minitest::Test def setup @env = Sprockets::Environment.new @env.append_path File.expand_path("../fixtures", __FILE__) diff --git a/test/test_uri_utils.rb b/test/test_uri_utils.rb index f3b946d47..8a9f7dbfc 100644 --- a/test/test_uri_utils.rb +++ b/test/test_uri_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/uri_utils' -class TestURIUtils < MiniTest::Test +class TestURIUtils < Minitest::Test include Sprockets::URIUtils DOSISH = File::ALT_SEPARATOR != nil diff --git a/test/test_utils.rb b/test/test_utils.rb index 49f511d7b..65b009337 100644 --- a/test/test_utils.rb +++ b/test/test_utils.rb @@ -2,7 +2,7 @@ require 'minitest/autorun' require 'sprockets/utils' -class TestUtils < MiniTest::Test +class TestUtils < Minitest::Test include Sprockets::Utils def test_duplicable diff --git a/test/test_yui_compressor.rb b/test/test_yui_compressor.rb index fe701234a..152033253 100644 --- a/test/test_yui_compressor.rb +++ b/test/test_yui_compressor.rb @@ -3,7 +3,7 @@ require 'sprockets/cache' require 'sprockets/yui_compressor' -class TestYUICompressor < MiniTest::Test +class TestYUICompressor < Minitest::Test def test_compress_javascript input = { content_type: 'application/javascript', From 5d795a7b19877118496ec1d2092d77db21171a4d Mon Sep 17 00:00:00 2001 From: Hartley McGuire Date: Sat, 29 Jul 2023 17:34:44 -0400 Subject: [PATCH 4/4] Fix header casing compatibility with Rails 7 To support Rack 3, response headers in `Sprockets::Server` were all downcased. However, this has led to issues with Rack 2 applications (ex. Rails 7) since they still expect mixed case (ex. `Content-Type`) headers. To ensure compatibility with both Rack 2 and Rack 3 applications, this commit makes the casing of the headers conditional on the Rack version. Rack itself provides constants to do this easily for most of the headers used (`Content-Type`, `Content-Length`, `Cache-Control`, and `ETag`) and the rest are added as constants under `Rack::Server`. As an alternative to this, the responses could instead be wrapped using `Rack::Headers` (and `Rack::Utils::HeaderHash` in Rack 2), but making the header casing conditional seems better to me because it is relatively easier to implement and there will be less churn if/when Rack 2 support is eventually removed. --- CHANGELOG.md | 1 + lib/sprockets/server.rb | 48 +++++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1817f73ee..9e19c3a9e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ Get upgrade notes from Sprockets 3.x to 4.x at https://github.com/rails/sprockets/blob/master/UPGRADING.md - Fix for precompile issues when multiple extensions map to the same MIME type (eg. `.jpeg` / `.jpg`). [#781](https://github.com/rails/sprockets/pull/781) +- Fix compatibility with Rack 2 applications. [#790](https://github.com/rails/sprockets/pull/790) ## 4.2.0 diff --git a/lib/sprockets/server.rb b/lib/sprockets/server.rb index f3cdb4f54..c32ce2228 100644 --- a/lib/sprockets/server.rb +++ b/lib/sprockets/server.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true require 'set' require 'time' -require 'rack/utils' +require 'rack' module Sprockets # `Server` is a concern mixed into `Environment` and @@ -11,6 +11,16 @@ module Server # Supported HTTP request methods. ALLOWED_REQUEST_METHODS = ['GET', 'HEAD'].to_set.freeze + # :stopdoc: + if Gem::Version.new(Rack::RELEASE) < Gem::Version.new("3") + X_CASCADE = "X-Cascade" + VARY = "Vary" + else + X_CASCADE = "x-cascade" + VARY = "vary" + end + # :startdoc: + # `call` implements the Rack 1.x specification which accepts an # `env` Hash and returns a three item tuple with the status code, # headers, and body. @@ -148,39 +158,39 @@ def not_modified_response(env, etag) # Returns a 400 Forbidden response tuple def bad_request_response(env) if head_request?(env) - [ 400, { "content-type" => "text/plain", "content-length" => "0" }, [] ] + [ 400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, [] ] else - [ 400, { "content-type" => "text/plain", "content-length" => "11" }, [ "Bad Request" ] ] + [ 400, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "11" }, [ "Bad Request" ] ] end end # Returns a 403 Forbidden response tuple def forbidden_response(env) if head_request?(env) - [ 403, { "content-type" => "text/plain", "content-length" => "0" }, [] ] + [ 403, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0" }, [] ] else - [ 403, { "content-type" => "text/plain", "content-length" => "9" }, [ "Forbidden" ] ] + [ 403, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "9" }, [ "Forbidden" ] ] end end # Returns a 404 Not Found response tuple def not_found_response(env) if head_request?(env) - [ 404, { "content-type" => "text/plain", "content-length" => "0", "x-cascade" => "pass" }, [] ] + [ 404, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0", X_CASCADE => "pass" }, [] ] else - [ 404, { "content-type" => "text/plain", "content-length" => "9", "x-cascade" => "pass" }, [ "Not found" ] ] + [ 404, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "9", X_CASCADE => "pass" }, [ "Not found" ] ] end end def method_not_allowed_response - [ 405, { "content-type" => "text/plain", "content-length" => "18" }, [ "Method Not Allowed" ] ] + [ 405, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "18" }, [ "Method Not Allowed" ] ] end def precondition_failed_response(env) if head_request?(env) - [ 412, { "content-type" => "text/plain", "content-length" => "0", "x-cascade" => "pass" }, [] ] + [ 412, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "0", X_CASCADE => "pass" }, [] ] else - [ 412, { "content-type" => "text/plain", "content-length" => "19", "x-cascade" => "pass" }, [ "Precondition Failed" ] ] + [ 412, { Rack::CONTENT_TYPE => "text/plain", Rack::CONTENT_LENGTH => "19", X_CASCADE => "pass" }, [ "Precondition Failed" ] ] end end @@ -189,7 +199,7 @@ def precondition_failed_response(env) def javascript_exception_response(exception) err = "#{exception.class.name}: #{exception.message}\n (in #{exception.backtrace[0]})" body = "throw Error(#{err.inspect})" - [ 200, { "content-type" => "application/javascript", "content-length" => body.bytesize.to_s }, [ body ] ] + [ 200, { Rack::CONTENT_TYPE => "application/javascript", Rack::CONTENT_LENGTH => body.bytesize.to_s }, [ body ] ] end # Returns a CSS response that hides all elements on the page and @@ -242,7 +252,7 @@ def css_exception_response(exception) } CSS - [ 200, { "content-type" => "text/css; charset=utf-8", "content-length" => body.bytesize.to_s }, [ body ] ] + [ 200, { Rack::CONTENT_TYPE => "text/css; charset=utf-8", Rack::CONTENT_LENGTH => body.bytesize.to_s }, [ body ] ] end # Escape special characters for use inside a CSS content("...") string @@ -258,18 +268,18 @@ def cache_headers(env, etag) headers = {} # Set caching headers - headers["cache-control"] = +"public" - headers["etag"] = %("#{etag}") + headers[Rack::CACHE_CONTROL] = +"public" + headers[Rack::ETAG] = %("#{etag}") # If the request url contains a fingerprint, set a long # expires on the response if path_fingerprint(env["PATH_INFO"]) - headers["cache-control"] << ", max-age=31536000, immutable" + headers[Rack::CACHE_CONTROL] << ", max-age=31536000, immutable" # Otherwise set `must-revalidate` since the asset could be modified. else - headers["cache-control"] << ", must-revalidate" - headers["vary"] = "Accept-Encoding" + headers[Rack::CACHE_CONTROL] << ", must-revalidate" + headers[VARY] = "Accept-Encoding" end headers @@ -279,7 +289,7 @@ def headers(env, asset, length) headers = {} # Set content length header - headers["content-length"] = length.to_s + headers[Rack::CONTENT_LENGTH] = length.to_s # Set content type header if type = asset.content_type @@ -287,7 +297,7 @@ def headers(env, asset, length) if type.start_with?("text/") && asset.charset type += "; charset=#{asset.charset}" end - headers["content-type"] = type + headers[Rack::CONTENT_TYPE] = type end headers.merge(cache_headers(env, asset.etag))