From 6697d8a097044d88da477a4f3effee936b1e80cd Mon Sep 17 00:00:00 2001
From: Sebastian Gierlinger <s.gierlinger@me.com>
Date: Tue, 24 Sep 2013 17:21:43 +0200
Subject: [PATCH] Add invalidate cache headers

closes #570
- added X-Cach-Invalidate headers for PUT, POST, DELETE requests
---
 core/server/api.js               | 37 +++++++++++++++++++++++++++++++-
 core/server/controllers/admin.js |  6 ++++++
 2 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/core/server/api.js b/core/server/api.js
index 5611a27681..41e73da570 100644
--- a/core/server/api.js
+++ b/core/server/api.js
@@ -81,7 +81,14 @@ posts = {
         }
 
         return canThis(this.user).remove.post(args.id).then(function () {
-            return dataProvider.Post.destroy(args.id);
+            return when(posts.read({id : args.id})).then(function (result) {
+                return dataProvider.Post.destroy(args.id).then(function () {
+                    var deletedObj = {};
+                    deletedObj.id = result.attributes.id;
+                    deletedObj.slug = result.attributes.slug;
+                    return deletedObj;
+                });
+            });
         }, function () {
             return when.reject("You do not have permission to remove posts.");
         });
@@ -301,6 +308,33 @@ settings = {
 
 // ## Request Handlers
 
+function invalidateCache(req, res, result) {
+    var parsedUrl = req._parsedUrl.pathname.replace(/\/$/, '').split('/'),
+        method = req.method,
+        endpoint = parsedUrl[3],
+        id = parsedUrl[4],
+        cacheInvalidate;
+    if (method === 'POST' || method === 'PUT' || method === 'DELETE') {
+        if (endpoint === 'settings' || endpoint === 'users') {
+            cacheInvalidate = "/*";
+        } else if (endpoint === 'posts') {
+            cacheInvalidate = "/, /page/*, /rss/, /rss/*";
+            if (id) {
+                if (result.toJSON) {
+                    cacheInvalidate += ', /' + result.toJSON().slug;
+                } else {
+                    cacheInvalidate += ', /' + result.slug;
+                }
+            }
+        }
+        if (cacheInvalidate) {
+            res.set({
+                "X-Cache-Invalidate": cacheInvalidate
+            });
+        }
+    }
+}
+
 // ### requestHandler
 // decorator for api functions which are called via an HTTP request
 // takes the API method and wraps it so that it gets data from the request and returns a sensible JSON response
@@ -312,6 +346,7 @@ requestHandler = function (apiMethod) {
             };
 
         return apiMethod.call(apiContext, options).then(function (result) {
+            invalidateCache(req, res, result);
             res.json(result || {});
         }, function (error) {
             error = {error: _.isString(error) ? error : (_.isObject(error) ? error.message : 'Unknown API Error')};
diff --git a/core/server/controllers/admin.js b/core/server/controllers/admin.js
index 32f2db72c1..78661c3ad1 100644
--- a/core/server/controllers/admin.js
+++ b/core/server/controllers/admin.js
@@ -369,6 +369,9 @@ adminControllers = {
 
                     return api.notifications.add(notification).then(function () {
                         delete req.session.user;
+                        res.set({
+                            "X-Cache-Invalidate": "/*"
+                        });
                         res.redirect('/ghost/signin/');
                     });
 
@@ -399,6 +402,9 @@ adminControllers = {
 
                     return api.notifications.add(notification).then(function () {
                         delete req.session.user;
+                        res.set({
+                            "X-Cache-Invalidate": "/*"
+                        });
                         res.redirect('/ghost/signup/');
                     });
                 }, function resetFailure(error) {