FEATURE: move stylesheet cache out of the uploads directory

This commit is contained in:
Sam 2015-05-05 15:50:13 +10:00
parent 8e372f3616
commit f58d85edea
8 changed files with 105 additions and 6 deletions

View File

@ -0,0 +1,33 @@
class StylesheetsController < ApplicationController
skip_before_filter :preload_json, :redirect_to_login_if_required, :check_xhr, :verify_authenticity_token, only: [:show]
def show
target,digest = params[:name].split("_")
digest = "_" + digest if digest
# Security note, safe due to route constraint
location = "#{DiscourseStylesheets::CACHE_PATH}/#{target}#{digest}.css"
unless File.exist?(location)
query = StylesheetCache.where(target: target)
if digest
query = query.where(digest: digest)
else
query = query.order('id desc')
end
if current = query.first
File.write(location, current.content)
else
return render nothing: true, status: 404
end
end
expires_in 1.year, public: true unless Rails.env == "development"
send_file(location, disposition: :inline)
end
end

View File

@ -0,0 +1,25 @@
class StylesheetCache < ActiveRecord::Base
self.table_name = 'stylesheet_cache'
MAX_TO_KEEP = 10
def self.add(target,digest,content)
success = create(target: target, digest: digest, content: content)
count = StylesheetCache.count
if count > MAX_TO_KEEP
remove_lower = StylesheetCache.limit(MAX_TO_KEEP)
.order('id desc')
.pluck(:id)
.last
exec_sql("DELETE FROM stylesheet_cache where id < :id", id: remove_lower)
end
success
rescue ActiveRecord::RecordNotUnique
false
end
end

View File

@ -33,7 +33,8 @@ if defined?(Rack::MiniProfiler)
/^\/site_customizations/,
/^\/uploads/,
/^\/javascripts\//,
/^\/images\//
/^\/images\//,
/^\/stylesheets\//
]
# For our app, let's just show mini profiler always, polling is chatty so nuke that

View File

@ -158,7 +158,7 @@ server {
# This big block is needed so we can selectively enable
# acceleration for backups and avatars
# see note about repetition above
location ~ ^/(letter_avatar|user_avatar|highlight-js) {
location ~ ^/(letter_avatar|user_avatar|highlight-js|stylesheets) {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

View File

@ -287,6 +287,8 @@ Discourse::Application.routes.draw do
get "highlight-js/:hostname/:version.js" => "highlight_js#show", format: false, constraints: { hostname: /[\w\.-]+/ }
get "stylesheets/:name.css" => "stylesheets#show", constraints: {name: /[a-z0-9_]+/}
get "uploads/:site/:id/:sha.:extension" => "uploads#show", constraints: {site: /\w+/, id: /\d+/, sha: /[a-z0-9]{15,16}/i, extension: /\w{2,}/}
get "uploads/:site/:sha" => "uploads#show", constraints: { site: /\w+/, sha: /[a-z0-9]{40}/}
post "uploads" => "uploads#create"

View File

@ -0,0 +1,12 @@
class AddStylesheetCache < ActiveRecord::Migration
def change
create_table :stylesheet_cache do |t|
t.string :target, null: false
t.string :digest, null: false
t.text :content, null: false
t.timestamps
end
add_index :stylesheet_cache, [:target, :digest], unique: true
end
end

View File

@ -3,7 +3,7 @@ require_dependency 'distributed_cache'
class DiscourseStylesheets
CACHE_PATH ||= 'uploads/stylesheet-cache'
CACHE_PATH ||= 'tmp/stylesheet-cache'
MANIFEST_DIR ||= "#{Rails.root}/tmp/cache/assets/#{Rails.env}"
MANIFEST_FULL_PATH ||= "#{MANIFEST_DIR}/stylesheet-manifest"
@ -89,6 +89,7 @@ class DiscourseStylesheets
File.open(stylesheet_fullpath, "w") do |f|
f.puts css
end
StylesheetCache.add(@target, digest, css)
css
end
@ -100,7 +101,7 @@ class DiscourseStylesheets
end
def cache_fullpath
"#{Rails.root}/public/#{CACHE_PATH}"
"#{Rails.root}/#{CACHE_PATH}"
end
def stylesheet_fullpath
@ -118,12 +119,13 @@ class DiscourseStylesheets
"#{GlobalSetting.relative_url_root}/"
end
# using uploads cause we already have all the routing in place
def stylesheet_relpath
"#{root_path}#{CACHE_PATH}/#{stylesheet_filename}"
"#{root_path}stylesheets/#{stylesheet_filename}"
end
def stylesheet_relpath_no_digest
"#{root_path}#{CACHE_PATH}/#{stylesheet_filename_no_digest}"
"#{root_path}stylesheets/#{stylesheet_filename_no_digest}"
end
def stylesheet_filename

View File

@ -0,0 +1,24 @@
require 'spec_helper'
describe StylesheetCache do
describe "add" do
it "correctly cycles once MAX_TO_KEEP is hit" do
(StylesheetCache::MAX_TO_KEEP + 1).times do |i|
StylesheetCache.add(i.to_s, "d" + i.to_s, "c" + i.to_s)
end
expect(StylesheetCache.count).to eq StylesheetCache::MAX_TO_KEEP
expect(StylesheetCache.order(:id).first.content).to eq "c1"
end
it "does nothing if digest is set and already exists" do
StylesheetCache.add("a", "b", "c")
StylesheetCache.add("a", "b", "cc")
expect(StylesheetCache.count).to eq 1
expect(StylesheetCache.first.content).to eq "c"
end
end
end