diff --git a/lib/mastodon/middleware/public_file_server.rb b/lib/mastodon/middleware/public_file_server.rb index 634ef6886f..ac2f8c52c4 100644 --- a/lib/mastodon/middleware/public_file_server.rb +++ b/lib/mastodon/middleware/public_file_server.rb @@ -22,12 +22,11 @@ module Mastodon status, headers, response = file # Set cache headers on static files. Some paths require different cache headers + request = Rack::Request.new env headers['cache-control'] = begin - request_path = env['REQUEST_PATH'] - - if request_path.start_with?('/sw.js') + if request.path.start_with?('/sw.js') "public, max-age=#{SERVICE_WORKER_TTL}, must-revalidate" - elsif request_path.start_with?(paperclip_root_url) + elsif request.path.start_with?(paperclip_root_url) "public, max-age=#{CACHE_TTL}, immutable" else "public, max-age=#{CACHE_TTL}, must-revalidate" @@ -35,9 +34,9 @@ module Mastodon end # Override the default CSP header set by the CSP middleware - headers['Content-Security-Policy'] = "default-src 'none'; form-action 'none'" if request_path.start_with?(paperclip_root_url) + headers['content-security-policy'] = "default-src 'none'; form-action 'none'" if request.path.start_with?(paperclip_root_url) - headers['X-Content-Type-Options'] = 'nosniff' + headers['x-content-type-options'] = 'nosniff' [status, headers, response] end diff --git a/spec/requests/public_files_spec.rb b/spec/requests/public_files_spec.rb new file mode 100644 index 0000000000..512e069cf7 --- /dev/null +++ b/spec/requests/public_files_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'Public files' do + include RoutingHelper + + context 'when requesting service worker file' do + it 'returns the file with the expected headers' do + get '/sw.js' + + expect(response) + .to have_http_status(200) + + expect(response.headers['Cache-Control']) + .to eq "public, max-age=#{Mastodon::Middleware::PublicFileServer::SERVICE_WORKER_TTL}, must-revalidate" + + expect(response.headers['X-Content-Type-Options']) + .to eq 'nosniff' + end + end + + context 'when requesting paperclip attachments', :attachment_processing do + let(:attachment) { Fabricate(:media_attachment, type: :image) } + + it 'returns the file with the expected headers' do + get attachment.file.url(:original) + + expect(response) + .to have_http_status(200) + + expect(response.headers['Cache-Control']) + .to eq "public, max-age=#{Mastodon::Middleware::PublicFileServer::CACHE_TTL}, immutable" + + expect(response.headers['Content-Security-Policy']) + .to eq "default-src 'none'; form-action 'none'" + + expect(response.headers['X-Content-Type-Options']) + .to eq 'nosniff' + end + end + + context 'when requesting other static files' do + it 'returns the file with the expected headers' do + get '/sounds/boop.ogg' + + expect(response) + .to have_http_status(200) + + expect(response.headers['Cache-Control']) + .to eq "public, max-age=#{Mastodon::Middleware::PublicFileServer::CACHE_TTL}, must-revalidate" + + expect(response.headers['X-Content-Type-Options']) + .to eq 'nosniff' + end + end +end