Bug 970246 - Create an http-on-response-set-cookie notification to tell when cookies are created via SET-COOKIE response header. r=honzab
authorGirish Sharma <scrapmachines@gmail.com>
Thu, 27 Feb 2014 00:14:42 +0530
changeset 171164 75b8e45e9beb630512d705cebb306c04896d631a
parent 171163 0a61ab3b106c04d0e2062cf852f76deb05ff139f
child 171165 e6950f359b60f3ca667ecc683f5f3fe1f7ae8e59
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewershonzab
bugs970246
milestone30.0a1
Bug 970246 - Create an http-on-response-set-cookie notification to tell when cookies are created via SET-COOKIE response header. r=honzab
netwerk/protocol/http/HttpBaseChannel.cpp
--- a/netwerk/protocol/http/HttpBaseChannel.cpp
+++ b/netwerk/protocol/http/HttpBaseChannel.cpp
@@ -21,16 +21,17 @@
 #include "nsIApplicationCacheChannel.h"
 #include "nsEscape.h"
 #include "nsStreamListenerWrapper.h"
 #include "nsISecurityConsoleMessage.h"
 #include "nsURLHelper.h"
 #include "nsICookieService.h"
 #include "nsIStreamConverterService.h"
 #include "nsCRT.h"
+#include "nsIObserverService.h"
 
 #include <algorithm>
 
 namespace mozilla {
 namespace net {
 
 HttpBaseChannel::HttpBaseChannel()
   : mStartPos(UINT64_MAX)
@@ -1308,32 +1309,65 @@ HttpBaseChannel::GetResponseVersion(uint
   nsHttpVersion version = mResponseHead->Version();
 
   if (major) { *major = version / 10; }
   if (minor) { *minor = version % 10; }
 
   return NS_OK;
 }
 
+namespace {
+
+class CookieNotifierRunnable : public nsRunnable
+{
+public:
+  CookieNotifierRunnable(HttpBaseChannel* aChannel, char const * aCookie)
+    : mChannel(aChannel), mCookie(aCookie)
+  { }
+
+  NS_IMETHOD Run()
+  {
+    nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
+    if (obs) {
+      obs->NotifyObservers(static_cast<nsIChannel*>(mChannel.get()),
+                           "http-on-response-set-cookie",
+                           mCookie.get());
+    }
+    return NS_OK;
+  }
+
+private:
+  nsRefPtr<HttpBaseChannel> mChannel;
+  NS_ConvertASCIItoUTF16 mCookie;
+};
+
+} // anonymous namespace
+
 NS_IMETHODIMP
 HttpBaseChannel::SetCookie(const char *aCookieHeader)
 {
   if (mLoadFlags & LOAD_ANONYMOUS)
     return NS_OK;
 
   // empty header isn't an error
   if (!(aCookieHeader && *aCookieHeader))
     return NS_OK;
 
   nsICookieService *cs = gHttpHandler->GetCookieService();
   NS_ENSURE_TRUE(cs, NS_ERROR_FAILURE);
 
-  return cs->SetCookieStringFromHttp(mURI, nullptr, nullptr, aCookieHeader,
-                                     mResponseHead->PeekHeader(nsHttp::Date),
-                                     this);
+  nsresult rv =
+    cs->SetCookieStringFromHttp(mURI, nullptr, nullptr, aCookieHeader,
+                                mResponseHead->PeekHeader(nsHttp::Date), this);
+  if (NS_SUCCEEDED(rv)) {
+    nsRefPtr<CookieNotifierRunnable> r =
+      new CookieNotifierRunnable(this, aCookieHeader);
+    NS_DispatchToMainThread(r);
+  }
+  return rv;
 }
 
 NS_IMETHODIMP
 HttpBaseChannel::GetForceAllowThirdPartyCookie(bool *aForce)
 {
   *aForce = mForceAllowThirdPartyCookie;
   return NS_OK;
 }