2019-05-03 06:17:27 +08:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2015-05-05 13:50:13 +08:00
|
|
|
class StylesheetsController < ApplicationController
|
2020-08-28 22:36:52 +08:00
|
|
|
skip_before_action :preload_json,
|
|
|
|
:redirect_to_login_if_required,
|
2024-06-25 19:32:18 +08:00
|
|
|
:redirect_to_profile_if_required,
|
2020-08-28 22:36:52 +08:00
|
|
|
:check_xhr,
|
|
|
|
:verify_authenticity_token,
|
|
|
|
only: %i[show show_source_map color_scheme]
|
2017-04-12 22:52:52 +08:00
|
|
|
|
2021-01-29 10:14:49 +08:00
|
|
|
before_action :apply_cdn_headers, only: %i[show show_source_map color_scheme]
|
|
|
|
|
2017-04-12 22:52:52 +08:00
|
|
|
def show_source_map
|
|
|
|
show_resource(source_map: true)
|
|
|
|
end
|
2015-05-05 13:50:13 +08:00
|
|
|
|
|
|
|
def show
|
2018-03-06 12:20:39 +08:00
|
|
|
is_asset_path
|
|
|
|
|
2017-04-12 22:52:52 +08:00
|
|
|
show_resource
|
|
|
|
end
|
|
|
|
|
2020-08-28 22:36:52 +08:00
|
|
|
def color_scheme
|
|
|
|
params.require("id")
|
|
|
|
params.permit("theme_id")
|
|
|
|
|
2021-06-15 14:57:17 +08:00
|
|
|
manager = Stylesheet::Manager.new(theme_id: params[:theme_id])
|
|
|
|
stylesheet = manager.color_scheme_stylesheet_details(params[:id], "all")
|
2020-08-28 22:36:52 +08:00
|
|
|
render json: stylesheet
|
|
|
|
end
|
2021-07-16 00:52:40 +08:00
|
|
|
|
2017-04-12 22:52:52 +08:00
|
|
|
protected
|
|
|
|
|
|
|
|
def show_resource(source_map: false)
|
|
|
|
extension = source_map ? ".css.map" : ".css"
|
|
|
|
|
2015-05-22 14:15:46 +08:00
|
|
|
no_cookies
|
|
|
|
|
2015-05-23 13:25:05 +08:00
|
|
|
target, digest = params[:name].split(/_([a-f0-9]{40})/)
|
2015-05-21 14:09:23 +08:00
|
|
|
|
2015-05-21 15:05:22 +08:00
|
|
|
cache_time = request.env["HTTP_IF_MODIFIED_SINCE"]
|
2018-03-28 16:20:08 +08:00
|
|
|
|
2023-06-12 18:49:26 +08:00
|
|
|
if cache_time.present?
|
2018-03-28 16:20:08 +08:00
|
|
|
begin
|
|
|
|
cache_time = Time.rfc2822(cache_time)
|
|
|
|
rescue ArgumentError
|
|
|
|
end
|
|
|
|
end
|
2015-05-21 15:05:22 +08:00
|
|
|
|
|
|
|
query = StylesheetCache.where(target: target)
|
|
|
|
if digest
|
2015-05-22 09:21:16 +08:00
|
|
|
query = query.where(digest: digest)
|
2015-05-21 15:05:22 +08:00
|
|
|
else
|
|
|
|
query = query.order("id desc")
|
2015-05-21 14:09:23 +08:00
|
|
|
end
|
|
|
|
|
2015-05-22 09:21:16 +08:00
|
|
|
# Security note, safe due to route constraint
|
|
|
|
underscore_digest = digest ? "_" + digest : ""
|
2019-08-29 15:27:07 +08:00
|
|
|
|
2021-07-26 12:22:54 +08:00
|
|
|
cache_path = Stylesheet::Manager.cache_fullpath
|
2019-08-29 15:27:07 +08:00
|
|
|
location = "#{cache_path}/#{target}#{underscore_digest}#{extension}"
|
2015-05-22 09:21:16 +08:00
|
|
|
|
2023-02-13 12:39:45 +08:00
|
|
|
stylesheet_time = query.pick(:created_at)
|
2015-05-22 09:21:16 +08:00
|
|
|
|
|
|
|
handle_missing_cache(location, target, digest) if !stylesheet_time
|
2015-05-21 15:05:22 +08:00
|
|
|
|
2023-06-12 18:49:26 +08:00
|
|
|
if cache_time.present? && stylesheet_time && stylesheet_time <= cache_time
|
2017-08-31 12:06:56 +08:00
|
|
|
return render body: nil, status: 304
|
2015-05-21 15:05:22 +08:00
|
|
|
end
|
2015-05-05 13:50:13 +08:00
|
|
|
|
|
|
|
unless File.exist?(location)
|
2023-02-13 12:39:45 +08:00
|
|
|
if current = query.pick(source_map ? :source_map : :content)
|
2019-08-29 15:27:07 +08:00
|
|
|
FileUtils.mkdir_p(cache_path)
|
2017-04-12 22:52:52 +08:00
|
|
|
File.write(location, current)
|
2015-05-05 13:50:13 +08:00
|
|
|
else
|
2015-05-22 09:21:16 +08:00
|
|
|
raise Discourse::NotFound
|
2015-05-05 13:50:13 +08:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2017-04-12 22:52:52 +08:00
|
|
|
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
|
2015-05-05 13:50:13 +08:00
|
|
|
send_file(location, disposition: :inline)
|
2015-05-22 09:21:16 +08:00
|
|
|
end
|
|
|
|
|
|
|
|
def handle_missing_cache(location, name, digest)
|
2017-04-12 22:52:52 +08:00
|
|
|
location = location.sub(".css.map", ".css")
|
|
|
|
source_map_location = location + ".map"
|
2018-03-28 16:20:08 +08:00
|
|
|
existing = read_file(location)
|
2017-04-12 22:52:52 +08:00
|
|
|
|
2015-05-22 09:21:16 +08:00
|
|
|
if existing && digest
|
2018-03-28 16:20:08 +08:00
|
|
|
source_map = read_file(source_map_location)
|
2017-04-12 22:52:52 +08:00
|
|
|
StylesheetCache.add(name, digest, existing, source_map)
|
2015-05-22 09:21:16 +08:00
|
|
|
end
|
2015-05-05 13:50:13 +08:00
|
|
|
end
|
2015-05-22 09:21:16 +08:00
|
|
|
|
2018-03-28 16:20:08 +08:00
|
|
|
private
|
|
|
|
|
|
|
|
def read_file(location)
|
|
|
|
begin
|
|
|
|
File.read(location)
|
|
|
|
rescue Errno::ENOENT
|
|
|
|
end
|
2018-06-07 13:28:18 +08:00
|
|
|
end
|
2015-05-05 13:50:13 +08:00
|
|
|
end
|