backout Bug 784816 https://hg.mozilla.org/mozilla-central/rev/1000c23df772 for breaking multi-process TCPSocket SSL connections
authorAndrew Sutherland <asutherland@asutherland.org>
Sun, 08 Sep 2013 11:22:44 +0200
changeset 146077 7bf2b6cf8d730cc9d36d1cbfb627d1674b725f14
parent 146076 9e839e0432ebed639ed1af98601d70e4913e8eaa
child 146080 0899b763a06608d2ecab5f2e2b96b437e828de32
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
bugs784816
milestone26.0a1
backout Bug 784816 https://hg.mozilla.org/mozilla-central/rev/1000c23df772 for breaking multi-process TCPSocket SSL connections
dom/network/interfaces/nsIDOMTCPSocket.idl
dom/network/interfaces/nsITCPSocketChild.idl
dom/network/src/PTCPSocket.ipdl
dom/network/src/TCPSocket.js
dom/network/src/TCPSocketChild.cpp
dom/network/src/TCPSocketParent.cpp
dom/network/src/TCPSocketParent.h
--- a/dom/network/interfaces/nsIDOMTCPSocket.idl
+++ b/dom/network/interfaces/nsIDOMTCPSocket.idl
@@ -27,29 +27,29 @@ interface nsISocketTransport;
 //  Once bug 723206 will be fixed, this method could be replaced by
 //  arguments when instantiating a TCPSocket object. For example it will
 //  be possible to do (similarly to the WebSocket API):
 //    var s = new MozTCPSocket(host, port); 
 
 // Bug 797561 - Expose a server tcp socket API to web applications
 
 
-[scriptable, uuid(65f6d2c8-4be6-4695-958d-0735e8935289)]
+[scriptable, uuid(b7803a0b-4492-45ec-ac7a-3e29f6445fa4)]
 interface nsIDOMTCPSocket : nsISupports
 {
   /**
    * Create and return a socket object which will attempt to connect to
    * the given host and port.
    *
    * @param host The hostname of the server to connect to.
    * @param port The port to connect to.
    * @param options An object specifying one or more parameters which
    *                determine the details of the socket.
    *
-   *        useSecureTransport: true to create an SSL socket. Defaults to false.
+   *        useSSL: true to create an SSL socket. Defaults to false.
    *
    *        binaryType: "arraybuffer" to use ArrayBuffer
    *          instances in the ondata callback and as the argument
    *          to send. Defaults to "string", to use JavaScript strings.
    *
    * @return The new TCPSocket instance.
    */
   nsIDOMTCPSocket open(in DOMString host, in unsigned short port, [optional] in jsval options);
@@ -70,21 +70,16 @@ interface nsIDOMTCPSocket : nsISupports
    *                Pass -1 to use the default value.
    *
    * @return The new TCPServerSocket instance.
    */
   nsIDOMTCPServerSocket listen(in unsigned short localPort, [optional] in jsval options,
                                [optional] in unsigned short backlog);
 
   /**
-   * Enable secure on channel.
-   */
-  void upgradeToSecure();
-
-  /**
    * The host of this socket object.
    */
   readonly attribute DOMString host;
 
   /**
    * The port of this socket object.
    */
   readonly attribute unsigned short port;
--- a/dom/network/interfaces/nsITCPSocketChild.idl
+++ b/dom/network/interfaces/nsITCPSocketChild.idl
@@ -3,32 +3,31 @@
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "domstubs.idl"
 
 interface nsITCPSocketInternal;
 interface nsIDOMWindow;
 
 // Interface to allow the content process socket to reach the IPC bridge.
-[scriptable, uuid(ada5342d-6d45-4ff1-a7d3-6a4b150d0385)]
+[scriptable, uuid(edf07a93-36a6-4574-8e23-40f64ab5f596)]
 interface nsITCPSocketChild : nsISupports
 {
   // Tell the chrome process to open a corresponding connection with the given parameters
   [implicit_jscontext]
   void open(in nsITCPSocketInternal socket, in DOMString host,
             in unsigned short port, in boolean ssl, in DOMString binaryType,
             in nsIDOMWindow window, in jsval windowVal);
 
   // Tell the chrome process to perform equivalent operations to all following methods
   [implicit_jscontext] 
   void send(in jsval data, in unsigned long byteOffset, in unsigned long byteLength);
   void resume();
   void suspend();
   void close();
-  void startTLS();
 
   /**
    * Initialize the TCP socket on the child side for IPC. It is called from the child side,
    * which is generated in receiving a notification of accepting any open request
    * on the parent side. We use single implementation that works on a child process 
    * as well as in the single process model.
    *
    * @param socket
--- a/dom/network/src/PTCPSocket.ipdl
+++ b/dom/network/src/PTCPSocket.ipdl
@@ -32,17 +32,16 @@ namespace net {
 //-------------------------------------------------------------------
 protocol PTCPSocket
 {
   manager PNecko;
 
 parent:
   Open(nsString host, uint16_t port, bool useSSL, nsString binaryType);
   Data(SendableData data);
-  StartTLS();
   Suspend();
   Resume();
   Close();
 
 child:
   Callback(nsString type, CallbackData data,
            nsString readyState, uint32_t bufferedAmount);
 
--- a/dom/network/src/TCPSocket.js
+++ b/dom/network/src/TCPSocket.js
@@ -152,20 +152,16 @@ TCPSocket.prototype = {
   _suspendCount: 0,
 
   // Reported parent process buffer
   _bufferedAmount: 0,
 
   // IPC socket actor
   _socketBridge: null,
 
-  // StartTLS
-  _waitingForStartTLS: false,
-  _pendingDataAfterStartTLS: [],
-
   // Public accessors.
   get readyState() {
     return this._readyState;
   },
   get binaryType() {
     return this._binaryType;
   },
   get host() {
@@ -209,33 +205,29 @@ TCPSocket.prototype = {
   },
   get onclose() {
     return this._onclose;
   },
   set onclose(f) {
     this._onclose = f;
   },
 
-  _activateTLS: function() {
-    let securityInfo = this._transport.securityInfo
-          .QueryInterface(Ci.nsISSLSocketControl);
-    securityInfo.StartTLS();
-  },
-
   // Helper methods.
   _createTransport: function ts_createTransport(host, port, sslMode) {
-    let options;
-    if (sslMode === 'ssl') {
-      options = ['ssl'];
+    let options, optlen;
+    if (sslMode) {
+      options = [sslMode];
+      optlen = 1;
     } else {
-      options = ['starttls'];
+      options = null;
+      optlen = 0;
     }
     return Cc["@mozilla.org/network/socket-transport-service;1"]
              .getService(Ci.nsISocketTransportService)
-             .createTransport(options, 1, host, port, null);
+             .createTransport(options, optlen, host, port, null);
   },
 
   _ensureCopying: function ts_ensureCopying() {
     let self = this;
     if (this._asyncCopierActive) {
       return;
     }
     this._asyncCopierActive = true;
@@ -251,31 +243,16 @@ TCPSocket.prototype = {
           // onStopRequest for inbound data.
           self._maybeReportErrorAndCloseIfOpen(status);
           return;
         }
 
         if (self._multiplexStream.count) {
           self._ensureCopying();
         } else {
-          // If we are waiting for initiating starttls, we can begin to
-          // activate tls now.
-          if (self._waitingForStartTLS && self._readyState == kOPEN) {
-            self._activateTLS();
-            self._waitingForStartTLS = false;
-            // If we have pending data, we should send them, or fire
-            // a drain event if we are waiting for it.
-            if (self._pendingDataAfterStartTLS.length > 0) {
-              while (self._pendingDataAfterStartTLS.length)
-                self._multiplexStream.appendStream(self._pendingDataAfterStartTLS.shift());
-              self._ensureCopying();
-              return;
-            }
-          }
-
           if (self._waitingForDrain) {
             self._waitingForDrain = false;
             self.callListener("drain");
           }
           if (self._readyState === kCLOSING) {
             self._socketOutputStream.close();
             self._readyState = kCLOSED;
             self.callListener("close");
@@ -453,17 +430,17 @@ TCPSocket.prototype = {
 
     LOG("startup called");
     LOG("Host info: " + host + ":" + port);
 
     that._readyState = kCONNECTING;
     that._host = host;
     that._port = port;
     if (options !== undefined) {
-      if (options.useSecureTransport) {
+      if (options.useSSL) {
           that._ssl = 'ssl';
       } else {
           that._ssl = false;
       }
       that._binaryType = options.binaryType || that._binaryType;
     }
 
     LOG("SSL: " + that.ssl);
@@ -476,40 +453,17 @@ TCPSocket.prototype = {
       return that;
     }
 
     let transport = that._transport = this._createTransport(host, port, that._ssl);
     transport.setEventSink(that, Services.tm.currentThread);
     that._initStream(that._binaryType);
     return that;
   },
-
-  upgradeToSecure: function ts_upgradeToSecure() {
-    if (this._readyState !== kOPEN) {
-      throw new Error("Socket not open.");
-    }
-    if (this._ssl == 'ssl') {
-      // Already SSL
-      return;
-    }
-
-    this._ssl = 'ssl';
-
-    if (this._inChild) {
-      this._socketBridge.startTLS();
-      return;
-    }
-
-    if (this._multiplexStream.count == 0) {
-      this._activateTLS();
-    } else {
-      this._waitingForStartTLS = true;
-    }
-  },
-
+  
   listen: function ts_listen(localPort, options, backlog) {
     if (!this.initWindowless())
       return null;
 
     // in the testing case, init won't be called and
     // hasPrivileges will be null. We want to proceed to test.
     if (this._hasPrivileges !== true && this._hasPrivileges !== null) {
       throw new Error("TCPSocket does not have permission in this context.\n");
@@ -565,24 +519,17 @@ TCPSocket.prototype = {
     let new_stream;
     if (this._binaryType === "arraybuffer") {
       new_stream = new ArrayBufferInputStream();
       new_stream.setData(data, byteOffset, byteLength);
     } else {
       new_stream = new StringInputStream();
       new_stream.setData(data, length);
     }
-
-    if (this._waitingForStartTLS) {
-      // When we are waiting for starttls, new_stream is added to pendingData
-      // and will be appended to multiplexStream after tls had been set up.
-      this._pendingDataAfterStartTLS.push(new_stream);
-    } else {
-      this._multiplexStream.appendStream(new_stream);
-    }
+    this._multiplexStream.appendStream(new_stream);
 
     if (newBufferedAmount >= BUFFER_SIZE) {
       // If we buffered more than some arbitrary amount of data,
       // (65535 right now) we should tell the caller so they can
       // wait until ondrain is called if they so desire. Once all the
       //buffered data has been written to the socket, ondrain is
       // called.
       this._waitingForDrain = true;
--- a/dom/network/src/TCPSocketChild.cpp
+++ b/dom/network/src/TCPSocketChild.cpp
@@ -154,23 +154,16 @@ TCPSocketChild::RecvCallback(const nsStr
   } else {
     MOZ_CRASH("Invalid callback type!");
   }
   NS_ENSURE_SUCCESS(rv, true);
   return true;
 }
 
 NS_IMETHODIMP
-TCPSocketChild::StartTLS()
-{
-  SendStartTLS();
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 TCPSocketChild::Suspend()
 {
   SendSuspend();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 TCPSocketChild::Resume()
--- a/dom/network/src/TCPSocketParent.cpp
+++ b/dom/network/src/TCPSocketParent.cpp
@@ -111,25 +111,16 @@ NS_IMETHODIMP
 TCPSocketParent::InitJS(const JS::Value& aIntermediary, JSContext* aCx)
 {
   MOZ_ASSERT(aIntermediary.isObject());
   mIntermediaryObj = &aIntermediary.toObject();
   return NS_OK;
 }
 
 bool
-TCPSocketParent::RecvStartTLS()
-{
-  NS_ENSURE_TRUE(mSocket, true);
-  nsresult rv = mSocket->UpgradeToSecure();
-  NS_ENSURE_SUCCESS(rv, true);
-  return true;
-}
-
-bool
 TCPSocketParent::RecvSuspend()
 {
   NS_ENSURE_TRUE(mSocket, true);
   nsresult rv = mSocket->Suspend();
   NS_ENSURE_SUCCESS(rv, true);
   return true;
 }
 
--- a/dom/network/src/TCPSocketParent.h
+++ b/dom/network/src/TCPSocketParent.h
@@ -42,17 +42,16 @@ public:
   NS_DECL_NSITCPSOCKETPARENT
   NS_IMETHOD_(nsrefcnt) Release() MOZ_OVERRIDE;
 
   TCPSocketParent() : mIntermediaryObj(nullptr) {}
 
   virtual bool RecvOpen(const nsString& aHost, const uint16_t& aPort,
                         const bool& useSSL, const nsString& aBinaryType);
 
-  virtual bool RecvStartTLS() MOZ_OVERRIDE;
   virtual bool RecvSuspend() MOZ_OVERRIDE;
   virtual bool RecvResume() MOZ_OVERRIDE;
   virtual bool RecvClose() MOZ_OVERRIDE;
   virtual bool RecvData(const SendableData& aData) MOZ_OVERRIDE;
   virtual bool RecvRequestDelete() MOZ_OVERRIDE;
 
 private:
   virtual void ActorDestroy(ActorDestroyReason why) MOZ_OVERRIDE;