Fix anonymous access to outbox not being cached by the reverse proxy (#16458)
* Fix anonymous access to outbox not being cached by the reverse proxy Up until now, anonymous access to outbox was marked as public, but with a 0 duration for caching, which means remote proxies would only serve from cache when the server was completely overwhelmed. Changed that cache duration to one minute, so that repeated anonymous access to one account's outbox can be appropriately cached. Also added `Signature` to the `Vary` header in case a page is requested, so that authenticated fetches are never served from cache (which only contains public toots). * Remove Vary: Accept header from webfinger controller Indeed, we have stopped returning xrd, and only ever return jrd, so the Accept request header does not matter anymore. * Cache negative webfinger hits for 3 minutesgh/stable
parent
38b3419950
commit
49219508bc
|
@ -11,7 +11,11 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||||
before_action :set_cache_headers
|
before_action :set_cache_headers
|
||||||
|
|
||||||
def show
|
def show
|
||||||
expires_in(page_requested? ? 0 : 3.minutes, public: public_fetch_mode? && !(signed_request_account.present? && page_requested?))
|
if page_requested?
|
||||||
|
expires_in(1.minute, public: public_fetch_mode? && signed_request_account.nil?)
|
||||||
|
else
|
||||||
|
expires_in(3.minutes, public: public_fetch_mode?)
|
||||||
|
end
|
||||||
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
render json: outbox_presenter, serializer: ActivityPub::OutboxSerializer, adapter: ActivityPub::Adapter, content_type: 'application/activity+json'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -76,4 +80,8 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
||||||
def set_account
|
def set_account
|
||||||
@account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
|
@account = params[:account_username].present? ? Account.find_local!(username_param) : Account.representative
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def set_cache_headers
|
||||||
|
response.headers['Vary'] = 'Signature' if authorized_fetch_mode? || page_requested?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,6 @@ module WellKnown
|
||||||
class WebfingerController < ActionController::Base
|
class WebfingerController < ActionController::Base
|
||||||
include RoutingHelper
|
include RoutingHelper
|
||||||
|
|
||||||
before_action { response.headers['Vary'] = 'Accept' }
|
|
||||||
before_action :set_account
|
before_action :set_account
|
||||||
before_action :check_account_suspension
|
before_action :check_account_suspension
|
||||||
|
|
||||||
|
@ -39,10 +38,12 @@ module WellKnown
|
||||||
end
|
end
|
||||||
|
|
||||||
def bad_request
|
def bad_request
|
||||||
|
expires_in(3.minutes, public: true)
|
||||||
head 400
|
head 400
|
||||||
end
|
end
|
||||||
|
|
||||||
def not_found
|
def not_found
|
||||||
|
expires_in(3.minutes, public: true)
|
||||||
head 404
|
head 404
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,10 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||||
|
|
||||||
it_behaves_like 'cachable response'
|
it_behaves_like 'cachable response'
|
||||||
|
|
||||||
|
it 'does not have a Vary header' do
|
||||||
|
expect(response.headers['Vary']).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
context 'when account is permanently suspended' do
|
context 'when account is permanently suspended' do
|
||||||
before do
|
before do
|
||||||
account.suspend!
|
account.suspend!
|
||||||
|
@ -96,6 +100,10 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||||
|
|
||||||
it_behaves_like 'cachable response'
|
it_behaves_like 'cachable response'
|
||||||
|
|
||||||
|
it 'returns Vary header with Signature' do
|
||||||
|
expect(response.headers['Vary']).to include 'Signature'
|
||||||
|
end
|
||||||
|
|
||||||
context 'when account is permanently suspended' do
|
context 'when account is permanently suspended' do
|
||||||
before do
|
before do
|
||||||
account.suspend!
|
account.suspend!
|
||||||
|
@ -144,7 +152,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns private Cache-Control header' do
|
it 'returns private Cache-Control header' do
|
||||||
expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
|
expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -170,7 +178,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns private Cache-Control header' do
|
it 'returns private Cache-Control header' do
|
||||||
expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
|
expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -195,7 +203,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns private Cache-Control header' do
|
it 'returns private Cache-Control header' do
|
||||||
expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
|
expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -220,7 +228,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns private Cache-Control header' do
|
it 'returns private Cache-Control header' do
|
||||||
expect(response.headers['Cache-Control']).to eq 'max-age=0, private'
|
expect(response.headers['Cache-Control']).to eq 'max-age=60, private'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,10 @@ describe WellKnown::WebfingerController, type: :controller do
|
||||||
expect(response).to have_http_status(200)
|
expect(response).to have_http_status(200)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'does not set a Vary header' do
|
||||||
|
expect(response.headers['Vary']).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
it 'returns application/jrd+json' do
|
it 'returns application/jrd+json' do
|
||||||
expect(response.media_type).to eq 'application/jrd+json'
|
expect(response.media_type).to eq 'application/jrd+json'
|
||||||
end
|
end
|
||||||
|
|
Reference in New Issue