Bug 1268889 - Implement Clear-Site-Data header - part 4 - cleanup image cache, r=aosmond
authorAndrea Marchesini <amarchesini@mozilla.com>
Wed, 20 Jun 2018 11:57:50 -0400
changeset 477508 2a94bdf78194df4c5ff16769310abe152534c98f
parent 477507 d6a2857d3e217aa3343555a2e258fe0812e00341
child 477509 e0e706157952b5d21477f1cf87288e5c9b8a7bd6
push id9385
push userdluca@mozilla.com
push dateFri, 22 Jun 2018 15:47:18 +0000
treeherdermozilla-beta@82a9a1027e2b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaosmond
bugs1268889
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1268889 - Implement Clear-Site-Data header - part 4 - cleanup image cache, r=aosmond
image/ImageCacheKey.h
image/imgICache.idl
image/imgLoader.cpp
toolkit/components/cleardata/ClearDataService.js
--- a/image/ImageCacheKey.h
+++ b/image/ImageCacheKey.h
@@ -36,19 +36,21 @@ public:
                 nsIDocument* aDocument, nsresult& aRv);
 
   ImageCacheKey(const ImageCacheKey& aOther);
   ImageCacheKey(ImageCacheKey&& aOther);
 
   bool operator==(const ImageCacheKey& aOther) const;
   PLDHashNumber Hash() const { return mHash; }
 
-  /// A weak pointer to the URI. For logging only.
+  /// A weak pointer to the URI.
   nsIURI* URI() const { return mURI; }
 
+  const OriginAttributes& OriginAttributesRef() const { return mOriginAttributes; }
+
   /// Is this cache entry for a chrome image?
   bool IsChrome() const { return mIsChrome; }
 
   /// A token indicating which service worker controlled document this entry
   /// belongs to, if any.
   void* ControlledDocument() const { return mControlledDocument; }
 
 private:
--- a/image/imgICache.idl
+++ b/image/imgICache.idl
@@ -3,21 +3,30 @@
  * 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 "nsISupports.idl"
 
 interface imgIRequest;
 interface nsIDocument;
+interface nsIPrincipal;
 interface nsIProperties;
 interface nsIURI;
 
 webidl Document;
 
+%{ C++
+namespace mozilla {
+class OriginAttributes;
+} // mozilla namespace
+%}
+
+[ptr] native OriginAttributesPtr(mozilla::OriginAttributes);
+
 /**
  * imgICache interface
  *
  * @author Stuart Parmenter <pavlov@netscape.com>
  * @version 0.1
  * @see imagelib2
  */
 [scriptable, builtinclass, uuid(bfdf23ff-378e-402e-8a6c-840f0c82b6c3)]
@@ -37,16 +46,24 @@ interface imgICache : nsISupports
    * @param uri The URI to remove.
    * @param doc The document to remove the cache entry for.
    * @throws NS_ERROR_NOT_AVAILABLE if \a uri was unable to be removed from
    * the cache.
    */
   [noscript] void removeEntry(in nsIURI uri, [optional] in Document doc);
 
   /**
+   * Evict images from the cache with the same origin and the same
+   * originAttributes of the passed principal.
+   *
+   * @param aPrincipal The principal
+   */
+  void removeEntriesFromPrincipal(in nsIPrincipal aPrincipal);
+
+  /**
    * Find Properties
    * Used to get properties such as 'type' and 'content-disposition'
    * 'type' is a nsISupportsCString containing the images' mime type such as
    * 'image/png'
    * 'content-disposition' will be a nsISupportsCString containing the header
    * If you call this before any data has been loaded from a URI, it will
    * succeed, but come back empty.
    *
--- a/image/imgLoader.cpp
+++ b/image/imgLoader.cpp
@@ -1465,16 +1465,55 @@ imgLoader::ClearCache(bool chrome)
   if (chrome) {
     return ClearChromeImageCache();
   }
   return ClearImageCache();
 
 }
 
 NS_IMETHODIMP
+imgLoader::RemoveEntriesFromPrincipal(nsIPrincipal* aPrincipal)
+{
+  nsAutoString origin;
+  nsresult rv = nsContentUtils::GetUTFOrigin(aPrincipal, origin);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  AutoTArray<RefPtr<imgCacheEntry>, 128> entriesToBeRemoved;
+
+  imgCacheTable& cache = GetCache(nsContentUtils::IsSystemPrincipal(aPrincipal));
+  for (auto iter = cache.Iter(); !iter.Done(); iter.Next()) {
+    auto& key = iter.Key();
+
+    if (key.OriginAttributesRef() != BasePrincipal::Cast(aPrincipal)->OriginAttributesRef()) {
+       continue;
+    }
+
+    nsAutoString imageOrigin;
+    nsresult rv = nsContentUtils::GetUTFOrigin(key.URI(), imageOrigin);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      continue;
+    }
+
+    if (imageOrigin == origin) {
+      entriesToBeRemoved.AppendElement(iter.Data());
+    }
+  }
+
+  for (auto& entry : entriesToBeRemoved) {
+    if (!RemoveFromCache(entry)) {
+      NS_WARNING("Couldn't remove an entry from the cache in RemoveEntriesFromPrincipal()\n");
+    }
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 imgLoader::RemoveEntry(nsIURI* aURI,
                        nsIDocument* aDoc)
 {
   if (aURI) {
     OriginAttributes attrs;
     if (aDoc) {
       nsCOMPtr<nsIPrincipal> principal = aDoc->NodePrincipal();
       if (principal) {
--- a/toolkit/components/cleardata/ClearDataService.js
+++ b/toolkit/components/cleardata/ClearDataService.js
@@ -90,16 +90,26 @@ const NetworkCacheCleaner = {
     return new Promise(aResolve => {
       Services.cache2.clear();
       aResolve();
     });
   },
 };
 
 const ImageCacheCleaner = {
+  deleteByPrincipal(aPrincipal) {
+    return new Promise(aResolve => {
+      let imageCache = Cc["@mozilla.org/image/tools;1"]
+                         .getService(Ci.imgITools)
+                         .getImgCacheForDocument(null);
+      imageCache.removeEntriesFromPrincipal(aPrincipal);
+      aResolve();
+    });
+  },
+
   deleteAll() {
     return new Promise(aResolve => {
       let imageCache = Cc["@mozilla.org/image/tools;1"]
                          .getService(Ci.imgITools)
                          .getImgCacheForDocument(null);
       imageCache.clearCache(false); // true=chrome, false=content
       aResolve();
     });