Cache JSON of immutable ActivityPub representations (#6171)
This commit is contained in:
		
							parent
							
								
									d907d4352e
								
							
						
					
					
						commit
						c10f4bdb03
					
				| @ -2,7 +2,8 @@ | ||||
| 
 | ||||
| class AccountsController < ApplicationController | ||||
|   include AccountControllerConcern | ||||
|   include SignatureVerification | ||||
| 
 | ||||
|   before_action :set_cache_headers | ||||
| 
 | ||||
|   def show | ||||
|     respond_to do |format| | ||||
| @ -26,10 +27,11 @@ class AccountsController < ApplicationController | ||||
|       end | ||||
| 
 | ||||
|       format.json do | ||||
|         render json: @account, | ||||
|                serializer: ActivityPub::ActorSerializer, | ||||
|                adapter: ActivityPub::Adapter, | ||||
|                content_type: 'application/activity+json' | ||||
|         skip_session! | ||||
| 
 | ||||
|         render_cached_json(['activitypub', 'actor', @account.cache_key], content_type: 'application/activity+json') do | ||||
|           ActiveModelSerializers::SerializableResource.new(@account, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  | ||||
| @ -4,15 +4,19 @@ class ActivityPub::FollowsController < Api::BaseController | ||||
|   include SignatureVerification | ||||
| 
 | ||||
|   def show | ||||
|     render( | ||||
|       json: FollowRequest.includes(:account).references(:account).find_by!( | ||||
|         id: params.require(:id), | ||||
|         accounts: { domain: nil, username: params.require(:account_username) }, | ||||
|         target_account: signed_request_account | ||||
|       ), | ||||
|       serializer: ActivityPub::FollowSerializer, | ||||
|       adapter: ActivityPub::Adapter, | ||||
|       content_type: 'application/activity+json' | ||||
|     render json: follow_request, | ||||
|            serializer: ActivityPub::FollowSerializer, | ||||
|            adapter: ActivityPub::Adapter, | ||||
|            content_type: 'application/activity+json' | ||||
|   end | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def follow_request | ||||
|     FollowRequest.includes(:account).references(:account).find_by!( | ||||
|       id: params.require(:id), | ||||
|       accounts: { domain: nil, username: params.require(:account_username) }, | ||||
|       target_account: signed_request_account | ||||
|     ) | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -123,11 +123,23 @@ class ApplicationController < ActionController::Base | ||||
|   end | ||||
| 
 | ||||
|   def render_cached_json(cache_key, **options) | ||||
|     options[:expires_in] ||= 3.minutes | ||||
|     cache_key              = cache_key.join(':') if cache_key.is_a?(Enumerable) | ||||
|     content_type           = options.delete(:content_type) || 'application/json' | ||||
| 
 | ||||
|     data = Rails.cache.fetch(cache_key, { raw: true }.merge(options)) do | ||||
|       yield.to_json | ||||
|     end | ||||
| 
 | ||||
|     expires_in options[:expires_in], public: true | ||||
|     render json: data | ||||
|     render json: data, content_type: content_type | ||||
|   end | ||||
| 
 | ||||
|   def set_cache_headers | ||||
|     response.headers['Vary'] = 'Accept' | ||||
|   end | ||||
| 
 | ||||
|   def skip_session! | ||||
|     request.session_options[:skip] = true | ||||
|   end | ||||
| end | ||||
|  | ||||
| @ -2,14 +2,16 @@ | ||||
| 
 | ||||
| class EmojisController < ApplicationController | ||||
|   before_action :set_emoji | ||||
|   before_action :set_cache_headers | ||||
| 
 | ||||
|   def show | ||||
|     respond_to do |format| | ||||
|       format.json do | ||||
|         render json: @emoji, | ||||
|                serializer: ActivityPub::EmojiSerializer, | ||||
|                adapter: ActivityPub::Adapter, | ||||
|                content_type: 'application/activity+json' | ||||
|         skip_session! | ||||
| 
 | ||||
|         render_cached_json(['activitypub', 'emoji', @emoji.cache_key], content_type: 'application/activity+json') do | ||||
|           ActiveModelSerializers::SerializableResource.new(@emoji, serializer: ActivityPub::EmojiSerializer, adapter: ActivityPub::Adapter) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
|  | ||||
| @ -10,7 +10,7 @@ class StatusesController < ApplicationController | ||||
|   before_action :set_link_headers | ||||
|   before_action :check_account_suspension | ||||
|   before_action :redirect_to_original, only: [:show] | ||||
|   before_action { response.headers['Vary'] = 'Accept' } | ||||
|   before_action :set_cache_headers | ||||
| 
 | ||||
|   def show | ||||
|     respond_to do |format| | ||||
| @ -22,25 +22,21 @@ class StatusesController < ApplicationController | ||||
|       end | ||||
| 
 | ||||
|       format.json do | ||||
|         render json: @status, | ||||
|                serializer: ActivityPub::NoteSerializer, | ||||
|                adapter: ActivityPub::Adapter, | ||||
|                content_type: 'application/activity+json' | ||||
|         skip_session! unless @stream_entry.hidden? | ||||
| 
 | ||||
|         # Allow HTTP caching for 3 minutes if the status is public | ||||
|         unless @stream_entry.hidden? | ||||
|           request.session_options[:skip] = true | ||||
|           expires_in(3.minutes, public: true) | ||||
|         render_cached_json(['activitypub', 'note', @status.cache_key], content_type: 'application/activity+json') do | ||||
|           ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::NoteSerializer, adapter: ActivityPub::Adapter) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def activity | ||||
|     render json: @status, | ||||
|            serializer: ActivityPub::ActivitySerializer, | ||||
|            adapter: ActivityPub::Adapter, | ||||
|            content_type: 'application/activity+json' | ||||
|     skip_session! | ||||
| 
 | ||||
|     render_cached_json(['activitypub', 'activity', @status.cache_key], content_type: 'application/activity+json') do | ||||
|       ActiveModelSerializers::SerializableResource.new(@status, serializer: ActivityPub::ActivitySerializer, adapter: ActivityPub::Adapter) | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def embed | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user