Bug 837326 - Informing observers upon accept/reject of a third-party cookie;r=ehsan
☠☠ backed out by 918fd1e35b39 ☠ ☠
authorDavid Rajchenbach-Teller <dteller@mozilla.com>
Fri, 21 Jun 2013 17:48:31 +0200
changeset 147474 75fa13b20c1dd01ed96618e3f3d234191f5ed9b7
parent 147473 7cbc024b3c77934c98052ea50e89d7ef4fc7fe5c
child 147475 8508340fabb78cc93b0a11b9cafc90982be37f39
push id2697
push userbbajaj@mozilla.com
push dateMon, 05 Aug 2013 18:49:53 +0000
treeherdermozilla-beta@dfec938c7b63 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs837326
milestone24.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 837326 - Informing observers upon accept/reject of a third-party cookie;r=ehsan
netwerk/cookie/nsCookieService.cpp
netwerk/cookie/nsCookieService.h
netwerk/cookie/nsICookieService.idl
--- a/netwerk/cookie/nsCookieService.cpp
+++ b/netwerk/cookie/nsCookieService.cpp
@@ -1641,23 +1641,33 @@ nsCookieService::SetCookieStringInternal
     return;
   }
 
   nsCookieKey key(baseDomain, aAppId, aInBrowserElement);
 
   // check default prefs
   CookieStatus cookieStatus = CheckPrefs(aHostURI, aIsForeign, requireHostMatch,
                                          aCookieHeader.get());
-  // fire a notification if cookie was rejected (but not if there was an error)
+  // fire a notification if third party or if cookie was rejected
+  // (but not if there was an error)
   switch (cookieStatus) {
   case STATUS_REJECTED:
     NotifyRejected(aHostURI);
-    return;
+    if (aIsForeign) {
+      NotifyThirdParty(aHostURI, false, aChannel);
+    }
+    return; // Stop here
   case STATUS_REJECTED_WITH_ERROR:
     return;
+  case STATUS_ACCEPTED: // Fallthrough
+  case STATUS_ACCEPT_SESSION:
+    if (aIsForeign) {
+      NotifyThirdParty(aHostURI, true, aChannel);
+    }
+    break;
   default:
     break;
   }
 
   // parse server local time. this is not just done here for efficiency
   // reasons - if there's an error parsing it, and we need to default it
   // to the current time, we must do it here since the current time in
   // SetCookieInternal() will change for each cookie processed (e.g. if the
@@ -1680,18 +1690,48 @@ nsCookieService::SetCookieStringInternal
       break;
   }
 }
 
 // notify observers that a cookie was rejected due to the users' prefs.
 void
 nsCookieService::NotifyRejected(nsIURI *aHostURI)
 {
-  if (mObserverService)
+  if (mObserverService) {
     mObserverService->NotifyObservers(aHostURI, "cookie-rejected", nullptr);
+  }
+}
+
+// notify observers that a third-party cookie was accepted/rejected
+// if the cookie issuer is unknown, it defaults to "?"
+void
+nsCookieService::NotifyThirdParty(nsIURI *aHostURI, bool aIsAccepted, nsIChannel *aChannel)
+{
+  if (!mObserverService) {
+    return;
+  }
+  const char* topic = aIsAccepted ? "third-party-cookie-accepted"
+    : "third-party-cookie-rejected";
+
+  if (aChannel) {
+    nsCOMPtr<nsIURI> channelURI;
+    DebugOnly<nsresult> rv = aChannel->GetURI(getter_AddRefs(channelURI));
+    NS_ASSERTION(NS_SUCCEEDED(rv), "Channel doesn't have a uri");
+    nsAutoCString referringHost;
+    rv = channelURI->GetHost(referringHost);
+    NS_ASSERTION(NS_SUCCEEDED(rv), "URI doesn't have a host");
+    nsAutoString referringHostUTF16 = NS_ConvertUTF8toUTF16(referringHost);
+    mObserverService->NotifyObservers(aHostURI,
+                                      topic,
+                                      referringHostUTF16.get());
+  } else {
+    mObserverService->NotifyObservers(aHostURI,
+                                      topic,
+                                      NS_LITERAL_STRING("?").get());
+  }
 }
 
 // notify observers that the cookie list changed. there are five possible
 // values for aData:
 // "deleted" means a cookie was deleted. aSubject is the deleted cookie.
 // "added"   means a cookie was added. aSubject is the added cookie.
 // "changed" means a cookie was altered. aSubject is the new cookie.
 // "cleared" means the entire cookie list was cleared. aSubject is null.
--- a/netwerk/cookie/nsCookieService.h
+++ b/netwerk/cookie/nsCookieService.h
@@ -282,16 +282,17 @@ class nsCookieService : public nsICookie
     bool                          CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI, const nsCString &aBaseDomain, bool aRequireHostMatch);
     static bool                   CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
     static bool                   GetExpiry(nsCookieAttributes &aCookie, int64_t aServerTime, int64_t aCurrentTime);
     void                          RemoveAllFromMemory();
     already_AddRefed<nsIArray>    PurgeCookies(int64_t aCurrentTimeInUsec);
     bool                          FindCookie(const nsCookieKey& aKey, const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter);
     static void                   FindStaleCookie(nsCookieEntry *aEntry, int64_t aCurrentTime, nsListIter &aIter);
     void                          NotifyRejected(nsIURI *aHostURI);
+    void                          NotifyThirdParty(nsIURI *aHostURI, bool aAccepted, nsIChannel *aChannel);
     void                          NotifyChanged(nsISupports *aSubject, const PRUnichar *aData);
     void                          NotifyPurged(nsICookie2* aCookie);
     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.
      */
--- a/netwerk/cookie/nsICookieService.idl
+++ b/netwerk/cookie/nsICookieService.idl
@@ -53,16 +53,28 @@ interface nsIChannel;
  *          the entire cookie list should be reloaded.  the subject is null.
  *
  * topic  : "cookie-rejected"
  *          broadcast whenever a cookie was rejected from being set as a
  *          result of user prefs.
  * subject: an nsIURI interface pointer representing the URI that attempted
  *          to set the cookie.
  * data   : none.
+ *
+ * topic  : "third-party-cookie-accepted"
+ *           broadcast whenever a third party cookie was accepted
+ * subject:  an nsIURI interface pointer representing the URI that attempted
+ *           to set the cookie.
+ * data   :  the referrer, or "?" if unknown
+ *
+ * topic  : "third-party-cookie-rejected"
+ *           broadcast whenever a third party cookie was rejected
+ * subject:  an nsIURI interface pointer representing the URI that attempted
+ *           to set the cookie.
+ * data   :  the referrer, or "?" if unknown
  */
 [scriptable, uuid(2aaa897a-293c-4d2b-a657-8c9b7136996d)]
 interface nsICookieService : nsISupports
 {
   /*
    * Get the complete cookie string associated with the URI.
    *
    * @param aURI