mirror of
https://github.com/discourse/discourse.git
synced 2024-12-18 19:04:29 +08:00
e1d2b67178
The cache_fullpath for the Stylesheet::Manager was the same for every test runner in a parallel test environment, so when other specs or other places e.g. the stylesheets_controller_spec ran rm -rf Stylesheet::Manager.cache_fullpath this caused errors for other specs running that went through the Stylesheet::Manager::Builder#compile path, causing the error ``` Errno::ENOENT: No such file or directory @ rb_sysopen ``` Also fixed the stylesheet_controller which was interpolating Rails.root + CACHE_PATH itself instead of just using Stylesheet::Manager.cache_fullpath
109 lines
2.7 KiB
Ruby
109 lines
2.7 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class StylesheetsController < ApplicationController
|
|
skip_before_action :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show, :show_source_map, :color_scheme]
|
|
|
|
before_action :apply_cdn_headers, only: [:show, :show_source_map, :color_scheme]
|
|
|
|
def show_source_map
|
|
show_resource(source_map: true)
|
|
end
|
|
|
|
def show
|
|
is_asset_path
|
|
|
|
show_resource
|
|
end
|
|
|
|
def color_scheme
|
|
params.require("id")
|
|
params.permit("theme_id")
|
|
|
|
manager = Stylesheet::Manager.new(theme_id: params[:theme_id])
|
|
stylesheet = manager.color_scheme_stylesheet_details(params[:id], 'all')
|
|
render json: stylesheet
|
|
end
|
|
|
|
protected
|
|
|
|
def show_resource(source_map: false)
|
|
|
|
extension = source_map ? ".css.map" : ".css"
|
|
|
|
no_cookies
|
|
|
|
target, digest = params[:name].split(/_([a-f0-9]{40})/)
|
|
|
|
cache_time = request.env["HTTP_IF_MODIFIED_SINCE"]
|
|
|
|
if cache_time
|
|
begin
|
|
cache_time = Time.rfc2822(cache_time)
|
|
rescue ArgumentError
|
|
end
|
|
end
|
|
|
|
query = StylesheetCache.where(target: target)
|
|
if digest
|
|
query = query.where(digest: digest)
|
|
else
|
|
query = query.order('id desc')
|
|
end
|
|
|
|
# Security note, safe due to route constraint
|
|
underscore_digest = digest ? "_" + digest : ""
|
|
|
|
cache_path = Stylesheet::Manager.cache_fullpath
|
|
location = "#{cache_path}/#{target}#{underscore_digest}#{extension}"
|
|
|
|
stylesheet_time = query.pluck_first(:created_at)
|
|
|
|
if !stylesheet_time
|
|
handle_missing_cache(location, target, digest)
|
|
end
|
|
|
|
if cache_time && stylesheet_time && stylesheet_time <= cache_time
|
|
return render body: nil, status: 304
|
|
end
|
|
|
|
unless File.exist?(location)
|
|
if current = query.pluck_first(source_map ? :source_map : :content)
|
|
FileUtils.mkdir_p(cache_path)
|
|
File.write(location, current)
|
|
else
|
|
raise Discourse::NotFound
|
|
end
|
|
end
|
|
|
|
if Rails.env == "development"
|
|
response.headers['Last-Modified'] = Time.zone.now.httpdate
|
|
immutable_for(1.second)
|
|
else
|
|
response.headers['Last-Modified'] = stylesheet_time.httpdate if stylesheet_time
|
|
immutable_for(1.year)
|
|
end
|
|
send_file(location, disposition: :inline)
|
|
end
|
|
|
|
def handle_missing_cache(location, name, digest)
|
|
location = location.sub(".css.map", ".css")
|
|
source_map_location = location + ".map"
|
|
existing = read_file(location)
|
|
|
|
if existing && digest
|
|
source_map = read_file(source_map_location)
|
|
StylesheetCache.add(name, digest, existing, source_map)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def read_file(location)
|
|
begin
|
|
File.read(location)
|
|
rescue Errno::ENOENT
|
|
end
|
|
end
|
|
|
|
end
|