Bug 1541339 - WebSocket channel should use the correct CookieSettings in workers, r=Ehsan
authorAndrea Marchesini <amarchesini@mozilla.com>
Fri, 26 Apr 2019 22:51:42 +0000
changeset 530507 fd9f15fe0ec120717b9690ace0b1a42bb01f48a9
parent 530506 2ce05675c4470e08e9cc9dbdecac62518a7df578
child 530513 3eb7623b5e63b37823d5e9c562d56e586604c823
child 530514 488caf8c768000d2aa1805c1dc34bd5116f60998
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersEhsan
bugs1541339
milestone68.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 1541339 - WebSocket channel should use the correct CookieSettings in workers, r=Ehsan Differential Revision: https://phabricator.services.mozilla.com/D28949
dom/websocket/WebSocket.cpp
netwerk/protocol/websocket/BaseWebSocketChannel.cpp
netwerk/protocol/websocket/BaseWebSocketChannel.h
netwerk/protocol/websocket/nsIWebSocketChannel.idl
testing/web-platform/meta/infrastructure/server/__dir__.ini
testing/web-platform/meta/websockets/__dir__.ini
testing/web-platform/meta/websockets/binary/__dir__.ini
testing/web-platform/meta/websockets/constructor/__dir__.ini
--- a/dom/websocket/WebSocket.cpp
+++ b/dom/websocket/WebSocket.cpp
@@ -27,16 +27,17 @@
 #include "nsGlobalWindow.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsIDOMWindow.h"
 #include "mozilla/dom/Document.h"
 #include "nsXPCOM.h"
 #include "nsIXPConnect.h"
 #include "nsContentUtils.h"
 #include "nsError.h"
+#include "nsICookieSettings.h"
 #include "nsIScriptObjectPrincipal.h"
 #include "nsIURL.h"
 #include "nsThreadUtils.h"
 #include "nsIPromptFactory.h"
 #include "nsIWindowWatcher.h"
 #include "nsIPrompt.h"
 #include "nsIStringBundle.h"
 #include "nsIConsoleService.h"
@@ -121,17 +122,18 @@ class WebSocketImpl final : public nsIIn
                 const nsACString& aScriptFile, uint32_t aScriptLine,
                 uint32_t aScriptColumn);
 
   nsresult AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
                      nsITransportProvider* aTransportProvider,
                      const nsACString& aNegotiatedExtensions);
 
   nsresult ParseURL(const nsAString& aURL);
-  nsresult InitializeConnection(nsIPrincipal* aPrincipal);
+  nsresult InitializeConnection(nsIPrincipal* aPrincipal,
+                                nsICookieSettings* aCookieSettings);
 
   // These methods when called can release the WebSocket object
   void FailConnection(uint16_t reasonCode,
                       const nsACString& aReasonString = EmptyCString());
   nsresult CloseConnection(uint16_t reasonCode,
                            const nsACString& aReasonString = EmptyCString());
   void Disconnect();
   void DisconnectInternal();
@@ -1088,27 +1090,28 @@ class ConnectRunnable final : public Web
 
  protected:
   virtual bool InitWithWindow(nsPIDOMWindowInner* aWindow) override {
     Document* doc = aWindow->GetExtantDoc();
     if (!doc) {
       return true;
     }
 
-    mConnectionFailed =
-        NS_FAILED(mImpl->InitializeConnection(doc->NodePrincipal()));
+    mConnectionFailed = NS_FAILED(mImpl->InitializeConnection(
+        doc->NodePrincipal(), mWorkerPrivate->CookieSettings()));
     return true;
   }
 
   virtual bool InitWindowless(WorkerPrivate* aTopLevelWorkerPrivate) override {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aTopLevelWorkerPrivate && !aTopLevelWorkerPrivate->GetWindow());
 
     mConnectionFailed = NS_FAILED(
-        mImpl->InitializeConnection(aTopLevelWorkerPrivate->GetPrincipal()));
+        mImpl->InitializeConnection(aTopLevelWorkerPrivate->GetPrincipal(),
+                                    mWorkerPrivate->CookieSettings()));
     return true;
   }
 
   // Raw pointer. This worker runnable runs synchronously.
   WebSocketImpl* mImpl;
 
   bool mConnectionFailed;
 };
@@ -1253,21 +1256,23 @@ already_AddRefed<WebSocket> WebSocket::C
     aRv = webSocketImpl->Init(aGlobal.Context(), loadingPrincipal, principal,
                               !!aTransportProvider, aUrl, protocolArray,
                               EmptyCString(), 0, 0);
 
     if (NS_WARN_IF(aRv.Failed())) {
       return nullptr;
     }
 
+    nsCOMPtr<Document> doc = webSocket->GetDocumentIfCurrent();
+
     // the constructor should throw a SYNTAX_ERROR only if it fails to parse the
     // url parameter, so don't throw if InitializeConnection fails, and call
     // onerror/onclose asynchronously
-    connectionFailed =
-        NS_FAILED(webSocketImpl->InitializeConnection(principal));
+    connectionFailed = NS_FAILED(webSocketImpl->InitializeConnection(
+        principal, doc ? doc->CookieSettings() : nullptr));
   } else {
     WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
     MOZ_ASSERT(workerPrivate);
 
     unsigned lineno, column;
     JS::AutoFilename file;
     if (!JS::DescribeScriptedCaller(aGlobal.Context(), &file, &lineno,
                                     &column)) {
@@ -1673,17 +1678,18 @@ class nsAutoCloseWS final {
           nsIWebSocketChannel::CLOSE_INTERNAL_ERROR);
     }
   }
 
  private:
   RefPtr<WebSocketImpl> mWebSocketImpl;
 };
 
-nsresult WebSocketImpl::InitializeConnection(nsIPrincipal* aPrincipal) {
+nsresult WebSocketImpl::InitializeConnection(
+    nsIPrincipal* aPrincipal, nsICookieSettings* aCookieSettings) {
   AssertIsOnMainThread();
   MOZ_ASSERT(!mChannel, "mChannel should be null");
 
   nsCOMPtr<nsIWebSocketChannel> wsChannel;
   nsAutoCloseWS autoClose(this);
   nsresult rv;
 
   if (mSecure) {
@@ -1716,20 +1722,20 @@ nsresult WebSocketImpl::InitializeConnec
   // are not thread-safe.
   mOriginDocument = nullptr;
 
   // The TriggeringPrincipal for websockets must always be a script.
   // Let's make sure that the doc's principal (if a doc exists)
   // and aPrincipal are same origin.
   MOZ_ASSERT(!doc || doc->NodePrincipal()->Equals(aPrincipal));
 
-  rv = wsChannel->InitLoadInfo(doc, doc ? doc->NodePrincipal() : aPrincipal,
-                               aPrincipal,
-                               nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
-                               nsIContentPolicy::TYPE_WEBSOCKET);
+  rv = wsChannel->InitLoadInfoNative(
+      doc, doc ? doc->NodePrincipal() : aPrincipal, aPrincipal, aCookieSettings,
+      nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
+      nsIContentPolicy::TYPE_WEBSOCKET);
   MOZ_ASSERT(NS_SUCCEEDED(rv));
 
   if (!mRequestedProtocolList.IsEmpty()) {
     rv = wsChannel->SetProtocol(mRequestedProtocolList);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsCOMPtr<nsIThreadRetargetableRequest> rr = do_QueryInterface(wsChannel);
--- a/netwerk/protocol/websocket/BaseWebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/BaseWebSocketChannel.cpp
@@ -195,24 +195,39 @@ BaseWebSocketChannel::SetPingTimeout(uin
 
   mPingResponseTimeout = aSeconds * 1000;
   mClientSetPingTimeout = 1;
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
+BaseWebSocketChannel::InitLoadInfoNative(nsINode *aLoadingNode,
+                                         nsIPrincipal *aLoadingPrincipal,
+                                         nsIPrincipal *aTriggeringPrincipal,
+                                         nsICookieSettings *aCookieSettings,
+                                         uint32_t aSecurityFlags,
+                                         uint32_t aContentPolicyType) {
+  mLoadInfo = new LoadInfo(aLoadingPrincipal, aTriggeringPrincipal,
+                           aLoadingNode, aSecurityFlags, aContentPolicyType);
+  if (aCookieSettings) {
+    mLoadInfo->SetCookieSettings(aCookieSettings);
+  }
+  return NS_OK;
+}
+
+NS_IMETHODIMP
 BaseWebSocketChannel::InitLoadInfo(nsINode *aLoadingNode,
                                    nsIPrincipal *aLoadingPrincipal,
                                    nsIPrincipal *aTriggeringPrincipal,
                                    uint32_t aSecurityFlags,
                                    uint32_t aContentPolicyType) {
-  mLoadInfo = new LoadInfo(aLoadingPrincipal, aTriggeringPrincipal,
-                           aLoadingNode, aSecurityFlags, aContentPolicyType);
-  return NS_OK;
+  return InitLoadInfoNative(aLoadingNode, aLoadingPrincipal,
+                            aTriggeringPrincipal, nullptr, aSecurityFlags,
+                            aContentPolicyType);
 }
 
 NS_IMETHODIMP
 BaseWebSocketChannel::GetSerial(uint32_t *aSerial) {
   if (!aSerial) {
     return NS_ERROR_FAILURE;
   }
 
--- a/netwerk/protocol/websocket/BaseWebSocketChannel.h
+++ b/netwerk/protocol/websocket/BaseWebSocketChannel.h
@@ -48,16 +48,22 @@ class BaseWebSocketChannel : public nsIW
   NS_IMETHOD GetLoadInfo(nsILoadInfo **aLoadInfo) override;
   NS_IMETHOD GetExtensions(nsACString &aExtensions) override;
   NS_IMETHOD GetProtocol(nsACString &aProtocol) override;
   NS_IMETHOD SetProtocol(const nsACString &aProtocol) override;
   NS_IMETHOD GetPingInterval(uint32_t *aSeconds) override;
   NS_IMETHOD SetPingInterval(uint32_t aSeconds) override;
   NS_IMETHOD GetPingTimeout(uint32_t *aSeconds) override;
   NS_IMETHOD SetPingTimeout(uint32_t aSeconds) override;
+  NS_IMETHOD InitLoadInfoNative(nsINode *aLoadingNode,
+                                nsIPrincipal *aLoadingPrincipal,
+                                nsIPrincipal *aTriggeringPrincipal,
+                                nsICookieSettings *aCookieSettings,
+                                uint32_t aSecurityFlags,
+                                uint32_t aContentPolicyType) override;
   NS_IMETHOD InitLoadInfo(nsINode *aLoadingNode,
                           nsIPrincipal *aLoadingPrincipal,
                           nsIPrincipal *aTriggeringPrincipal,
                           uint32_t aSecurityFlags,
                           uint32_t aContentPolicyType) override;
   NS_IMETHOD GetSerial(uint32_t *aSerial) override;
   NS_IMETHOD SetSerial(uint32_t aSerial) override;
   NS_IMETHOD SetServerParameters(
--- a/netwerk/protocol/websocket/nsIWebSocketChannel.idl
+++ b/netwerk/protocol/websocket/nsIWebSocketChannel.idl
@@ -1,14 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set sw=4 ts=4 et tw=80 : */
 /* 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/. */
 
+interface nsICookieSettings;
 interface nsIURI;
 interface nsIInterfaceRequestor;
 interface nsILoadGroup;
 interface nsIWebSocketListener;
 interface nsIInputStream;
 interface nsILoadInfo;
 interface nsIPrincipal;
 interface nsITransportProvider;
@@ -71,29 +72,41 @@ interface nsIWebSocketChannel : nsISuppo
      */
     [must_use] readonly attribute ACString extensions;
 
     /**
      * Init the WebSocketChannel with LoadInfo arguments.
      * @param aLoadingNode
      * @param aLoadingPrincipal
      * @param aTriggeringPrincipal
+     * @param aCookieSettings
      * @param aSecurityFlags
      * @param aContentPolicyType
      *        These will be used as values for the nsILoadInfo object on the
      *        created channel. For details, see nsILoadInfo in nsILoadInfo.idl
      * @return reference to the new nsIChannel object
      *
      * Keep in mind that URIs coming from a webpage should *never* use the
      * systemPrincipal as the loadingPrincipal.
      *
      * Please note, if you provide both a loadingNode and a loadingPrincipal,
      * then loadingPrincipal must be equal to loadingNode->NodePrincipal().
      * But less error prone is to just supply a loadingNode.
      */
+     [notxpcom] nsresult initLoadInfoNative(in Node aLoadingNode,
+                                            in nsIPrincipal aLoadingPrincipal,
+                                            in nsIPrincipal aTriggeringPrincipal,
+                                            in nsICookieSettings aCookieSettings,
+                                            in unsigned long aSecurityFlags,
+                                            in unsigned long aContentPolicyType);
+
+     /**
+      * Similar to the previous one but without nsICookieSettings.
+      * This method is used by JS code where nsICookieSettings is not exposed.
+      */
      [must_use] void initLoadInfo(in Node aLoadingNode,
                                   in nsIPrincipal aLoadingPrincipal,
                                   in nsIPrincipal aTriggeringPrincipal,
                                   in unsigned long aSecurityFlags,
                                   in unsigned long aContentPolicyType);
 
     /**
      * Asynchronously open the websocket connection.  Received messages are fed
--- a/testing/web-platform/meta/infrastructure/server/__dir__.ini
+++ b/testing/web-platform/meta/infrastructure/server/__dir__.ini
@@ -1,2 +1,2 @@
-lsan-allowed: [Alloc, Create, CreateInner, MakeUnique, NewPage, PLDHashTable::ChangeTable, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::WeakPtr, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::CookieSettings::Create, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsStandardURL::TemplatedMutator, nsSupportsWeakReference::GetWeakReference]
+lsan-allowed: [Alloc, Create, CreateInner, MakeUnique, NewPage, PLDHashTable::ChangeTable, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::WeakPtr, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::BaseWebSocketChannel::InitLoadInfoNative, mozilla::net::CookieSettings::Create, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsStandardURL::TemplatedMutator, nsSupportsWeakReference::GetWeakReference]
 leak-threshold: [default:51200, tab:51200]
--- a/testing/web-platform/meta/websockets/__dir__.ini
+++ b/testing/web-platform/meta/websockets/__dir__.ini
@@ -1,2 +1,2 @@
 leak-threshold: [default:102400, tab:51200]
-lsan-allowed: [Alloc, Create, MakeUnique, NewPage, PLDHashTable::Add, Realloc, SetPropertyAsInterface, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::WeakPtr, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::extensions::ChannelWrapper::ChannelWrapper, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::CookieSettings::Create, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsHttpTransaction::ParseHead, mozilla::net::nsStandardURL::TemplatedMutator, nsNodeSupportsWeakRefTearoff::GetWeakReference, nsSupportsWeakReference::GetWeakReference]
+lsan-allowed: [Alloc, Create, MakeUnique, NewPage, PLDHashTable::Add, Realloc, SetPropertyAsInterface, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::WeakPtr, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::extensions::ChannelWrapper::ChannelWrapper, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::BaseWebSocketChannel::InitLoadInfoNative, mozilla::net::CookieSettings::Create, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsHttpTransaction::ParseHead, mozilla::net::nsStandardURL::TemplatedMutator, nsNodeSupportsWeakRefTearoff::GetWeakReference, nsSupportsWeakReference::GetWeakReference]
--- a/testing/web-platform/meta/websockets/binary/__dir__.ini
+++ b/testing/web-platform/meta/websockets/binary/__dir__.ini
@@ -1,3 +1,3 @@
-lsan-allowed: [MakeUnique, mozilla::dom::WebSocket::ConstructorCommon, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, Alloc, Create, Malloc, NewPage, PLDHashTable::Add, PLDHashTable::ChangeTable, Realloc, RecvOnAcknowledge, RecvOnStop, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::ThrottledEventQueue::Create, mozilla::WeakPtr, mozilla::dom::ScriptElement::MaybeProcessScript, mozilla::dom::WebSocket::WebSocket, mozilla::dom::WorkerCSPEventListener::Create, mozilla::dom::ContentChild::GetConstructedEventTarget, mozilla::net::WebSocketChannelChild::RecvOnServerClose, mozilla::net::nsStandardURL::TemplatedMutator, nsAtomTable::Atomize, nsDocShell::Create]
+lsan-allowed: [MakeUnique, mozilla::dom::WebSocket::ConstructorCommon, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::BaseWebSocketChannel::InitLoadInfoNative, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketEventService::GetOrCreate, Alloc, Create, Malloc, NewPage, PLDHashTable::Add, PLDHashTable::ChangeTable, Realloc, RecvOnAcknowledge, RecvOnStop, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::ThrottledEventQueue::Create, mozilla::WeakPtr, mozilla::dom::ScriptElement::MaybeProcessScript, mozilla::dom::WebSocket::WebSocket, mozilla::dom::WorkerCSPEventListener::Create, mozilla::dom::ContentChild::GetConstructedEventTarget, mozilla::net::WebSocketChannelChild::RecvOnServerClose, mozilla::net::nsStandardURL::TemplatedMutator, nsAtomTable::Atomize, nsDocShell::Create]
 lsan-max-stack-depth: 7
 leak-threshold: [tab:51200]
--- a/testing/web-platform/meta/websockets/constructor/__dir__.ini
+++ b/testing/web-platform/meta/websockets/constructor/__dir__.ini
@@ -1,3 +1,3 @@
-lsan-allowed: [Alloc, Create, MakeUnique, Malloc, NewPage, PLDHashTable::Add, PLDHashTable::ChangeTable, Realloc, RecvOnAcknowledge, RecvOnStop, SetPropertyAsInterface, SetSucceededCertChain, allocate, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::ThrottledEventQueue::Create, mozilla::WeakPtr, mozilla::dom::ContentChild::GetConstructedEventTarget, mozilla::dom::ScriptElement::MaybeProcessScript, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::dom::WorkerCSPEventListener::Create, mozilla::extensions::ChannelWrapper::ChannelWrapper, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketChannelChild::RecvOnServerClose, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsHttpTransaction::ParseHead, mozilla::net::nsStandardURL::TemplatedMutator, nsAtomTable::Atomize, nsDocShell::Create, nsNSSCertificate::Create, nsNodeSupportsWeakRefTearoff::GetWeakReference, nsSSLIOLayerAddToSocket]
+lsan-allowed: [Alloc, Create, MakeUnique, Malloc, NewPage, PLDHashTable::Add, PLDHashTable::ChangeTable, Realloc, RecvOnAcknowledge, RecvOnStop, SetPropertyAsInterface, SetSucceededCertChain, allocate, mozilla::BasePrincipal::CreateCodebasePrincipal, mozilla::SchedulerGroup::CreateEventTargetFor, mozilla::ThrottledEventQueue::Create, mozilla::WeakPtr, mozilla::dom::ContentChild::GetConstructedEventTarget, mozilla::dom::ScriptElement::MaybeProcessScript, mozilla::dom::WebSocket::ConstructorCommon, mozilla::dom::WebSocket::WebSocket, mozilla::dom::WorkerCSPEventListener::Create, mozilla::extensions::ChannelWrapper::ChannelWrapper, mozilla::net::BaseWebSocketChannel::InitLoadInfo, mozilla::net::BaseWebSocketChannel::InitLoadInfoNative, mozilla::net::WebSocketChannelChild::AsyncOpen, mozilla::net::WebSocketChannelChild::RecvOnServerClose, mozilla::net::WebSocketEventService::GetOrCreate, mozilla::net::nsHttpTransaction::ParseHead, mozilla::net::nsStandardURL::TemplatedMutator, nsAtomTable::Atomize, nsDocShell::Create, nsNSSCertificate::Create, nsNodeSupportsWeakRefTearoff::GetWeakReference, nsSSLIOLayerAddToSocket]
 lsan-max-stack-depth: 7
 leak-threshold: [tab:51200]