diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8bef4ed2a59..82a83869f80 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -66,6 +66,12 @@ class ApplicationController < ActionController::Base refresh_session(current_user) end + def immutable_for(duration) + response.cache_control[:max_age] = duration.to_i + response.cache_control[:public] = true + response.cache_control[:extras] = ["immutable"] + end + def dont_cache_page if !response.headers["Cache-Control"] && response.cache_control.blank? response.headers["Cache-Control"] = "no-store, must-revalidate, no-cache, private" diff --git a/app/controllers/highlight_js_controller.rb b/app/controllers/highlight_js_controller.rb index b815a49f626..86137be56ea 100644 --- a/app/controllers/highlight_js_controller.rb +++ b/app/controllers/highlight_js_controller.rb @@ -20,7 +20,7 @@ class HighlightJsController < ApplicationController response.headers["Last-Modified"] = 10.years.ago.httpdate response.headers["Content-Length"] = highlight_js.bytesize.to_s - expires_in 1.year, public: true + immutable_for 1.year render text: highlight_js, disposition: nil, content_type: 'application/javascript' end diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index 6fa864c2683..fe0fb1ffead 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -117,7 +117,7 @@ class StaticController < ApplicationController response.headers["Content-Length"] = @@default_favicon.bytesize.to_s render text: @@default_favicon, content_type: "image/png" else - expires_in 1.year, public: true + immutable_for 1.year response.headers["Expires"] = 1.year.from_now.httpdate response.headers["Content-Length"] = data.bytesize.to_s response.headers["Last-Modified"] = Time.new('2000-01-01').httpdate @@ -151,7 +151,7 @@ class StaticController < ApplicationController response.headers["Cache-Control"] = 'max-age=31557600, public' response.headers["Content-Encoding"] = 'br' - expires_in 1.year, public: true, must_revalidate: false + immutable_for 1.year send_file(path, opts) end @@ -163,7 +163,7 @@ class StaticController < ApplicationController # SECURITY what if path has /../ raise Discourse::NotFound unless path.start_with?(Rails.root.to_s + "/public/assets") - expires_in 1.year, public: true + immutable_for 1.year response.headers["Expires"] = 1.year.from_now.httpdate response.headers["Access-Control-Allow-Origin"] = params[:origin] if params[:origin] diff --git a/app/controllers/stylesheets_controller.rb b/app/controllers/stylesheets_controller.rb index 2d3df8b3a37..55c5166d4f1 100644 --- a/app/controllers/stylesheets_controller.rb +++ b/app/controllers/stylesheets_controller.rb @@ -41,7 +41,7 @@ class StylesheetsController < ApplicationController end response.headers['Last-Modified'] = stylesheet_time.httpdate if stylesheet_time - expires_in 1.year, public: true unless Rails.env == "development" + immutable_for(1.year) unless Rails.env == "development" send_file(location, disposition: :inline) end diff --git a/app/controllers/user_avatars_controller.rb b/app/controllers/user_avatars_controller.rb index b0d0b4ea7e4..de49789cb6c 100644 --- a/app/controllers/user_avatars_controller.rb +++ b/app/controllers/user_avatars_controller.rb @@ -40,7 +40,7 @@ class UserAvatarsController < ApplicationController response.headers["Last-Modified"] = File.ctime(image).httpdate response.headers["Content-Length"] = File.size(image).to_s - expires_in 1.year, public: true + immutable_for(1.year) send_file image, disposition: nil end @@ -57,7 +57,7 @@ class UserAvatarsController < ApplicationController response.headers["Last-Modified"] = File.ctime(image).httpdate response.headers["Content-Length"] = File.size(image).to_s - expires_in 1.year, public: true + immutable_for(1.year) send_file image, disposition: nil end @@ -112,7 +112,7 @@ class UserAvatarsController < ApplicationController if image response.headers["Last-Modified"] = File.ctime(image).httpdate response.headers["Content-Length"] = File.size(image).to_s - expires_in 1.year, public: true + immutable_for 1.year send_file image, disposition: nil else render_blank @@ -139,7 +139,7 @@ class UserAvatarsController < ApplicationController # putting a bogus date cause download is not retaining the data response.headers["Last-Modified"] = DateTime.parse("1-1-2000").httpdate response.headers["Content-Length"] = File.size(path).to_s - expires_in 1.year, public: true + immutable_for(1.year) send_file path, disposition: nil end diff --git a/spec/controllers/user_avatars_controller_spec.rb b/spec/controllers/user_avatars_controller_spec.rb index 7c40e2ba72a..38c93ccb6f3 100644 --- a/spec/controllers/user_avatars_controller_spec.rb +++ b/spec/controllers/user_avatars_controller_spec.rb @@ -46,7 +46,7 @@ describe UserAvatarsController do get :show, size: 98, username: user.username, version: upload.id, hostname: 'default' expect(response.body).to eq("image") - expect(response.headers["Cache-Control"]).to eq('max-age=31557600, public') + expect(response.headers["Cache-Control"]).to eq('max-age=31557600, public, immutable') end it 'serves image even if size missing and its in local mode' do