Created
September 20, 2023 10:58
-
-
Save fwolfst/3aa45686b912bfcb3bea102aeb1bfda5 to your computer and use it in GitHub Desktop.
rails initializer for sprockets patch
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
# Avoid a funky bug in Sprockets | |
# https://github.com/rails/sprockets/issues/749 | |
# made serving files likes /assets/logos/layout-logo-compact.svg | |
# impossible under certain circumstances. | |
class MonkeyPatch🐒ObsoleteCheck < StandardError | |
end | |
CURRENT_SPROCKETS_VERSION_WITHOUT_PATCH = "4.2.1" | |
if Sprockets::VERSION != CURRENT_SPROCKETS_VERSION_WITHOUT_PATCH | |
raise MonkeyPatch🐒ObsoleteCheck.new( | |
<<-MESSAGE | |
Sprockets was updated! (finally?) | |
Has https://github.com/rails/sprockets/pull/793/ been merged?' | |
-> If so, delete this file. | |
Offending spec is e.g.: | |
`rspec ./spec/dependsonyourprojcet.rb:5` | |
MESSAGE | |
) | |
end | |
# Patch from https://github.com/rails/sprockets/pull/793/ | |
module Sprockets | |
# `Server` is a concern mixed into `Environment` and | |
# `CachedEnvironment` that provides a Rack compatible `call` | |
# interface and url generation helpers. | |
module Server | |
def call(env) | |
start_time = Time.now.to_f | |
time_elapsed = lambda { ((Time.now.to_f - start_time) * 1000).to_i } | |
unless ALLOWED_REQUEST_METHODS.include? env['REQUEST_METHOD'] | |
return method_not_allowed_response | |
end | |
msg = "Served asset #{env['PATH_INFO']} -" | |
# Extract the path from everything after the leading slash | |
full_path = Rack::Utils.unescape(env['PATH_INFO'].to_s.sub(/^\//, '')) | |
path = full_path | |
return bad_request_response(env) unless path.valid_encoding? | |
return forbidden_response(env) if forbidden_request?(path) | |
asset = find_asset(path) | |
# Strip fingerprint | |
if asset.nil? && fingerprint = path_fingerprint(path) | |
path = path.sub("-#{fingerprint}", '') | |
return forbidden_response(env) if forbidden_request?(path) | |
asset = find_asset(path) | |
end | |
if fingerprint | |
if_match = asset&.etag | |
elsif env['HTTP_IF_MATCH'] | |
if_match = env['HTTP_IF_MATCH'][/"(\w+)"$/, 1] | |
end | |
if env['HTTP_IF_NONE_MATCH'] | |
if_none_match = env['HTTP_IF_NONE_MATCH'][/"(\w+)"$/, 1] | |
end | |
if asset.nil? | |
status = :not_found | |
elsif fingerprint && asset.etag != fingerprint | |
status = :not_found | |
elsif if_match && asset.etag != if_match | |
status = :precondition_failed | |
elsif if_none_match && asset.etag == if_none_match | |
status = :not_modified | |
else | |
status = :ok | |
end | |
case status | |
when :ok | |
logger.info "#{msg} 200 OK (#{time_elapsed.call}ms)" | |
ok_response(asset, env) | |
when :not_modified | |
logger.info "#{msg} 304 Not Modified (#{time_elapsed.call}ms)" | |
not_modified_response(env, if_none_match) | |
when :not_found | |
logger.info "#{msg} 404 Not Found (#{time_elapsed.call}ms)" | |
not_found_response(env) | |
when :precondition_failed | |
logger.info "#{msg} 412 Precondition Failed (#{time_elapsed.call}ms)" | |
precondition_failed_response(env) | |
end | |
rescue Exception => e | |
logger.error "Error compiling asset #{path}:" | |
logger.error "#{e.class.name}: #{e.message}" | |
case File.extname(path) | |
when ".js" | |
# Re-throw JavaScript asset exceptions to the browser | |
logger.info "#{msg} 500 Internal Server Error\n\n" | |
return javascript_exception_response(e) | |
when ".css" | |
# Display CSS asset exceptions in the browser | |
logger.info "#{msg} 500 Internal Server Error\n\n" | |
return css_exception_response(e) | |
else | |
raise | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment