From 44fc8e42dc1b2427c16bf2d5d93c9b79f4d2b24c Mon Sep 17 00:00:00 2001
From: Sam <sam.saffron@gmail.com>
Date: Thu, 21 May 2015 17:05:22 +1000
Subject: [PATCH] nginx is stripping ETags, just use last modified instead

---
 .../site_customizations_controller.rb         | 12 ++++++--
 app/controllers/stylesheets_controller.rb     | 29 ++++++++++++-------
 2 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/app/controllers/site_customizations_controller.rb b/app/controllers/site_customizations_controller.rb
index 46af82b035b..e86fac11d0b 100644
--- a/app/controllers/site_customizations_controller.rb
+++ b/app/controllers/site_customizations_controller.rb
@@ -2,13 +2,19 @@ class SiteCustomizationsController < ApplicationController
   skip_before_filter :preload_json, :check_xhr, :redirect_to_login_if_required
 
   def show
-    version = params["v"]
+    cache_time = request.env["HTTP_IF_MODIFIED_SINCE"]
+    cache_time = Time.rfc2822(cache_time) rescue nil if cache_time
+    stylesheet_time = SiteCustomization.where(key: params[:key].to_s).pluck(:created_at).first
 
-    if version && version == request.headers['If-None-Match']
+    if !stylesheet_time
+      raise Discourse::NotFound
+    end
+
+    if cache_time && stylesheet_time <= cache_time
       return render nothing: true, status: 304
     end
 
-    response.headers["ETag"] = version if version
+    response.headers["Last-Modified"] = stylesheet_time.httpdate
     expires_in 1.year, public: true
     render text: SiteCustomization.stylesheet_contents(params[:key], params[:target] == "mobile" ? :mobile : :desktop),
            content_type: "text/css"
diff --git a/app/controllers/stylesheets_controller.rb b/app/controllers/stylesheets_controller.rb
index cec57ddcba0..97b9f2b4984 100644
--- a/app/controllers/stylesheets_controller.rb
+++ b/app/controllers/stylesheets_controller.rb
@@ -5,24 +5,31 @@ class StylesheetsController < ApplicationController
 
     target,digest = params[:name].split("_")
     digest_orig = digest
+    digest = "_" + digest if digest
 
-    if digest_orig && digest_orig == request.headers['If-None-Match']
-      return render nothing: true, status: 304
+    cache_time = request.env["HTTP_IF_MODIFIED_SINCE"]
+    cache_time = Time.rfc2822(cache_time) rescue nil if cache_time
+
+    query = StylesheetCache.where(target: target)
+    if digest
+      query = query.where(digest: digest_orig)
+    else
+      query = query.order('id desc')
     end
 
-    digest = "_" + digest if digest
+    stylesheet_time = query.pluck(:created_at).first
+    if !stylesheet_time
+      return render nothing: true, status: 404
+    end
+
+    if cache_time && stylesheet_time && stylesheet_time <= cache_time
+      return render nothing: true, status: 304
+    end
 
     # Security note, safe due to route constraint
     location = "#{Rails.root}/#{DiscourseStylesheets::CACHE_PATH}/#{target}#{digest}.css"
 
     unless File.exist?(location)
-      query = StylesheetCache.where(target: target)
-      if digest
-        query = query.where(digest: digest_orig)
-      else
-        query = query.order('id desc')
-      end
-
       if current = query.first
         File.write(location, current.content)
       else
@@ -30,7 +37,7 @@ class StylesheetsController < ApplicationController
       end
     end
 
-    response.headers['ETag'] = digest_orig if digest_orig
+    response.headers['Last-Modified'] = stylesheet_time.httpdate
     expires_in 1.year, public: true unless Rails.env == "development"
     send_file(location, disposition: :inline)