Bug 1188637 - Use channel->ascynOpen2 in dom/base/EventSource.cpp (r=sicking)
authorChristoph Kerschbaumer <mozilla@christophkerschbaumer.com>
Tue, 04 Aug 2015 20:06:19 -0700
changeset 287924 9776adf990a4072f2236e06397bf73118a539219
parent 287923 401e10fc988b0127bcec58bfca4199c17f4896e1
child 287925 bff74cecc67cb09b03974e2fa3fd85a9ba873786
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssicking
bugs1188637
milestone42.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 1188637 - Use channel->ascynOpen2 in dom/base/EventSource.cpp (r=sicking)
dom/base/EventSource.cpp
dom/base/EventSource.h
dom/security/nsContentSecurityManager.cpp
--- a/dom/base/EventSource.cpp
+++ b/dom/base/EventSource.cpp
@@ -547,19 +547,24 @@ EventSource::AsyncOnChannelRedirect(nsIC
   NS_ENSURE_SUCCESS(rv, rv);
 
   NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
 
   nsCOMPtr<nsIURI> newURI;
   rv = NS_GetFinalChannelURI(aNewChannel, getter_AddRefs(newURI));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!CheckCanRequestSrc(newURI)) {
-    DispatchFailConnection();
-    return NS_ERROR_DOM_SECURITY_ERR;
+  bool isValidScheme =
+    (NS_SUCCEEDED(newURI->SchemeIs("http", &isValidScheme)) && isValidScheme) ||
+    (NS_SUCCEEDED(newURI->SchemeIs("https", &isValidScheme)) && isValidScheme);
+
+  rv = CheckInnerWindowCorrectness();
+  if (NS_FAILED(rv) || !isValidScheme) {
+     DispatchFailConnection();
+     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   // Prepare to receive callback
   mRedirectFlags = aFlags;
   mRedirectCallback = aCallback;
   mNewRedirectChannel = aNewChannel;
 
   if (mChannelEventSink) {
@@ -740,48 +745,57 @@ EventSource::SetupHttpChannel()
 
 nsresult
 EventSource::InitChannelAndRequestEventSource()
 {
   if (mReadyState == CLOSED) {
     return NS_ERROR_ABORT;
   }
 
-  // eventsource validation
+  bool isValidScheme =
+    (NS_SUCCEEDED(mSrc->SchemeIs("http", &isValidScheme)) && isValidScheme) ||
+    (NS_SUCCEEDED(mSrc->SchemeIs("https", &isValidScheme)) && isValidScheme);
 
-  if (!CheckCanRequestSrc()) {
+  nsresult rv = CheckInnerWindowCorrectness();
+  if (NS_FAILED(rv) || !isValidScheme) {
     DispatchFailConnection();
     return NS_ERROR_DOM_SECURITY_ERR;
   }
 
   nsLoadFlags loadFlags;
   loadFlags = nsIRequest::LOAD_BACKGROUND | nsIRequest::LOAD_BYPASS_CACHE;
 
-  nsresult rv;
   nsIScriptContext* sc = GetContextForEventHandlers(&rv);
   nsCOMPtr<nsIDocument> doc =
     nsContentUtils::GetDocumentFromScriptContext(sc);
 
+  nsSecurityFlags securityFlags =
+    nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
+
+  if (mWithCredentials) {
+    securityFlags |= nsILoadInfo::SEC_REQUIRE_CORS_WITH_CREDENTIALS;
+  }
+
   nsCOMPtr<nsIChannel> channel;
   // If we have the document, use it
   if (doc) {
     rv = NS_NewChannel(getter_AddRefs(channel),
                        mSrc,
                        doc,
-                       nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                       securityFlags,
                        nsIContentPolicy::TYPE_DATAREQUEST,
                        mLoadGroup,       // loadGroup
                        nullptr,          // aCallbacks
                        loadFlags);       // aLoadFlags
   } else {
     // otherwise use the principal
     rv = NS_NewChannel(getter_AddRefs(channel),
                        mSrc,
                        mPrincipal,
-                       nsILoadInfo::SEC_FORCE_INHERIT_PRINCIPAL,
+                       securityFlags,
                        nsIContentPolicy::TYPE_DATAREQUEST,
                        mLoadGroup,       // loadGroup
                        nullptr,          // aCallbacks
                        loadFlags);       // aLoadFlags
   }
 
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -793,26 +807,23 @@ EventSource::InitChannelAndRequestEventS
 
   nsCOMPtr<nsIInterfaceRequestor> notificationCallbacks;
   mHttpChannel->GetNotificationCallbacks(getter_AddRefs(notificationCallbacks));
   if (notificationCallbacks != this) {
     mNotificationCallbacks = notificationCallbacks;
     mHttpChannel->SetNotificationCallbacks(this);
   }
 
-  nsRefPtr<nsCORSListenerProxy> listener =
-    new nsCORSListenerProxy(this, mPrincipal, mWithCredentials);
-  rv = listener->Init(mHttpChannel, DataURIHandling::Allow);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   // Start reading from the channel
-  rv = mHttpChannel->AsyncOpen(listener, nullptr);
-  if (NS_SUCCEEDED(rv)) {
-    mWaitingForOnStopRequest = true;
+  rv = mHttpChannel->AsyncOpen2(this);
+  if (NS_FAILED(rv)) {
+    DispatchFailConnection();
+    return rv;
   }
+  mWaitingForOnStopRequest = true;
   return rv;
 }
 
 void
 EventSource::AnnounceConnection()
 {
   if (mReadyState == CLOSED) {
     return;
@@ -1073,73 +1084,16 @@ EventSource::FailConnection()
 
   rv = DispatchDOMEvent(nullptr, event, nullptr, nullptr);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to dispatch the error event!!!");
     return;
   }
 }
 
-bool
-EventSource::CheckCanRequestSrc(nsIURI* aSrc)
-{
-  if (mReadyState == CLOSED) {
-    return false;
-  }
-
-  bool isValidURI = false;
-  bool isValidContentLoadPolicy = false;
-  bool isValidProtocol = false;
-
-  nsCOMPtr<nsIURI> srcToTest = aSrc ? aSrc : mSrc.get();
-  NS_ENSURE_TRUE(srcToTest, false);
-
-  uint32_t aCheckURIFlags =
-    nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL |
-    nsIScriptSecurityManager::DISALLOW_SCRIPT;
-
-  nsresult rv = nsContentUtils::GetSecurityManager()->
-    CheckLoadURIWithPrincipal(mPrincipal,
-                              srcToTest,
-                              aCheckURIFlags);
-  isValidURI = NS_SUCCEEDED(rv);
-
-  // After the security manager, the content-policy check
-
-  nsIScriptContext* sc = GetContextForEventHandlers(&rv);
-  nsCOMPtr<nsIDocument> doc =
-    nsContentUtils::GetDocumentFromScriptContext(sc);
-
-  // mScriptContext should be initialized because of GetBaseURI() above.
-  // Still need to consider the case that doc is nullptr however.
-  rv = CheckInnerWindowCorrectness();
-  NS_ENSURE_SUCCESS(rv, false);
-  int16_t shouldLoad = nsIContentPolicy::ACCEPT;
-  rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_DATAREQUEST,
-                                 srcToTest,
-                                 mPrincipal,
-                                 doc,
-                                 NS_LITERAL_CSTRING(TEXT_EVENT_STREAM),
-                                 nullptr,    // extra
-                                 &shouldLoad,
-                                 nsContentUtils::GetContentPolicy(),
-                                 nsContentUtils::GetSecurityManager());
-  isValidContentLoadPolicy = NS_SUCCEEDED(rv) && NS_CP_ACCEPTED(shouldLoad);
-
-  nsAutoCString targetURIScheme;
-  rv = srcToTest->GetScheme(targetURIScheme);
-  if (NS_SUCCEEDED(rv)) {
-    // We only have the http support for now
-    isValidProtocol = targetURIScheme.EqualsLiteral("http") ||
-                      targetURIScheme.EqualsLiteral("https");
-  }
-
-  return isValidURI && isValidContentLoadPolicy && isValidProtocol;
-}
-
 // static
 void
 EventSource::TimerCallback(nsITimer* aTimer, void* aClosure)
 {
   nsRefPtr<EventSource> thisObject = static_cast<EventSource*>(aClosure);
 
   if (thisObject->mReadyState == CLOSED) {
     return;
--- a/dom/base/EventSource.h
+++ b/dom/base/EventSource.h
@@ -140,17 +140,16 @@ protected:
                                     uint32_t        aToOffset,
                                     uint32_t        aCount,
                                     uint32_t       *aWriteCount);
   nsresult SetFieldAndClear();
   nsresult ClearFields();
   nsresult ResetEvent();
   nsresult DispatchCurrentMessageEvent();
   nsresult ParseCharacter(char16_t aChr);
-  bool CheckCanRequestSrc(nsIURI* aSrc = nullptr);  // if null, it tests mSrc
   nsresult CheckHealthOfRequestCallback(nsIRequest *aRequestCallback);
   nsresult OnRedirectVerifyCallback(nsresult result);
 
   nsCOMPtr<nsIURI> mSrc;
 
   nsString mLastEventID;
   uint32_t mReconnectionTime;  // in ms
 
--- a/dom/security/nsContentSecurityManager.cpp
+++ b/dom/security/nsContentSecurityManager.cpp
@@ -127,23 +127,29 @@ DoContentSecurityChecks(nsIURI* aURI, ns
     case nsIContentPolicy::TYPE_SCRIPT:
     case nsIContentPolicy::TYPE_IMAGE:
     case nsIContentPolicy::TYPE_STYLESHEET:
     case nsIContentPolicy::TYPE_OBJECT:
     case nsIContentPolicy::TYPE_DOCUMENT:
     case nsIContentPolicy::TYPE_SUBDOCUMENT:
     case nsIContentPolicy::TYPE_REFRESH:
     case nsIContentPolicy::TYPE_XBL:
-    case nsIContentPolicy::TYPE_PING:
-    case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
-    // alias nsIContentPolicy::TYPE_DATAREQUEST:
+    case nsIContentPolicy::TYPE_PING: {
       MOZ_ASSERT(false, "contentPolicyType not supported yet");
       break;
     }
 
+    case nsIContentPolicy::TYPE_XMLHTTPREQUEST: {
+      // alias nsIContentPolicy::TYPE_DATAREQUEST:
+      mimeTypeGuess = NS_LITERAL_CSTRING(TEXT_EVENT_STREAM);
+      requestingContext = aLoadInfo->LoadingNode();
+      break;
+    }
+
+
     case nsIContentPolicy::TYPE_OBJECT_SUBREQUEST: {
       mimeTypeGuess = EmptyCString();
       requestingContext = aLoadInfo->LoadingNode();
       MOZ_ASSERT(!requestingContext ||
                  requestingContext->NodeType() == nsIDOMNode::ELEMENT_NODE,
                  "type_subrequest requires requestingContext of type Element");
       break;
     }