Bug 1203802 - Websocket Frame Listener API for devtool Network Inspector - part 1 - WindowID added into WebSocketChannel, r=michal
authorAndrea Marchesini <amarchesini@mozilla.com>
Mon, 26 Oct 2015 15:29:28 +0000
changeset 304687 bf77e2eef0a0d12f2b0c5dc8d771d436291b5de8
parent 304686 d9f5c51cfa0029b60ebfc7cf2aaf766010072ca4
child 304688 1465c8af67d72c1e554a15d572cabdba4864cffe
push id1001
push userraliiev@mozilla.com
push dateMon, 18 Jan 2016 19:06:03 +0000
treeherdermozilla-release@8b89261f3ac4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmichal
bugs1203802
milestone44.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 1203802 - Websocket Frame Listener API for devtool Network Inspector - part 1 - WindowID added into WebSocketChannel, r=michal
browser/components/loop/modules/MozLoopPushHandler.jsm
browser/components/loop/test/xpcshell/head.js
dom/base/WebSocket.cpp
dom/push/PushServiceWebSocket.jsm
dom/push/test/xpcshell/head.js
dom/simplepush/PushService.jsm
netwerk/protocol/websocket/PWebSocket.ipdl
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/protocol/websocket/WebSocketChannel.h
netwerk/protocol/websocket/WebSocketChannelChild.cpp
netwerk/protocol/websocket/WebSocketChannelChild.h
netwerk/protocol/websocket/WebSocketChannelParent.cpp
netwerk/protocol/websocket/WebSocketChannelParent.h
netwerk/protocol/websocket/nsIWebSocketChannel.idl
netwerk/test/unit/test_dns_proxy_bypass.js
netwerk/test/unit/test_websocket_offline.js
--- a/browser/components/loop/modules/MozLoopPushHandler.jsm
+++ b/browser/components/loop/modules/MozLoopPushHandler.jsm
@@ -65,17 +65,17 @@ PushSocket.prototype = {
                                    Services.scriptSecurityManager.getSystemPrincipal(),
                                    null, // aTriggeringPrincipal
                                    Ci.nsILoadInfo.SEC_NORMAL,
                                    Ci.nsIContentPolicy.TYPE_WEBSOCKET);
     }
 
     let uri = Services.io.newURI(pushUri, null, null);
     this._websocket.protocol = "push-notification";
-    this._websocket.asyncOpen(uri, pushUri, this, null);
+    this._websocket.asyncOpen(uri, pushUri, 0, this, null);
   },
 
   /**
    * nsIWebSocketListener method, handles the start of the websocket stream.
    *
    * @param {nsISupports} aContext Not used
    */
   onStart: function() {
--- a/browser/components/loop/test/xpcshell/head.js
+++ b/browser/components/loop/test/xpcshell/head.js
@@ -152,21 +152,22 @@ MockWebSocketChannel.prototype = {
                                      JSON.stringify({}));
     return;
   },
 
   /**
    * nsIWebSocketChannel implementations.
    * See nsIWebSocketChannel.idl for API details.
    */
-  asyncOpen: function(aURI, aOrigin, aListener, aContext) {
+  asyncOpen: function(aURI, aOrigin, aWindowId, aListener, aContext) {
     this.uri = aURI;
     this.origin = aOrigin;
     this.listener = aListener;
     this.context = aContext;
+    this.windowId = aWindowId;
 
     this.listener.onStart(this.context);
   },
 
   sendMsg: function(aMsg) {
     var message = JSON.parse(aMsg);
 
     switch (message.messageType) {
--- a/dom/base/WebSocket.cpp
+++ b/dom/base/WebSocket.cpp
@@ -121,17 +121,18 @@ public:
             const nsAString& aURL,
             nsTArray<nsString>& aProtocolArray,
             const nsACString& aScriptFile,
             uint32_t aScriptLine,
             uint32_t aScriptColumn,
             ErrorResult& aRv,
             bool* aConnectionFailed);
 
-  void AsyncOpen(nsIPrincipal* aPrincipal, ErrorResult& aRv);
+  void AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
+                 ErrorResult& aRv);
 
   nsresult ParseURL(const nsAString& aURL);
   nsresult InitializeConnection(nsIPrincipal* aPrincipal);
 
   // These methods when called can release the WebSocket object
   void FailConnection(uint16_t reasonCode,
                       const nsACString& aReasonString = EmptyCString());
   nsresult CloseConnection(uint16_t reasonCode,
@@ -1119,39 +1120,48 @@ public:
     MOZ_ASSERT(mWorkerPrivate);
     mWorkerPrivate->AssertIsOnWorkerThread();
   }
 
 protected:
   virtual bool InitWithWindow(nsPIDOMWindow* aWindow) override
   {
     AssertIsOnMainThread();
+    MOZ_ASSERT(aWindow);
 
     nsIDocument* doc = aWindow->GetExtantDoc();
     if (!doc) {
       mRv.Throw(NS_ERROR_FAILURE);
       return true;
     }
 
     nsCOMPtr<nsIPrincipal> principal = doc->NodePrincipal();
     if (!principal) {
       mRv.Throw(NS_ERROR_FAILURE);
       return true;
     }
 
-    mImpl->AsyncOpen(principal, mRv);
+    uint64_t windowID = 0;
+    nsCOMPtr<nsIDOMWindow> topWindow;
+    aWindow->GetScriptableTop(getter_AddRefs(topWindow));
+    nsCOMPtr<nsPIDOMWindow> pTopWindow = do_QueryInterface(topWindow);
+    if (pTopWindow) {
+      windowID = pTopWindow->WindowID();
+    }
+
+    mImpl->AsyncOpen(principal, windowID, mRv);
     return true;
   }
 
   virtual bool InitWindowless(WorkerPrivate* aTopLevelWorkerPrivate) override
   {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(aTopLevelWorkerPrivate && !aTopLevelWorkerPrivate->GetWindow());
 
-    mImpl->AsyncOpen(aTopLevelWorkerPrivate->GetPrincipal(), mRv);
+    mImpl->AsyncOpen(aTopLevelWorkerPrivate->GetPrincipal(), 0, mRv);
     return true;
   }
 
 private:
   // Raw pointer. This worker runs synchronously.
   WebSocketImpl* mImpl;
 
   ErrorResult& mRv;
@@ -1303,17 +1313,26 @@ WebSocket::Constructor(const GlobalObjec
   // main-thread.
   aRv = webSocket->mImpl->mChannel->SetNotificationCallbacks(webSocket->mImpl);
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
   }
 
   if (NS_IsMainThread()) {
     MOZ_ASSERT(principal);
-    webSocket->mImpl->AsyncOpen(principal, aRv);
+
+    uint64_t windowID = 0;
+    nsCOMPtr<nsIDOMWindow> topWindow;
+    ownerWindow->GetScriptableTop(getter_AddRefs(topWindow));
+    nsCOMPtr<nsPIDOMWindow> pTopWindow = do_QueryInterface(topWindow);
+    if (pTopWindow) {
+      windowID = pTopWindow->WindowID();
+    }
+
+    webSocket->mImpl->AsyncOpen(principal, windowID, aRv);
   } else {
     RefPtr<AsyncOpenRunnable> runnable =
       new AsyncOpenRunnable(webSocket->mImpl, aRv);
     runnable->Dispatch(aGlobal.Context());
   }
 
   if (NS_WARN_IF(aRv.Failed())) {
     return nullptr;
@@ -1599,33 +1618,34 @@ WebSocketImpl::Init(JSContext* aCx,
   if (NS_FAILED(InitializeConnection(aPrincipal))) {
     *aConnectionFailed = true;
   } else {
     *aConnectionFailed = false;
   }
 }
 
 void
-WebSocketImpl::AsyncOpen(nsIPrincipal* aPrincipal, ErrorResult& aRv)
+WebSocketImpl::AsyncOpen(nsIPrincipal* aPrincipal, uint64_t aInnerWindowID,
+                         ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread(), "Not running on main thread");
 
   nsCString asciiOrigin;
   aRv = nsContentUtils::GetASCIIOrigin(aPrincipal, asciiOrigin);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 
   ToLowerCase(asciiOrigin);
 
   nsCOMPtr<nsIURI> uri;
   aRv = NS_NewURI(getter_AddRefs(uri), mURI);
   MOZ_ASSERT(!aRv.Failed());
 
-  aRv = mChannel->AsyncOpen(uri, asciiOrigin, this, nullptr);
+  aRv = mChannel->AsyncOpen(uri, asciiOrigin, aInnerWindowID, this, nullptr);
   if (NS_WARN_IF(aRv.Failed())) {
     return;
   }
 }
 
 //-----------------------------------------------------------------------------
 // WebSocketImpl methods:
 //-----------------------------------------------------------------------------
--- a/dom/push/PushServiceWebSocket.jsm
+++ b/dom/push/PushServiceWebSocket.jsm
@@ -633,17 +633,17 @@ this.PushServiceWebSocket = {
 
     debug("serverURL: " + uri.spec);
     this._wsListener = new PushWebSocketListener(this);
     this._ws.protocol = "push-notification";
 
     try {
       // Grab a wakelock before we open the socket to ensure we don't go to
       // sleep before connection the is opened.
-      this._ws.asyncOpen(uri, uri.spec, this._wsListener, null);
+      this._ws.asyncOpen(uri, uri.spec, 0, this._wsListener, null);
       this._acquireWakeLock();
       this._currentState = STATE_WAITING_FOR_WS_START;
     } catch(e) {
       debug("Error opening websocket. asyncOpen failed!");
       this._reconnect();
     }
   },
 
--- a/dom/push/test/xpcshell/head.js
+++ b/dom/push/test/xpcshell/head.js
@@ -274,17 +274,17 @@ MockWebSocket.prototype = {
     Ci.nsISupports,
     Ci.nsIWebSocketChannel
   ]),
 
   get originalURI() {
     return this._originalURI;
   },
 
-  asyncOpen(uri, origin, listener, context) {
+  asyncOpen(uri, origin, windowId, listener, context) {
     this._listener = listener;
     this._context = context;
     waterfall(() => this._listener.onStart(this._context));
   },
 
   _handleMessage(msg) {
     let messageType, request;
     if (msg == '{}') {
--- a/dom/simplepush/PushService.jsm
+++ b/dom/simplepush/PushService.jsm
@@ -842,17 +842,17 @@ this.PushService = {
 
     debug("serverURL: " + uri.spec);
     this._wsListener = new PushWebSocketListener(this);
     this._ws.protocol = "push-notification";
 
     try {
       // Grab a wakelock before we open the socket to ensure we don't go to sleep
       // before connection the is opened.
-      this._ws.asyncOpen(uri, serverURL, this._wsListener, null);
+      this._ws.asyncOpen(uri, serverURL, 0, this._wsListener, null);
       this._acquireWakeLock();
       this._currentState = STATE_WAITING_FOR_WS_START;
     } catch(e) {
       debug("Error opening websocket. asyncOpen failed!");
       this._shutdownWS();
       this._reconnectAfterBackoff();
     }
   },
--- a/netwerk/protocol/websocket/PWebSocket.ipdl
+++ b/netwerk/protocol/websocket/PWebSocket.ipdl
@@ -21,16 +21,17 @@ namespace net {
 async protocol PWebSocket
 {
   manager PNecko;
 
 parent:
   // Forwarded methods corresponding to methods on nsIWebSocketChannel
   AsyncOpen(URIParams aURI,
             nsCString aOrigin,
+            uint64_t aInnerWindowID,
             nsCString aProtocol,
             bool aSecure,
             // ping values only meaningful if client set them
             uint32_t aPingInterval,
             bool aClientSetPingInterval,
             uint32_t aPingTimeout,
             bool aClientSetPingTimeout,
             OptionalLoadInfoArgs aLoadInfoArgs);
--- a/netwerk/protocol/websocket/WebSocketChannel.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannel.cpp
@@ -3109,16 +3109,17 @@ WebSocketChannel::GetSecurityInfo(nsISup
   }
   return NS_OK;
 }
 
 
 NS_IMETHODIMP
 WebSocketChannel::AsyncOpen(nsIURI *aURI,
                             const nsACString &aOrigin,
+                            uint64_t aInnerWindowID,
                             nsIWebSocketListener *aListener,
                             nsISupports *aContext)
 {
   LOG(("WebSocketChannel::AsyncOpen() %p\n", this));
 
   if (!NS_IsMainThread()) {
     MOZ_ASSERT(false, "not main thread");
     LOG(("WebSocketChannel::AsyncOpen() called off the main thread"));
@@ -3215,16 +3216,17 @@ WebSocketChannel::AsyncOpen(nsIURI *aURI
     // an error here instead of queueing
     return NS_ERROR_SOCKET_CREATE_FAILED;
   }
 
   mOriginalURI = aURI;
   mURI = mOriginalURI;
   mURI->GetHostPort(mHost);
   mOrigin = aOrigin;
+  mInnerWindowID = aInnerWindowID;
 
   nsCOMPtr<nsIURI> localURI;
   nsCOMPtr<nsIChannel> localChannel;
 
   mURI->Clone(getter_AddRefs(localURI));
   if (mEncrypted)
     rv = localURI->SetScheme(NS_LITERAL_CSTRING("https"));
   else
--- a/netwerk/protocol/websocket/WebSocketChannel.h
+++ b/netwerk/protocol/websocket/WebSocketChannel.h
@@ -83,16 +83,17 @@ public:
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSICHANNELEVENTSINK
   NS_DECL_NSIOBSERVER
 
   // nsIWebSocketChannel methods BaseWebSocketChannel didn't implement for us
   //
   NS_IMETHOD AsyncOpen(nsIURI *aURI,
                        const nsACString &aOrigin,
+                       uint64_t aWindowID,
                        nsIWebSocketListener *aListener,
                        nsISupports *aContext) override;
   NS_IMETHOD Close(uint16_t aCode, const nsACString & aReason) override;
   NS_IMETHOD SendMsg(const nsACString &aMsg) override;
   NS_IMETHOD SendBinaryMsg(const nsACString &aMsg) override;
   NS_IMETHOD SendBinaryStream(nsIInputStream *aStream, uint32_t length) override;
   NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo) override;
 
@@ -222,16 +223,18 @@ private:
   nsCOMPtr<nsITimer>              mPingTimer;
 
   nsCOMPtr<nsITimer>              mLingeringCloseTimer;
   const static int32_t            kLingeringCloseTimeout =   1000;
   const static int32_t            kLingeringCloseThreshold = 50;
 
   int32_t                         mMaxConcurrentConnections;
 
+  uint64_t                        mInnerWindowID;
+
   // following members are accessed only on the main thread
   uint32_t                        mGotUpgradeOK              : 1;
   uint32_t                        mRecvdHttpUpgradeTransport : 1;
   uint32_t                        mAutoFollowRedirects       : 1;
   uint32_t                        mAllowPMCE                 : 1;
   uint32_t                                                   : 0;
 
   // following members are accessed only on the socket thread
--- a/netwerk/protocol/websocket/WebSocketChannelChild.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.cpp
@@ -451,16 +451,17 @@ WebSocketChannelChild::OnServerClose(con
     mListenerMT->mListener->OnServerClose(mListenerMT->mContext, aCode,
                                           aReason);
   }
 }
 
 NS_IMETHODIMP
 WebSocketChannelChild::AsyncOpen(nsIURI *aURI,
                                  const nsACString &aOrigin,
+                                 uint64_t aInnerWindowID,
                                  nsIWebSocketListener *aListener,
                                  nsISupports *aContext)
 {
   LOG(("WebSocketChannelChild::AsyncOpen() %p\n", this));
 
   MOZ_ASSERT(NS_IsMainThread(), "not main thread");
   MOZ_ASSERT(aURI && aListener && !mListenerMT,
              "Invalid state for WebSocketChannelChild::AsyncOpen");
@@ -484,18 +485,18 @@ WebSocketChannelChild::AsyncOpen(nsIURI 
   AddIPDLReference();
 
   OptionalLoadInfoArgs loadInfoArgs;
   nsresult rv = LoadInfoToLoadInfoArgs(mLoadInfo, &loadInfoArgs);
   NS_ENSURE_SUCCESS(rv, rv);
 
   gNeckoChild->SendPWebSocketConstructor(this, tabChild,
                                          IPC::SerializedLoadContext(this));
-  if (!SendAsyncOpen(uri, nsCString(aOrigin), mProtocol, mEncrypted,
-                     mPingInterval, mClientSetPingInterval,
+  if (!SendAsyncOpen(uri, nsCString(aOrigin), aInnerWindowID, mProtocol,
+                     mEncrypted, mPingInterval, mClientSetPingInterval,
                      mPingResponseTimeout, mClientSetPingTimeout, loadInfoArgs)) {
     return NS_ERROR_UNEXPECTED;
   }
 
   mOriginalURI = aURI;
   mURI = mOriginalURI;
   mListenerMT = new ListenerAndContextContainer(aListener, aContext);
   mOrigin = aOrigin;
--- a/netwerk/protocol/websocket/WebSocketChannelChild.h
+++ b/netwerk/protocol/websocket/WebSocketChannelChild.h
@@ -24,17 +24,19 @@ class WebSocketChannelChild final : publ
   explicit WebSocketChannelChild(bool aSecure);
 
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSITHREADRETARGETABLEREQUEST
 
   // nsIWebSocketChannel methods BaseWebSocketChannel didn't implement for us
   //
   NS_IMETHOD AsyncOpen(nsIURI *aURI, const nsACString &aOrigin,
-                       nsIWebSocketListener *aListener, nsISupports *aContext) override;
+                       uint64_t aInnerWindowID,
+                       nsIWebSocketListener *aListener,
+                       nsISupports *aContext) override;
   NS_IMETHOD Close(uint16_t code, const nsACString & reason) override;
   NS_IMETHOD SendMsg(const nsACString &aMsg) override;
   NS_IMETHOD SendBinaryMsg(const nsACString &aMsg) override;
   NS_IMETHOD SendBinaryStream(nsIInputStream *aStream, uint32_t aLength) override;
   nsresult SendBinaryStream(OptionalInputStreamParams *aStream, uint32_t aLength);
   NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo) override;
 
   void AddIPDLReference();
--- a/netwerk/protocol/websocket/WebSocketChannelParent.cpp
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.cpp
@@ -55,16 +55,17 @@ WebSocketChannelParent::RecvDeleteSelf()
   mChannel = nullptr;
   mAuthProvider = nullptr;
   return mIPCOpen ? Send__delete__(this) : true;
 }
 
 bool
 WebSocketChannelParent::RecvAsyncOpen(const URIParams& aURI,
                                       const nsCString& aOrigin,
+                                      const uint64_t& aInnerWindowID,
                                       const nsCString& aProtocol,
                                       const bool& aSecure,
                                       const uint32_t& aPingInterval,
                                       const bool& aClientSetPingInterval,
                                       const uint32_t& aPingTimeout,
                                       const bool& aClientSetPingTimeout,
                                       const OptionalLoadInfoArgs& aLoadInfoArgs)
 {
@@ -123,17 +124,17 @@ WebSocketChannelParent::RecvAsyncOpen(co
     MOZ_ASSERT(aPingInterval >= 1000 && !(aPingInterval % 1000));
     mChannel->SetPingInterval(aPingInterval / 1000);
   }
   if (aClientSetPingTimeout) {
     MOZ_ASSERT(aPingTimeout >= 1000 && !(aPingTimeout % 1000));
     mChannel->SetPingTimeout(aPingTimeout / 1000);
   }
 
-  rv = mChannel->AsyncOpen(uri, aOrigin, this, nullptr);
+  rv = mChannel->AsyncOpen(uri, aOrigin, aInnerWindowID, this, nullptr);
   if (NS_FAILED(rv))
     goto fail;
 
   return true;
 
 fail:
   mChannel = nullptr;
   return SendOnStop(rv);
--- a/netwerk/protocol/websocket/WebSocketChannelParent.h
+++ b/netwerk/protocol/websocket/WebSocketChannelParent.h
@@ -35,16 +35,17 @@ class WebSocketChannelParent : public PW
 
   WebSocketChannelParent(nsIAuthPromptProvider* aAuthProvider,
                          nsILoadContext* aLoadContext,
                          PBOverrideStatus aOverrideStatus);
 
  private:
   bool RecvAsyncOpen(const URIParams& aURI,
                      const nsCString& aOrigin,
+                     const uint64_t& aInnerWindowID,
                      const nsCString& aProtocol,
                      const bool& aSecure,
                      const uint32_t& aPingInterval,
                      const bool& aClientSetPingInterval,
                      const uint32_t& aPingTimeout,
                      const bool& aClientSetPingTimeout,
                      const OptionalLoadInfoArgs& aLoadInfoArgs) override;
   bool RecvClose(const uint16_t & code, const nsCString & reason) override;
--- a/netwerk/protocol/websocket/nsIWebSocketChannel.idl
+++ b/netwerk/protocol/websocket/nsIWebSocketChannel.idl
@@ -17,17 +17,17 @@ interface nsIPrincipal;
 
 /**
  * Low-level websocket API: handles network protocol.  
  *
  * This is primarly intended for use by the higher-level nsIWebSocket.idl.
  * We are also making it scriptable for now, but this may change once we have
  * WebSockets for Workers.
  */
-[scriptable, uuid(21217c03-2ff7-4f9c-9d10-6d3d94a7d843)]
+[scriptable, uuid(352e0c08-f14c-40c8-ad06-2f8bb5d9d9e0)]
 interface nsIWebSocketChannel : nsISupports
 {
     /**
      * The original URI used to construct the protocol connection. This is used
      * in the case of a redirect or URI "resolution" (e.g. resolving a
      * resource: URI to a file: URI) so that the original pre-redirect
      * URI can still be obtained.  This is never null.
      */
@@ -133,21 +133,23 @@ interface nsIWebSocketChannel : nsISuppo
      * after asyncOpen returns.  If asyncOpen returns successfully, the
      * protocol implementation promises to call at least onStop on the listener.
      *
      * NOTE: Implementations should throw NS_ERROR_ALREADY_OPENED if the
      * websocket connection is reopened.
      *
      * @param aURI the uri of the websocket protocol - may be redirected
      * @param aOrigin the uri of the originating resource
+     * @param aInnerWindowID the inner window ID
      * @param aListener the nsIWebSocketListener implementation
      * @param aContext an opaque parameter forwarded to aListener's methods
      */
     void asyncOpen(in nsIURI aURI,
                    in ACString aOrigin,
+                   in unsigned long long aInnerWindowID,
                    in nsIWebSocketListener aListener,
                    in nsISupports aContext);
 
     /*
      * Close the websocket connection for writing - no more calls to sendMsg
      * or sendBinaryMsg should be made after calling this. The listener object
      * may receive more messages if a server close has not yet been received.
      *
--- a/netwerk/test/unit/test_dns_proxy_bypass.js
+++ b/netwerk/test/unit/test_dns_proxy_bypass.js
@@ -66,12 +66,12 @@ function run_test() {
 
   chan.initLoadInfo(null, // aLoadingNode
                     Services.scriptSecurityManager.getSystemPrincipal(),
                     null, // aTriggeringPrincipal
                     Ci.nsILoadInfo.SEC_NORMAL,
                     Ci.nsIContentPolicy.TYPE_WEBSOCKET);
 
   var uri = ioService.newURI(url, null, null);
-  chan.asyncOpen(uri, url, listener, null);
+  chan.asyncOpen(uri, url, 0, listener, null);
   do_test_pending();
 }
 
--- a/netwerk/test/unit/test_websocket_offline.js
+++ b/netwerk/test/unit/test_websocket_offline.js
@@ -37,15 +37,15 @@ function run_test() {
       createInstance(Components.interfaces.nsIWebSocketChannel);
     chan.initLoadInfo(null, // aLoadingNode
                       Services.scriptSecurityManager.getSystemPrincipal(),
                       null, // aTriggeringPrincipal
                       Ci.nsILoadInfo.SEC_NORMAL,
                       Ci.nsIContentPolicy.TYPE_WEBSOCKET);
 
     var uri = Services.io.newURI(url, null, null);
-    chan.asyncOpen(uri, url, listener, null);
+    chan.asyncOpen(uri, url, 0, listener, null);
     do_test_pending();
   } catch (x) {
     dump("throwing " + x);
     do_throw(x);
   }
 }