Commit b793f0fa authored by Tim Zallmann's avatar Tim Zallmann

Restructured the assets caching setup

New definitions for different types of Uploads

Updated Caching strategy for project + group avatars, Notes Uploads

Fixed upload actions specs + offenses

Added random string as cache buster

Fixing the double quoted string for interpolation
parent fecbe2ed
...@@ -29,12 +29,17 @@ module UploadsActions ...@@ -29,12 +29,17 @@ module UploadsActions
def show def show
return render_404 unless uploader&.exists? return render_404 unless uploader&.exists?
# We need to reset caching from the applications controller to get rid of the no-store value
headers['Cache-Control'] = ''
headers['Pragma'] = ''
if cache_publicly? if cache_publicly?
# We need to reset caching from the applications controller to get rid of the no-store value # Caching for user avatars
headers['Cache-Control'] = ''
expires_in 5.minutes, public: true, must_revalidate: false expires_in 5.minutes, public: true, must_revalidate: false
elsif avatar?
# Caching for Project + Group Avatars
expires_in 5.minutes, private: true, must_revalidate: true
else else
expires_in 0.seconds, must_revalidate: true, private: true expires_in 6.months, private: true, must_revalidate: true
end end
disposition = uploader.embeddable? ? 'inline' : 'attachment' disposition = uploader.embeddable? ? 'inline' : 'attachment'
...@@ -124,6 +129,10 @@ module UploadsActions ...@@ -124,6 +129,10 @@ module UploadsActions
false false
end end
def avatar?
false
end
def model def model
strong_memoize(:model) { find_model } strong_memoize(:model) { find_model }
end end
......
...@@ -85,6 +85,14 @@ class UploadsController < ApplicationController ...@@ -85,6 +85,14 @@ class UploadsController < ApplicationController
User === model || Appearance === model User === model || Appearance === model
end end
def avatar?
User === model || Project === model || Group === model
end
def note_upload?
Note === model
end
def secret? def secret?
params[:secret].present? params[:secret].present?
end end
......
# frozen_string_literal: true # frozen_string_literal: true
require 'spec_helper' require 'spec_helper'
shared_examples 'content not cached without revalidation' do shared_examples 'content 5 min private cached with revalidation' do
it 'ensures content will not be cached without revalidation' do it 'ensures content will not be cached without revalidation' do
expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate') expect(subject['Cache-Control']).to eq('max-age=300, private, must-revalidate')
end end
end end
shared_examples 'content not cached without revalidation and no-store' do shared_examples 'content long term private cached with revalidation' do
it 'ensures content will not be cached without revalidation' do it 'ensures content will not be cached without revalidation' do
# Fixed in newer versions of ActivePack, it will only output a single `private`. expect(subject['Cache-Control']).to eq('max-age=15778476, private, must-revalidate')
expect(subject['Cache-Control']).to eq('max-age=0, private, must-revalidate, no-store')
end end
end end
...@@ -285,7 +284,7 @@ describe UploadsController do ...@@ -285,7 +284,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation' do it_behaves_like 'content 5 min private cached with revalidation' do
subject do subject do
get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' } get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' }
...@@ -305,7 +304,7 @@ describe UploadsController do ...@@ -305,7 +304,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation and no-store' do it_behaves_like 'content 5 min private cached with revalidation' do
subject do subject do
get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' } get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' }
...@@ -358,7 +357,7 @@ describe UploadsController do ...@@ -358,7 +357,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation and no-store' do it_behaves_like 'content 5 min private cached with revalidation' do
subject do subject do
get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' } get :show, params: { model: 'project', mounted_as: 'avatar', id: project.id, filename: 'dk.png' }
...@@ -390,7 +389,7 @@ describe UploadsController do ...@@ -390,7 +389,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation' do it_behaves_like 'content 5 min private cached with revalidation' do
subject do subject do
get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' } get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' }
...@@ -410,7 +409,7 @@ describe UploadsController do ...@@ -410,7 +409,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation and no-store' do it_behaves_like 'content 5 min private cached with revalidation' do
subject do subject do
get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' } get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' }
...@@ -454,7 +453,7 @@ describe UploadsController do ...@@ -454,7 +453,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation and no-store' do it_behaves_like 'content 5 min private cached with revalidation' do
subject do subject do
get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' } get :show, params: { model: 'group', mounted_as: 'avatar', id: group.id, filename: 'dk.png' }
...@@ -491,7 +490,7 @@ describe UploadsController do ...@@ -491,7 +490,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation' do it_behaves_like 'content long term private cached with revalidation' do
subject do subject do
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
...@@ -511,7 +510,7 @@ describe UploadsController do ...@@ -511,7 +510,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation and no-store' do it_behaves_like 'content long term private cached with revalidation' do
subject do subject do
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
...@@ -564,7 +563,7 @@ describe UploadsController do ...@@ -564,7 +563,7 @@ describe UploadsController do
expect(response).to have_gitlab_http_status(200) expect(response).to have_gitlab_http_status(200)
end end
it_behaves_like 'content not cached without revalidation and no-store' do it_behaves_like 'content long term private cached with revalidation' do
subject do subject do
get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' } get :show, params: { model: 'note', mounted_as: 'attachment', id: note.id, filename: 'dk.png' }
......
...@@ -45,7 +45,7 @@ describe 'User creates snippet', :js do ...@@ -45,7 +45,7 @@ describe 'User creates snippet', :js do
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
expect(link).to match(%r{/uploads/-/system/user/#{user.id}/\h{32}/banana_sample\.gif\z}) expect(link).to match(%r{/uploads/-/system/user/#{user.id}/\h{32}/banana_sample\.gif\z})
reqs = inspect_requests { visit(link) } reqs = inspect_requests { visit("#{link}?ran=#{SecureRandom.base64(20)}") }
expect(reqs.first.status_code).to eq(200) expect(reqs.first.status_code).to eq(200)
end end
end end
...@@ -63,7 +63,7 @@ describe 'User creates snippet', :js do ...@@ -63,7 +63,7 @@ describe 'User creates snippet', :js do
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z}) expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
reqs = inspect_requests { visit(link) } reqs = inspect_requests { visit("#{link}?ran=#{SecureRandom.base64(20)}") }
expect(reqs.first.status_code).to eq(200) expect(reqs.first.status_code).to eq(200)
end end
...@@ -88,7 +88,7 @@ describe 'User creates snippet', :js do ...@@ -88,7 +88,7 @@ describe 'User creates snippet', :js do
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src'] link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z}) expect(link).to match(%r{/uploads/-/system/personal_snippet/#{Snippet.last.id}/\h{32}/banana_sample\.gif\z})
reqs = inspect_requests { visit(link) } reqs = inspect_requests { visit("#{link}?ran=#{SecureRandom.base64(20)}") }
expect(reqs.first.status_code).to eq(200) expect(reqs.first.status_code).to eq(200)
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment