Bug 917432 - hook to webapps-clear-data notification, r=michal
authorHonza Bambas <honzab.moz@firemni.cz>
Wed, 20 Nov 2013 23:20:16 +0100
changeset 165731 66a063b14ddbfd82e8029d12a3577c72927d9d5d
parent 165730 3591be35378653dcecab524c10d495a3c808389a
child 165732 2b59776ddb86f3a3638e88884b39bea684b3b31f
push idunknown
push userunknown
push dateunknown
reviewersmichal
bugs917432
milestone28.0a1
Bug 917432 - hook to webapps-clear-data notification, r=michal
netwerk/build/nsNetModule.cpp
netwerk/cache2/AppCacheStorage.cpp
netwerk/cache2/CacheObserver.cpp
netwerk/cache2/CacheStorage.cpp
netwerk/cache2/OldWrappers.cpp
netwerk/cache2/OldWrappers.h
netwerk/protocol/http/nsHttpHandler.cpp
netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp
netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.h
--- a/netwerk/build/nsNetModule.cpp
+++ b/netwerk/build/nsNetModule.cpp
@@ -264,17 +264,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsViewSou
 #endif
 
 #ifdef NECKO_PROTOCOL_data
 #include "nsDataHandler.h"
 #endif
 
 #ifdef NECKO_PROTOCOL_wyciwyg
 #include "nsWyciwygProtocolHandler.h"
-NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWyciwygProtocolHandler, Init)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsWyciwygProtocolHandler)
 #endif
 
 #ifdef NECKO_PROTOCOL_websocket
 #include "WebSocketChannel.h"
 #include "WebSocketChannelChild.h"
 namespace mozilla {
 namespace net {
 static BaseWebSocketChannel*
--- a/netwerk/cache2/AppCacheStorage.cpp
+++ b/netwerk/cache2/AppCacheStorage.cpp
@@ -66,18 +66,22 @@ NS_IMETHODIMP AppCacheStorage::AsyncOpen
   nsCOMPtr<nsIURI> noRefURI;
   rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString cacheKey;
   rv = noRefURI->GetAsciiSpec(cacheKey);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  nsAutoCString scheme;
+  rv = noRefURI->GetScheme(scheme);
+  NS_ENSURE_SUCCESS(rv, rv);
+
   nsRefPtr<_OldCacheLoad> appCacheLoad =
-    new _OldCacheLoad(cacheKey, aCallback, appCache,
+    new _OldCacheLoad(scheme, cacheKey, aCallback, appCache,
                       LoadInfo(), WriteToDisk(), aFlags);
   rv = appCacheLoad->Start();
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP AppCacheStorage::AsyncDoomURI(nsIURI *aURI, const nsACString & aIdExtension,
--- a/netwerk/cache2/CacheObserver.cpp
+++ b/netwerk/cache2/CacheObserver.cpp
@@ -1,17 +1,20 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CacheObserver.h"
 
 #include "CacheStorageService.h"
 #include "CacheFileIOManager.h"
+#include "LoadContextInfo.h"
+#include "nsICacheStorage.h"
 #include "nsIObserverService.h"
+#include "mozIApplicationClearPrivateDataParams.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 #include "nsServiceManagerUtils.h"
 
 namespace mozilla {
 namespace net {
 
 CacheObserver* CacheObserver::sSelf = nullptr;
@@ -41,16 +44,17 @@ CacheObserver::Init()
   sSelf = new CacheObserver();
   NS_ADDREF(sSelf);
 
   obs->AddObserver(sSelf, "prefservice:after-app-defaults", true);
   obs->AddObserver(sSelf, "profile-do-change", true);
   obs->AddObserver(sSelf, "profile-before-change", true);
   obs->AddObserver(sSelf, "xpcom-shutdown", true);
   obs->AddObserver(sSelf, "last-pb-context-exited", true);
+  obs->AddObserver(sSelf, "webapps-clear-data", true);
   obs->AddObserver(sSelf, "memory-pressure", true);
 
   return NS_OK;
 }
 
 nsresult
 CacheObserver::Shutdown()
 {
@@ -86,16 +90,93 @@ bool const CacheObserver::UseNewCache()
       static bool const sABTest = rand() & 1;
       return sABTest;
     }
   }
 
   return true;
 }
 
+namespace { // anon
+
+class CacheStorageEvictHelper
+{
+public:
+  nsresult Run(mozIApplicationClearPrivateDataParams* aParams);
+
+private:
+  uint32_t mAppId;
+  nsresult ClearStorage(bool const aPrivate,
+                        bool const aInBrowser,
+                        bool const aAnonymous);
+};
+
+nsresult
+CacheStorageEvictHelper::Run(mozIApplicationClearPrivateDataParams* aParams)
+{
+  nsresult rv;
+
+  rv = aParams->GetAppId(&mAppId);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool aBrowserOnly;
+  rv = aParams->GetBrowserOnly(&aBrowserOnly);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  MOZ_ASSERT(mAppId != nsILoadContextInfo::UNKNOWN_APP_ID);
+
+  // Clear all [private X anonymous] combinations
+  rv = ClearStorage(false, aBrowserOnly, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = ClearStorage(false, aBrowserOnly, true);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = ClearStorage(true, aBrowserOnly, false);
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = ClearStorage(true, aBrowserOnly, true);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  return NS_OK;
+}
+
+nsresult
+CacheStorageEvictHelper::ClearStorage(bool const aPrivate,
+                                      bool const aInBrowser,
+                                      bool const aAnonymous)
+{
+  nsresult rv;
+
+  nsRefPtr<LoadContextInfo> info = GetLoadContextInfo(
+    aPrivate, mAppId, aInBrowser, aAnonymous);
+
+  nsCOMPtr<nsICacheStorage> storage;
+  nsRefPtr<CacheStorageService> service = CacheStorageService::Self();
+  NS_ENSURE_TRUE(service, NS_ERROR_FAILURE);
+
+  // Clear disk storage
+  rv = service->DiskCacheStorage(info, false, getter_AddRefs(storage));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = storage->AsyncEvictStorage(nullptr);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Clear memory storage
+  rv = service->MemoryCacheStorage(info, getter_AddRefs(storage));
+  NS_ENSURE_SUCCESS(rv, rv);
+  rv = storage->AsyncEvictStorage(nullptr);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!aInBrowser) {
+    rv = ClearStorage(aPrivate, true, aAnonymous);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
+  return NS_OK;
+}
+
+} // anon
+
 NS_IMETHODIMP
 CacheObserver::Observe(nsISupports* aSubject,
                        const char* aTopic,
                        const PRUnichar* aData)
 {
   if (!strcmp(aTopic, "prefservice:after-app-defaults")) {
     CacheFileIOManager::Init();
     return NS_OK;
@@ -128,16 +209,31 @@ CacheObserver::Observe(nsISupports* aSub
   if (!strcmp(aTopic, "last-pb-context-exited")) {
     nsRefPtr<CacheStorageService> service = CacheStorageService::Self();
     if (service)
       service->DropPrivateBrowsingEntries();
 
     return NS_OK;
   }
 
+  if (!strcmp(aTopic, "webapps-clear-data")) {
+    nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
+            do_QueryInterface(aSubject);
+    if (!params) {
+      NS_ERROR("'webapps-clear-data' notification's subject should be a mozIApplicationClearPrivateDataParams");
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    CacheStorageEvictHelper helper;
+    nsresult rv = helper.Run(params);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return NS_OK;
+  }
+
   if (!strcmp(aTopic, "memory-pressure")) {
     nsRefPtr<CacheStorageService> service = CacheStorageService::Self();
     if (service)
       service->PurgeFromMemory(nsICacheStorageService::PURGE_EVERYTHING);
 
     return NS_OK;
   }
 
--- a/netwerk/cache2/CacheStorage.cpp
+++ b/netwerk/cache2/CacheStorage.cpp
@@ -62,18 +62,22 @@ NS_IMETHODIMP CacheStorage::AsyncOpenURI
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (appCache) {
     nsAutoCString cacheKey;
     rv = noRefURI->GetAsciiSpec(cacheKey);
     NS_ENSURE_SUCCESS(rv, rv);
 
+    nsAutoCString scheme;
+    rv = noRefURI->GetScheme(scheme);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     nsRefPtr<_OldCacheLoad> appCacheLoad =
-      new _OldCacheLoad(cacheKey, aCallback, appCache,
+      new _OldCacheLoad(scheme, cacheKey, aCallback, appCache,
                         LoadInfo(), WriteToDisk(), aFlags);
     rv = appCacheLoad->Start();
     NS_ENSURE_SUCCESS(rv, rv);
 
     LOG(("CacheStorage::AsyncOpenURI loading from appcache"));
     return NS_OK;
   }
 
--- a/netwerk/cache2/OldWrappers.cpp
+++ b/netwerk/cache2/OldWrappers.cpp
@@ -356,47 +356,88 @@ NS_IMETHODIMP _OldCacheEntryWrapper::Has
   LOG(("_OldCacheEntryWrapper::HasWriteAccess [this=%p, write-access=%d]", this, *aWriteAccess));
 
   return NS_OK;
 }
 
 
 namespace { // anon
 
-void
+nsresult
 GetCacheSessionNameForStoragePolicy(
+        nsCSubstring const &scheme,
         nsCacheStoragePolicy storagePolicy,
         bool isPrivate,
         uint32_t appId,
         bool inBrowser,
         nsACString& sessionName)
 {
   MOZ_ASSERT(!isPrivate || storagePolicy == nsICache::STORE_IN_MEMORY);
 
-  switch (storagePolicy) {
+  // HTTP
+  if (scheme.Equals(NS_LITERAL_CSTRING("http")) ||
+      scheme.Equals(NS_LITERAL_CSTRING("https"))) {
+    switch (storagePolicy) {
     case nsICache::STORE_IN_MEMORY:
-      sessionName.AssignASCII(isPrivate ? "HTTP-memory-only-PB" : "HTTP-memory-only");
+      if (isPrivate)
+        sessionName.Assign(NS_LITERAL_CSTRING("HTTP-memory-only-PB"));
+      else
+        sessionName.Assign(NS_LITERAL_CSTRING("HTTP-memory-only"));
       break;
     case nsICache::STORE_OFFLINE:
-      sessionName.AssignLiteral("HTTP-offline");
+      // XXX This is actually never used, only added to prevent
+      // any compatibility damage.
+      sessionName.Assign(NS_LITERAL_CSTRING("HTTP-offline"));
       break;
     default:
-      sessionName.AssignLiteral("HTTP");
+      sessionName.Assign(NS_LITERAL_CSTRING("HTTP"));
       break;
+    }
   }
+  // WYCIWYG
+  else if (scheme.Equals(NS_LITERAL_CSTRING("wyciwyg"))) {
+    if (isPrivate)
+      sessionName.Assign(NS_LITERAL_CSTRING("wyciwyg-private"));
+    else
+      sessionName.Assign(NS_LITERAL_CSTRING("wyciwyg"));
+  }
+  // FTP
+  else if (scheme.Equals(NS_LITERAL_CSTRING("ftp"))) {
+    if (isPrivate)
+      sessionName.Assign(NS_LITERAL_CSTRING("FTP-private"));
+    else
+      sessionName.Assign(NS_LITERAL_CSTRING("FTP"));
+  }
+  // all remaining URL scheme
+  else {
+    // Since with the new API a consumer cannot specify its own session name
+    // and partitioning of the cache is handled stricly only by the cache
+    // back-end internally, we will use a separate session name to pretend
+    // functionality of the new API wrapping the Darin's cache for all other
+    // URL schemes.
+    // Deliberately omitting |anonymous| since other session types don't
+    // recognize it too.
+    sessionName.Assign(NS_LITERAL_CSTRING("other"));
+    if (isPrivate)
+      sessionName.Append(NS_LITERAL_CSTRING("-private"));
+  }
+
   if (appId != nsILoadContextInfo::NO_APP_ID || inBrowser) {
     sessionName.Append('~');
     sessionName.AppendInt(appId);
     sessionName.Append('~');
     sessionName.AppendInt(inBrowser);
   }
+
+  return NS_OK;
 }
 
 nsresult
-GetCacheSession(bool aWriteToDisk,
+GetCacheSession(nsCSubstring const &aScheme,
+                bool aWriteToDisk,
                 nsILoadContextInfo* aLoadInfo,
                 nsIApplicationCache* aAppCache,
                 nsICacheSession** _result)
 {
   nsresult rv;
 
   nsCacheStoragePolicy storagePolicy;
   if (aAppCache)
@@ -406,22 +447,24 @@ GetCacheSession(bool aWriteToDisk,
   else
     storagePolicy = nsICache::STORE_ANYWHERE;
 
   nsAutoCString clientId;
   if (aAppCache) {
     aAppCache->GetClientID(clientId);
   }
   else {
-    GetCacheSessionNameForStoragePolicy(
+    rv = GetCacheSessionNameForStoragePolicy(
+      aScheme,
       storagePolicy,
       aLoadInfo->IsPrivate(),
       aLoadInfo->AppId(),
       aLoadInfo->IsInBrowserElement(),
       clientId);
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   LOG(("  GetCacheSession for client=%s, policy=%d", clientId.get(), storagePolicy));
 
   nsCOMPtr<nsICacheService> serv =
       do_GetService(NS_CACHESERVICE_CONTRACTID, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -450,23 +493,25 @@ GetCacheSession(bool aWriteToDisk,
   return NS_OK;
 }
 
 } // anon
 
 
 NS_IMPL_ISUPPORTS_INHERITED1(_OldCacheLoad, nsRunnable, nsICacheListener)
 
-_OldCacheLoad::_OldCacheLoad(nsCSubstring const& aCacheKey,
+_OldCacheLoad::_OldCacheLoad(nsCSubstring const& aScheme,
+                             nsCSubstring const& aCacheKey,
                              nsICacheEntryOpenCallback* aCallback,
                              nsIApplicationCache* aAppCache,
                              nsILoadContextInfo* aLoadInfo,
                              bool aWriteToDisk,
                              uint32_t aFlags)
-  : mCacheKey(aCacheKey)
+  : mScheme(aScheme)
+  , mCacheKey(aCacheKey)
   , mCallback(aCallback)
   , mLoadInfo(GetLoadContextInfo(aLoadInfo))
   , mFlags(aFlags)
   , mWriteToDisk(aWriteToDisk)
   , mMainThreadOnly(true)
   , mNew(true)
   , mStatus(NS_ERROR_UNEXPECTED)
   , mRunCount(0)
@@ -523,17 +568,18 @@ NS_IMETHODIMP
 _OldCacheLoad::Run()
 {
   LOG(("_OldCacheLoad::Run [this=%p, key=%s, cb=%p]", this, mCacheKey.get(), mCallback.get()));
 
   nsresult rv;
 
   if (!NS_IsMainThread()) {
     nsCOMPtr<nsICacheSession> session;
-    rv = GetCacheSession(mWriteToDisk, mLoadInfo, mAppCache, getter_AddRefs(session));
+    rv = GetCacheSession(mScheme, mWriteToDisk, mLoadInfo, mAppCache,
+                         getter_AddRefs(session));
     if (NS_SUCCEEDED(rv)) {
       // AsyncOpenCacheEntry isn't really async when its called on the
       // cache service thread.
 
       nsCacheAccessMode cacheAccess;
       if (mFlags & nsICacheStorage::OPEN_TRUNCATE)
         cacheAccess = nsICache::ACCESS_WRITE;
       else if ((mFlags & nsICacheStorage::OPEN_READONLY) || mAppCache)
@@ -692,53 +738,54 @@ NS_IMETHODIMP _OldStorage::AsyncOpenURI(
   nsAutoCString uriSpec;
   aURI->GetAsciiSpec(uriSpec);
   LOG(("_OldStorage::AsyncOpenURI [this=%p, uri=%s, ide=%s, flags=%x]",
     this, uriSpec.get(), aIdExtension.BeginReading(), aFlags));
 #endif
 
   nsresult rv;
 
-  nsAutoCString cacheKey;
-  rv = AssembleCacheKey(aURI, aIdExtension, cacheKey);
+  nsAutoCString cacheKey, scheme;
+  rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mAppCache && (mLookupAppCache || mOfflineStorage)) {
     rv = ChooseApplicationCache(cacheKey, getter_AddRefs(mAppCache));
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (mAppCache) {
       // From a chosen appcache open only as readonly
       aFlags &= ~nsICacheStorage::OPEN_TRUNCATE;
     }
   }
 
   nsRefPtr<_OldCacheLoad> cacheLoad =
-    new _OldCacheLoad(cacheKey, aCallback, mAppCache,
+    new _OldCacheLoad(scheme, cacheKey, aCallback, mAppCache,
                       mLoadInfo, mWriteToDisk, aFlags);
 
   rv = cacheLoad->Start();
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
 NS_IMETHODIMP _OldStorage::AsyncDoomURI(nsIURI *aURI, const nsACString & aIdExtension,
                                         nsICacheEntryDoomCallback* aCallback)
 {
   LOG(("_OldStorage::AsyncDoomURI"));
 
   nsresult rv;
 
-  nsAutoCString cacheKey;
-  rv = AssembleCacheKey(aURI, aIdExtension, cacheKey);
+  nsAutoCString cacheKey, scheme;
+  rv = AssembleCacheKey(aURI, aIdExtension, cacheKey, scheme);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsCOMPtr<nsICacheSession> session;
-  rv = GetCacheSession(mWriteToDisk, mLoadInfo, mAppCache, getter_AddRefs(session));
+  rv = GetCacheSession(scheme, mWriteToDisk, mLoadInfo, mAppCache,
+                       getter_AddRefs(session));
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsRefPtr<DoomCallbackWrapper> cb = aCallback
     ? new DoomCallbackWrapper(aCallback)
     : nullptr;
   rv = session->DoomEntry(cacheKey, cb);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -771,22 +818,54 @@ NS_IMETHODIMP _OldStorage::AsyncEvictSto
       NS_ENSURE_SUCCESS(rv, rv);
 
       rv = appCacheService->DiscardByAppId(mLoadInfo->AppId(),
                                            mLoadInfo->IsInBrowserElement());
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   else {
-    nsCOMPtr<nsICacheSession> session;
-    rv = GetCacheSession(mWriteToDisk, mLoadInfo, mAppCache, getter_AddRefs(session));
-    NS_ENSURE_SUCCESS(rv, rv);
+    if (mAppCache) {
+      nsCOMPtr<nsICacheSession> session;
+      rv = GetCacheSession(EmptyCString(),
+                           mWriteToDisk, mLoadInfo, mAppCache,
+                           getter_AddRefs(session));
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = session->EvictEntries();
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+    else {
+      // Oh, I'll be so happy when session names are gone...
+      nsCOMPtr<nsICacheSession> session;
+      rv = GetCacheSession(NS_LITERAL_CSTRING("http"),
+                           mWriteToDisk, mLoadInfo, mAppCache,
+                           getter_AddRefs(session));
+      NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = session->EvictEntries();
-    NS_ENSURE_SUCCESS(rv, rv);
+      rv = session->EvictEntries();
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = GetCacheSession(NS_LITERAL_CSTRING("wyciwyg"),
+                           mWriteToDisk, mLoadInfo, mAppCache,
+                           getter_AddRefs(session));
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = session->EvictEntries();
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      // This clears any data from scheme other then http, wyciwyg or ftp
+      rv = GetCacheSession(EmptyCString(),
+                           mWriteToDisk, mLoadInfo, mAppCache,
+                           getter_AddRefs(session));
+      NS_ENSURE_SUCCESS(rv, rv);
+
+      rv = session->EvictEntries();
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
   }
 
   if (aCallback) {
     nsRefPtr<DoomCallbackSynchronizer> sync =
       new DoomCallbackSynchronizer(aCallback);
     rv = sync->Dispatch();
     NS_ENSURE_SUCCESS(rv, rv);
   }
@@ -836,43 +915,59 @@ NS_IMETHODIMP _OldStorage::AsyncVisitSto
 
   return NS_OK;
 }
 
 // Internal
 
 nsresult _OldStorage::AssembleCacheKey(nsIURI *aURI,
                                        nsACString const & aIdExtension,
-                                       nsACString & aCacheKey)
+                                       nsACString & aCacheKey,
+                                       nsACString & aScheme)
 {
   // Copied from nsHttpChannel::AssembleCacheKey
 
   aCacheKey.Truncate();
 
-  if (mLoadInfo->IsAnonymous()) {
-    aCacheKey.AssignLiteral("anon&");
-  }
-
-  if (!aIdExtension.IsEmpty()) {
-    aCacheKey.AppendPrintf("id=%s&", aIdExtension.BeginReading());
-  }
-
   nsresult rv;
 
-  nsCOMPtr<nsIURI> noRefURI;
-  rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+  rv = aURI->GetScheme(aScheme);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString uriSpec;
-  rv = noRefURI->GetAsciiSpec(uriSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
+  if (aScheme.Equals(NS_LITERAL_CSTRING("http")) ||
+      aScheme.Equals(NS_LITERAL_CSTRING("https"))) {
+    if (mLoadInfo->IsAnonymous()) {
+      aCacheKey.AssignLiteral("anon&");
+    }
+
+    if (!aIdExtension.IsEmpty()) {
+      aCacheKey.AppendPrintf("id=%s&", aIdExtension.BeginReading());
+    }
+
+    nsCOMPtr<nsIURI> noRefURI;
+    rv = aURI->CloneIgnoringRef(getter_AddRefs(noRefURI));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!aCacheKey.IsEmpty()) {
-    aCacheKey.AppendLiteral("uri=");
+    rv = noRefURI->GetAsciiSpec(uriSpec);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    if (!aCacheKey.IsEmpty()) {
+      aCacheKey.AppendLiteral("uri=");
+    }
   }
+  else if (aScheme.Equals(NS_LITERAL_CSTRING("wyciwyg"))) {
+    rv = aURI->GetSpec(uriSpec);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  else {
+    rv = aURI->GetAsciiSpec(uriSpec);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   aCacheKey.Append(uriSpec);
 
   return NS_OK;
 }
 
 nsresult _OldStorage::ChooseApplicationCache(nsCSubstring const &cacheKey,
                                              nsIApplicationCache** aCache)
 {
--- a/netwerk/cache2/OldWrappers.h
+++ b/netwerk/cache2/OldWrappers.h
@@ -56,31 +56,33 @@ private:
 class _OldCacheLoad : public nsRunnable
                     , public nsICacheListener
 {
 public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIRUNNABLE
   NS_DECL_NSICACHELISTENER
 
-  _OldCacheLoad(nsCSubstring const& aCacheKey,
+  _OldCacheLoad(nsCSubstring const& aScheme,
+                nsCSubstring const& aCacheKey,
                 nsICacheEntryOpenCallback* aCallback,
                 nsIApplicationCache* aAppCache,
                 nsILoadContextInfo* aLoadInfo,
                 bool aWriteToDisk,
                 uint32_t aFlags);
   virtual ~_OldCacheLoad();
 
   nsresult Start();
 
 private:
   void Check();
 
   nsCOMPtr<nsIEventTarget> mCacheThread;
 
+  nsCString mScheme;
   nsCString mCacheKey;
   nsCOMPtr<nsICacheEntryOpenCallback> mCallback;
   nsCOMPtr<nsILoadContextInfo> mLoadInfo;
   uint32_t mFlags;
 
   bool const mWriteToDisk : 1;
   bool mMainThreadOnly : 1;
   bool mNew : 1;
@@ -103,17 +105,18 @@ public:
   _OldStorage(nsILoadContextInfo* aInfo,
               bool aAllowDisk,
               bool aLookupAppCache,
               bool aOfflineStorage,
               nsIApplicationCache* aAppCache);
 
 private:
   virtual ~_OldStorage();
-  nsresult AssembleCacheKey(nsIURI *aURI, nsACString const & aIdExtension, nsACString & _result);
+  nsresult AssembleCacheKey(nsIURI *aURI, nsACString const & aIdExtension,
+                            nsACString & aCacheKey, nsACString & aScheme);
   nsresult ChooseApplicationCache(nsCSubstring const &cacheKey, nsIApplicationCache** aCache);
 
   nsCOMPtr<nsILoadContextInfo> mLoadInfo;
   nsCOMPtr<nsIApplicationCache> mAppCache;
   bool const mWriteToDisk : 1;
   bool const mLookupAppCache : 1;
   bool const mOfflineStorage : 1;
 };
--- a/netwerk/protocol/http/nsHttpHandler.cpp
+++ b/netwerk/protocol/http/nsHttpHandler.cpp
@@ -15,18 +15,16 @@
 #include "nsIDOMConnection.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMNavigator.h"
 #include "nsIMozNavigatorNetwork.h"
 #include "nsINetworkProperties.h"
 #include "nsIHttpChannel.h"
 #include "nsIStandardURL.h"
 #include "LoadContextInfo.h"
-#include "nsICacheStorageService.h"
-#include "nsICacheStorage.h"
 #include "nsCategoryManagerUtils.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefLocalizedString.h"
 #include "nsISocketProviderService.h"
 #include "nsISocketProvider.h"
 #include "nsPrintfCString.h"
 #include "nsCOMPtr.h"
@@ -352,17 +350,16 @@ nsHttpHandler::Init()
     if (mObserverService) {
         mObserverService->AddObserver(this, "profile-change-net-teardown", true);
         mObserverService->AddObserver(this, "profile-change-net-restore", true);
         mObserverService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true);
         mObserverService->AddObserver(this, "net:clear-active-logins", true);
         mObserverService->AddObserver(this, "net:prune-dead-connections", true);
         mObserverService->AddObserver(this, "net:failed-to-process-uri-content", true);
         mObserverService->AddObserver(this, "last-pb-context-exited", true);
-        mObserverService->AddObserver(this, "webapps-clear-data", true);
     }
 
     MakeNewRequestTokenBucket();
     mWifiTickler = new Tickler();
     if (NS_FAILED(mWifiTickler->Init()))
         mWifiTickler = nullptr;
 
     return NS_OK;
@@ -1743,94 +1740,16 @@ nsHttpHandler::GetCacheSessionNameForSto
         sessionName.AppendInt(inBrowser);
     }
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpHandler::nsIObserver
 //-----------------------------------------------------------------------------
 
-namespace { // anon
-
-class CacheStorageEvictHelper
-{
-public:
-    CacheStorageEvictHelper(uint32_t appId, bool browserOnly)
-      : mAppId(appId), mBrowserOnly(browserOnly) { }
-
-    nsresult Run();
-
-private:
-    nsCOMPtr<nsICacheStorageService> mCacheStorageService;
-    uint32_t mAppId;
-    bool mBrowserOnly;
-
-    nsresult ClearStorage(bool const aPrivate,
-                          bool const aInBrowser,
-                          bool const aAnonymous);
-};
-
-nsresult
-CacheStorageEvictHelper::Run()
-{
-    nsresult rv;
-
-    mCacheStorageService = do_GetService(
-        "@mozilla.org/netwerk/cache-storage-service;1", &rv);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Clear all [private X anonymous] combinations
-    rv = ClearStorage(false, mBrowserOnly, false);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = ClearStorage(false, mBrowserOnly, true);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = ClearStorage(true, mBrowserOnly, false);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = ClearStorage(true, mBrowserOnly, true);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    return NS_OK;
-}
-
-nsresult
-CacheStorageEvictHelper::ClearStorage(bool const aPrivate,
-                                      bool const aInBrowser,
-                                      bool const aAnonymous)
-{
-    nsresult rv;
-
-    nsRefPtr<LoadContextInfo> info = GetLoadContextInfo(
-        aPrivate, mAppId, aInBrowser, aAnonymous);
-
-    nsCOMPtr<nsICacheStorage> storage;
-
-    // Clear disk storage
-    rv = mCacheStorageService->DiskCacheStorage(info, false,
-        getter_AddRefs(storage));
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = storage->AsyncEvictStorage(nullptr);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    // Clear memory storage
-    rv = mCacheStorageService->MemoryCacheStorage(info,
-        getter_AddRefs(storage));
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = storage->AsyncEvictStorage(nullptr);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    if (!aInBrowser) {
-        rv = ClearStorage(aPrivate, true, aAnonymous);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    return NS_OK;
-}
-
-} // anon
-
 NS_IMETHODIMP
 nsHttpHandler::Observe(nsISupports *subject,
                        const char *topic,
                        const PRUnichar *data)
 {
     LOG(("nsHttpHandler::Observe [topic=\"%s\"]\n", topic));
 
     if (strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
@@ -1873,37 +1792,16 @@ nsHttpHandler::Observe(nsISupports *subj
     else if (strcmp(topic, "net:failed-to-process-uri-content") == 0) {
         nsCOMPtr<nsIURI> uri = do_QueryInterface(subject);
         if (uri && mConnMgr)
             mConnMgr->ReportFailedToProcess(uri);
     }
     else if (strcmp(topic, "last-pb-context-exited") == 0) {
         mPrivateAuthCache.ClearAll();
     }
-    else if (strcmp(topic, "webapps-clear-data") == 0) {
-        nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
-                do_QueryInterface(subject);
-        if (!params) {
-            NS_ERROR("'webapps-clear-data' notification's subject should be a mozIApplicationClearPrivateDataParams");
-            return NS_ERROR_UNEXPECTED;
-        }
-
-        uint32_t appId;
-        bool browserOnly;
-        nsresult rv = params->GetAppId(&appId);
-        NS_ENSURE_SUCCESS(rv, rv);
-        rv = params->GetBrowserOnly(&browserOnly);
-        NS_ENSURE_SUCCESS(rv, rv);
-
-        MOZ_ASSERT(appId != NECKO_UNKNOWN_APP_ID);
-
-        CacheStorageEvictHelper helper(appId, browserOnly);
-        rv = helper.Run();
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
 
     return NS_OK;
 }
 
 // nsISpeculativeConnect
 
 NS_IMETHODIMP
 nsHttpHandler::SpeculativeConnect(nsIURI *aURI,
--- a/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp
+++ b/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.cpp
@@ -33,47 +33,16 @@ nsWyciwygProtocolHandler::nsWyciwygProto
   LOG(("Creating nsWyciwygProtocolHandler [this=%p].\n", this));
 }
 
 nsWyciwygProtocolHandler::~nsWyciwygProtocolHandler() 
 {
   LOG(("Deleting nsWyciwygProtocolHandler [this=%p]\n", this));
 }
 
-nsresult
-nsWyciwygProtocolHandler::Init()
-{
-  nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
-  if (obs) {
-    obs->AddObserver(this, "webapps-clear-data", true);
-  }
-  return NS_OK;
-}
-
-static void
-EvictCacheSession(uint32_t aAppId,
-                  bool aInBrowser,
-                  bool aPrivateBrowsing)
-{
-  nsAutoCString clientId;
-  nsWyciwygProtocolHandler::GetCacheSessionName(aAppId, aInBrowser,
-                                                aPrivateBrowsing,
-                                                clientId);
-  nsCOMPtr<nsICacheService> serv =
-      do_GetService(NS_CACHESERVICE_CONTRACTID);
-  nsCOMPtr<nsICacheSession> session;
-  nsresult rv = serv->CreateSession(clientId.get(),
-                                    nsICache::STORE_ANYWHERE,
-                                    nsICache::STREAM_BASED,
-                                    getter_AddRefs(session));
-  if (NS_SUCCEEDED(rv) && session) {
-    session->EvictEntries();
-  }
-}
-
 void
 nsWyciwygProtocolHandler::GetCacheSessionName(uint32_t aAppId,
                                               bool aInBrowser,
                                               bool aPrivateBrowsing,
                                               nsACString& aSessionName)
 {
   if (aPrivateBrowsing) {
     aSessionName.AssignLiteral("wyciwyg-private");
@@ -85,52 +54,18 @@ nsWyciwygProtocolHandler::GetCacheSessio
   }
 
   aSessionName.Append('~');
   aSessionName.AppendInt(aAppId);
   aSessionName.Append('~');
   aSessionName.AppendInt(aInBrowser);
 }
 
-NS_IMETHODIMP
-nsWyciwygProtocolHandler::Observe(nsISupports *subject,
-                                  const char *topic,
-                                  const PRUnichar *data)
-{
-  if (strcmp(topic, "webapps-clear-data") == 0) {
-    nsCOMPtr<mozIApplicationClearPrivateDataParams> params =
-        do_QueryInterface(subject);
-    if (!params) {
-      NS_ERROR("'webapps-clear-data' notification's subject should be a mozIApplicationClearPrivateDataParams");
-      return NS_ERROR_UNEXPECTED;
-    }
-
-    uint32_t appId;
-    bool browserOnly;
-    nsresult rv = params->GetAppId(&appId);
-    NS_ENSURE_SUCCESS(rv, rv);
-    rv = params->GetBrowserOnly(&browserOnly);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    MOZ_ASSERT(appId != NECKO_UNKNOWN_APP_ID);
-
-    EvictCacheSession(appId, browserOnly, false);
-    EvictCacheSession(appId, browserOnly, true);
-    if (!browserOnly) {
-      EvictCacheSession(appId, true, false);
-      EvictCacheSession(appId, true, true);
-    }
-  }
-  return NS_OK;
-}
-
-NS_IMPL_ISUPPORTS3(nsWyciwygProtocolHandler,
-                   nsIProtocolHandler,
-                   nsIObserver,
-                   nsISupportsWeakReference)
+NS_IMPL_ISUPPORTS1(nsWyciwygProtocolHandler,
+                   nsIProtocolHandler)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIProtocolHandler methods:
 ////////////////////////////////////////////////////////////////////////////////
 
 NS_IMETHODIMP
 nsWyciwygProtocolHandler::GetScheme(nsACString &result)
 {
--- a/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.h
+++ b/netwerk/protocol/wyciwyg/nsWyciwygProtocolHandler.h
@@ -3,27 +3,22 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsWyciwygProtocolHandler_h___
 #define nsWyciwygProtocolHandler_h___
 
 #include "nsIProtocolHandler.h"
-#include "nsIObserver.h"
-#include "nsWeakReference.h"
             
 class nsWyciwygProtocolHandler : public nsIProtocolHandler
-                               , public nsIObserver
-                               , public nsSupportsWeakReference
 {
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSIPROTOCOLHANDLER
-    NS_DECL_NSIOBSERVER
 
     nsWyciwygProtocolHandler();
     virtual ~nsWyciwygProtocolHandler();
 
     nsresult Init();
 
     static void GetCacheSessionName(uint32_t aAppId,
                                     bool aInBrowser,