diff --git a/app/controllers/site_customizations_controller.rb b/app/controllers/site_customizations_controller.rb index 46af82b035b..e86fac11d0b 100644 --- a/app/controllers/site_customizations_controller.rb +++ b/app/controllers/site_customizations_controller.rb @@ -2,13 +2,19 @@ class SiteCustomizationsController < ApplicationController skip_before_filter :preload_json, :check_xhr, :redirect_to_login_if_required def show - version = params["v"] + cache_time = request.env["HTTP_IF_MODIFIED_SINCE"] + cache_time = Time.rfc2822(cache_time) rescue nil if cache_time + stylesheet_time = SiteCustomization.where(key: params[:key].to_s).pluck(:created_at).first - if version && version == request.headers['If-None-Match'] + if !stylesheet_time + raise Discourse::NotFound + end + + if cache_time && stylesheet_time <= cache_time return render nothing: true, status: 304 end - response.headers["ETag"] = version if version + response.headers["Last-Modified"] = stylesheet_time.httpdate expires_in 1.year, public: true render text: SiteCustomization.stylesheet_contents(params[:key], params[:target] == "mobile" ? :mobile : :desktop), content_type: "text/css" diff --git a/app/controllers/stylesheets_controller.rb b/app/controllers/stylesheets_controller.rb index cec57ddcba0..97b9f2b4984 100644 --- a/app/controllers/stylesheets_controller.rb +++ b/app/controllers/stylesheets_controller.rb @@ -5,24 +5,31 @@ class StylesheetsController < ApplicationController target,digest = params[:name].split("_") digest_orig = digest + digest = "_" + digest if digest - if digest_orig && digest_orig == request.headers['If-None-Match'] - return render nothing: true, status: 304 + cache_time = request.env["HTTP_IF_MODIFIED_SINCE"] + cache_time = Time.rfc2822(cache_time) rescue nil if cache_time + + query = StylesheetCache.where(target: target) + if digest + query = query.where(digest: digest_orig) + else + query = query.order('id desc') end - digest = "_" + digest if digest + stylesheet_time = query.pluck(:created_at).first + if !stylesheet_time + return render nothing: true, status: 404 + end + + if cache_time && stylesheet_time && stylesheet_time <= cache_time + return render nothing: true, status: 304 + end # Security note, safe due to route constraint location = "#{Rails.root}/#{DiscourseStylesheets::CACHE_PATH}/#{target}#{digest}.css" unless File.exist?(location) - query = StylesheetCache.where(target: target) - if digest - query = query.where(digest: digest_orig) - else - query = query.order('id desc') - end - if current = query.first File.write(location, current.content) else @@ -30,7 +37,7 @@ class StylesheetsController < ApplicationController end end - response.headers['ETag'] = digest_orig if digest_orig + response.headers['Last-Modified'] = stylesheet_time.httpdate expires_in 1.year, public: true unless Rails.env == "development" send_file(location, disposition: :inline)