Bug 783408 - 2/4 - Add a function to remove app's cookies in nsICookieManager2. r=jduell sr=mconnor
authorMounir Lamouri <mounir.lamouri@gmail.com>
Thu, 27 Sep 2012 22:37:02 +0100
changeset 114648 aa1746e4ec72499f0a72f01bfbab2edc8f01f127
parent 114647 bd91830d06d10b2b8300fca32082fc478787b126
child 114649 40cb1880529199361332fd0f68aa7ccaa5e17728
push id1708
push userakeybl@mozilla.com
push dateMon, 19 Nov 2012 21:10:21 +0000
treeherdermozilla-beta@27b14fe50103 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjduell, mconnor
bugs783408
milestone18.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 783408 - 2/4 - Add a function to remove app's cookies in nsICookieManager2. r=jduell sr=mconnor
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsCookieService.h
netwerk/cookie/nsICookieManager2.idl
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -1795,21 +1795,21 @@ nsCookieService::Add(const nsACString &a
   if (!cookie) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   AddInternal(DEFAULT_APP_KEY(baseDomain), cookie, currentTimeInUsec, nullptr, nullptr, true);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsCookieService::Remove(const nsACString &aHost,
-                        const nsACString &aName,
-                        const nsACString &aPath,
-                        bool             aBlocked)
+
+nsresult
+nsCookieService::Remove(const nsACString& aHost, uint32_t aAppId,
+                        bool aInBrowserElement, const nsACString& aName,
+                        const nsACString& aPath, bool aBlocked)
 {
   if (!mDBState) {
     NS_WARNING("No DBState! Profile already closed?");
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   // first, normalize the hostname, and fail if it contains illegal characters.
   nsAutoCString host(aHost);
@@ -1817,17 +1817,17 @@ nsCookieService::Remove(const nsACString
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsAutoCString baseDomain;
   rv = GetBaseDomainFromHost(host, baseDomain);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsListIter matchIter;
   nsRefPtr<nsCookie> cookie;
-  if (FindCookie(DEFAULT_APP_KEY(baseDomain),
+  if (FindCookie(nsCookieKey(baseDomain, aAppId, aInBrowserElement),
                  host,
                  PromiseFlatCString(aName),
                  PromiseFlatCString(aPath),
                  matchIter)) {
     cookie = matchIter.Cookie();
     RemoveCookieFromList(matchIter);
   }
 
@@ -1849,16 +1849,25 @@ nsCookieService::Remove(const nsACString
   if (cookie) {
     // Everything's done. Notify observers.
     NotifyChanged(cookie, NS_LITERAL_STRING("deleted").get());
   }
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsCookieService::Remove(const nsACString &aHost,
+                        const nsACString &aName,
+                        const nsACString &aPath,
+                        bool             aBlocked)
+{
+  return Remove(aHost, NECKO_NO_APP_ID, false, aName, aPath, aBlocked);
+}
+
 /******************************************************************************
  * nsCookieService impl:
  * private file I/O functions
  ******************************************************************************/
 
 // Begin an asynchronous read from the database.
 OpenDBResult
 nsCookieService::Read()
@@ -3771,16 +3780,60 @@ nsCookieService::GetCookiesForApp(uint32
                  NS_ERROR_INVALID_ARG);
 
   GetCookiesForAppStruct data(aAppId, aOnlyBrowserElement);
   mDBState->hostTable.EnumerateEntries(GetCookiesForApp, &data);
 
   return NS_NewArrayEnumerator(aEnumerator, data.cookies);
 }
 
+NS_IMETHODIMP
+nsCookieService::RemoveCookiesForApp(uint32_t aAppId, bool aOnlyBrowserElement)
+{
+  nsCOMPtr<nsISimpleEnumerator> enumerator;
+  nsresult rv = GetCookiesForApp(aAppId, aOnlyBrowserElement,
+                                 getter_AddRefs(enumerator));
+
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool hasMore;
+  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
+    nsCOMPtr<nsICookie> cookie;
+    rv = enumerator->GetNext(getter_AddRefs(cookie));
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsAutoCString host;
+    cookie->GetHost(host);
+
+    nsAutoCString name;
+    cookie->GetName(name);
+
+    nsAutoCString path;
+    cookie->GetPath(path);
+
+    // nsICookie do not carry the appId/inBrowserElement information.
+    // That means we have to guess. This is easy for appId but not for
+    // inBrowserElement flag.
+    // A simple solution is to always ask to remove the cookie with
+    // inBrowserElement = true and only ask for the other one to be removed if
+    // we happen to be in the case of !aOnlyBrowserElement.
+    // Anyway, with this solution, we will likely be looking for unexistant
+    // cookies.
+    //
+    // NOTE: we could make this better by getting nsCookieEntry objects instead
+    // of plain nsICookie.
+    Remove(host, aAppId, true, name, path, false);
+    if (!aOnlyBrowserElement) {
+      Remove(host, aAppId, false, name, path, false);
+    }
+  }
+
+  return NS_OK;
+}
+
 // find an exact cookie specified by host, name, and path that hasn't expired.
 bool
 nsCookieService::FindCookie(const nsCookieKey    &aKey,
                             const nsAFlatCString &aHost,
                             const nsAFlatCString &aName,
                             const nsAFlatCString &aPath,
                             nsListIter           &aIter)
 {
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -284,16 +284,25 @@ class nsCookieService : public nsICookie
     already_AddRefed<nsIArray>    CreatePurgeList(nsICookie2* aCookie);
 
     /**
      * This method is used to iterate the cookie hash table and select the ones
      * that are part of a specific app.
      */
     static PLDHashOperator GetCookiesForApp(nsCookieEntry* entry, void* arg);
 
+    /**
+     * This method is a helper that allows calling nsICookieManager::Remove()
+     * with appId/inBrowserElement parameters.
+     * NOTE: this could be added to a public interface if we happen to need it.
+     */
+    nsresult Remove(const nsACString& aHost, uint32_t aAppId,
+                    bool aInBrowserElement, const nsACString& aName,
+                    const nsACString& aPath, bool aBlocked);
+
   protected:
     // cached members.
     nsCOMPtr<nsIObserverService>     mObserverService;
     nsCOMPtr<nsICookiePermission>    mPermissionService;
     nsCOMPtr<mozIThirdPartyUtil>     mThirdPartyUtil;
     nsCOMPtr<nsIEffectiveTLDService> mTLDService;
     nsCOMPtr<nsIIDNService>          mIDNService;
     nsCOMPtr<mozIStorageService>     mStorageService;
--- a/netwerk/cookie/nsICookieManager2.idl
+++ b/netwerk/cookie/nsICookieManager2.idl
@@ -7,17 +7,17 @@
 
 interface nsICookie2;
 interface nsIFile;
 
 /** 
  * Additions to the frozen nsICookieManager
  */
 
-[scriptable, uuid(c0058e11-8ac3-4349-b87c-7332d0bb542c)]
+[scriptable, uuid(daf0caa7-b431-4b4d-ba51-08c179bb9dfe)]
 interface nsICookieManager2 : nsICookieManager
 {
   /**
    * Add a cookie. nsICookieService is the normal way to do this. This
    * method is something of a backdoor.
    *
    * @param aHost
    *        the host or domain for which the cookie is set. presence of a
@@ -114,9 +114,19 @@ interface nsICookieManager2 : nsICookieM
    * If the onlyBrowserELement parameter is set to true, only cookies part of
    * a browser element inside the app will be returned. If set to false, all
    * cookies will be returned, regardless of their browserElement flag.
    *
    * This method assumes that appId is a valid app id. It should not be a
    * special value like UNKNOWN_APP_ID or NO_APP_ID.
    */
   nsISimpleEnumerator getCookiesForApp(in unsigned long appId, in boolean onlyBrowserElement);
+
+  /**
+   * Remove all the cookies associated with the app with the id aAppId.
+   *
+   * If onlyBrowserElement is set to true, the method will only remove the
+   * cookies marked as part of a browser element inside the app.
+   *
+   * Special app id values are not allowed (NO_APP_ID or UNKNOWN_APP_ID for example).
+   */
+  void removeCookiesForApp(in unsigned long appId, in boolean onlyBrowserElement);
 };