Bug 955700 - Accounts stuck in the "Connecting…" state, r=florian,clokep.
authoraleth <aleth@instantbird.org>
Fri, 22 Nov 2013 08:39:20 +0100
changeset 19240 d4e6e230a882948b37b3adaf1181d2a59380cde3
parent 19239 bf9bc8d8d719d6865e8ba7169909a5c89fef95a4
child 19241 09c7117e50e3719f41fc9ba996771fe6ddee714d
push id1103
push usermbanner@mozilla.com
push dateTue, 18 Mar 2014 07:44:06 +0000
treeherdercomm-beta@50c6279a0af0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian, clokep
bugs955700
Bug 955700 - Accounts stuck in the "Connecting…" state, r=florian,clokep.
chat/modules/socket.jsm
chat/protocols/irc/irc.js
chat/protocols/yahoo/yahoo-session.jsm
--- a/chat/modules/socket.jsm
+++ b/chat/modules/socket.jsm
@@ -29,17 +29,17 @@
  * High-level properties:
  *   binaryMode
  *   delimiter
  *   inputSegmentSize
  *   outputSegmentSize
  *   proxyFlags
  *   connectTimeout (default is no timeout)
  *   readWriteTimeout (default is no timeout)
- *   isConnected
+ *   disconnected
  *   sslStatus
  *
  * Users should "subclass" this object, i.e. set their .__proto__ to be it. And
  * then implement:
  *   onConnection()
  *   onConnectionHeard()
  *   onConnectionTimedOut()
  *   onConnectionReset()
@@ -140,16 +140,17 @@ const Socket = {
   // Synchronously open a connection.
   connect: function(aHost, aPort, aSecurity, aProxy) {
     if (Services.io.offline)
       throw Cr.NS_ERROR_FAILURE;
 
     this.LOG("Connecting to: " + aHost + ":" + aPort);
     this.host = aHost;
     this.port = aPort;
+    this.disconnected = false;
 
     this._pendingData = [];
     delete this._stopRequestStatus;
 
     // Array of security options
     this.security = aSecurity || [];
 
     // Choose a proxy, use the given one, otherwise get one from the proxy
@@ -205,17 +206,17 @@ const Socket = {
 
     if (this._pingTimer) {
       clearTimeout(this._pingTimer);
       delete this._pingTimer;
       delete this._resetPingTimerPending;
     }
     this.cancelDisconnectTimer();
 
-    delete this.isConnected;
+    this.disconnected = true;
   },
 
   // Listen for a connection on a port.
   // XXX take a timeout and then call stopListening
   listen: function(port) {
     this.LOG("Listening on port " + port);
 
     this.serverSocket = new ServerSocket(port, false, -1);
@@ -265,17 +266,17 @@ const Socket = {
     try {
       // Send the data as a byte array
       this._binaryOutputStream.writeByteArray(byteArray, byteArray.length);
     } catch(e) {
       Cu.reportError(e);
     }
   },
 
-  isConnected: false,
+  disconnected: true,
 
   startTLS: function() {
     this.transport.securityInfo.QueryInterface(Ci.nsISSLSocketControl).StartTLS();
   },
 
   // If using the ping functionality, this should be called whenever a message is
   // received (e.g. when it is known the socket is still open). Calling this for
   // the first time enables the ping functionality.
@@ -343,17 +344,16 @@ const Socket = {
     // Store the values
     this.transport = aTransport;
     this.host = this.transport.host;
     this.port = this.transport.port;
 
     this._resetBuffers();
     this._openStreams();
 
-    this.isConnected = true;
     this.onConnectionHeard();
     this.stopListening();
   },
   // Called when the listening socket stops for some reason.
   // The server socket is effectively dead after this notification.
   onStopListening: function(aSocket, aStatus) {
     this.LOG("onStopListening");
     if ("serverSocket" in this)
@@ -361,17 +361,17 @@ const Socket = {
   },
 
   /*
    * nsIStreamListener methods
    */
   // onDataAvailable, called by Mozilla's networking code.
   // Buffers the data, and parses it into discrete messages.
   onDataAvailable: function(aRequest, aContext, aInputStream, aOffset, aCount) {
-    if (!this.isConnected)
+    if (this.disconnected)
       return;
     if (this.binaryMode) {
       // Load the data from the stream
       this._incomingDataBuffer = this._incomingDataBuffer
                                      .concat(this._binaryInputStream
                                                  .readByteArray(aCount));
 
       let size = this._incomingDataBuffer.length;
@@ -443,31 +443,31 @@ const Socket = {
    * nsIRequestObserver methods
    */
   // Signifies the beginning of an async request
   onStartRequest: function(aRequest, aContext) {
     this.DEBUG("onStartRequest");
   },
   // Called to signify the end of an asynchronous request.
   onStopRequest: function(aRequest, aContext, aStatus) {
-    if (!this.isConnected) {
+    if (this.disconnected) {
       // We're already disconnected, so nothing left to do here.
       return;
     }
 
     this.DEBUG("onStopRequest (" + aStatus + ")");
     this._stopRequestStatus = aStatus;
     // The stop request will be handled when the queue is next empty.
     this._activateQueue();
   },
   // Close the connection after receiving a stop request.
   _handleStopRequest: function(aStatus) {
-    if (!this.isConnected)
+    if (this.disconnected)
       return;
-    delete this.isConnected;
+    this.disconnected = true;
     if (aStatus == NS_ERROR_NET_RESET)
       this.onConnectionReset();
     else if (aStatus == NS_ERROR_NET_TIMEOUT)
       this.onConnectionTimedOut();
     else if (!Components.isSuccessCode(aStatus)) {
       let nssErrorsService =
         Cc["@mozilla.org/nss_errors_service;1"].getService(Ci.nsINSSErrorsService);
       if ((aStatus <= nssErrorsService.getXPCOMFromNSSError(nssErrorsService.NSS_SEC_ERROR_BASE) &&
@@ -519,17 +519,16 @@ const Socket = {
          0x804b0005: "STATUS_SENDING_TO",
          0x804b000a: "STATUS_WAITING_FOR",
          0x804b0006: "STATUS_RECEIVING_FROM"
     };
     let status = nsITransportEventSinkStatus[aStatus];
     this.DEBUG("onTransportStatus(" + (status || ("0x" + aStatus.toString(16))) +")");
 
     if (status == "STATUS_CONNECTED_TO") {
-      this.isConnected = true;
       // Notify that the connection has been established.
       this.onConnection();
     }
   },
 
   /*
    *****************************************************************************
    ****************************** Private methods ******************************
--- a/chat/protocols/irc/irc.js
+++ b/chat/protocols/irc/irc.js
@@ -1213,17 +1213,17 @@ ircAccount.prototype = {
       // The nick we were about to try next is our current nick. This means
       // the user attempted to change to a version of the nick with a lower or
       // absent number suffix, and this failed.
       let msg = _("message.nick.fail", this._nickname);
       for each (let conversation in this._conversations)
         conversation.writeMessage(this._nickname, msg, {system: true});
       return true;
     }
-  
+
     this.LOG(aOldNick + " is already in use, trying " + newNick);
     this.sendMessage("NICK", newNick); // Nick message.
     return true;
   },
 
   handlePingReply: function(aSource, aPongTime) {
     // Received PING response, display to the user.
     let sentTime = new Date(parseInt(aPongTime, 10));
@@ -1378,17 +1378,17 @@ ircAccount.prototype = {
   },
   // When the user clicks "Disconnect" in account manager, or uses /quit.
   // aMessage is an optional parameter containing the quit message.
   disconnect: function(aMessage) {
     if (this.disconnected || this.disconnecting)
       return;
 
     // If there's no socket, disconnect immediately to avoid waiting 2 seconds.
-    if (!this._socket || !this._socket.isConnected) {
+    if (!this._socket || this._socket.disconnected) {
       this.gotDisconnected();
       return;
     }
 
     // Let the server know we're going to disconnect.
     this.quit(aMessage);
 
     // Reset original nickname for the next reconnect.
@@ -1520,17 +1520,17 @@ ircAccount.prototype = {
   // Returns false if the message could not be sent.
   sendRawMessage: function(aMessage, aLoggedData) {
     // Low level quoting, replace \0, \n, \r or \020 with \0200, \020n, \020r or
     // \020\020, respectively.
     const lowQuote = {"\0": "0", "\n": "n", "\r": "r", "\x10": "\x10"};
     const lowRegex = new RegExp("[" + Object.keys(lowQuote).join("") + "]", "g");
     aMessage = aMessage.replace(lowRegex, function(aChar) "\x10" + lowQuote[aChar]);
 
-    if (!this._socket || !this._socket.isConnected) {
+    if (!this._socket || this._socket.disconnected) {
       this.gotDisconnected(Ci.prplIAccount.ERROR_NETWORK_ERROR,
                            _("connection.error.lost"));
     }
 
     let length = this.countBytes(aMessage) + 2;
     if (length > this.maxMessageLength) {
       // Log if the message is too long, but try to send it anyway.
       this.WARN("Message length too long (" + length + " > " +
--- a/chat/protocols/yahoo/yahoo-session.jsm
+++ b/chat/protocols/yahoo/yahoo-session.jsm
@@ -372,17 +372,17 @@ YahooSession.prototype = {
   // Callbacks.
   onLoginComplete: function() {
     this._account.reportConnected();
     this._account.onLoginComplete();
   },
 
   onSessionError: function(aError, aMessage) {
     this._account.reportDisconnecting(aError, aMessage);
-    if (this.isConnected)
+    if (!this.disconnected)
       this.disconnect();
     this._account.reportDisconnected();
   },
 
   // Private methods.
 
   // Socket Event Callbacks.
   LOG: function(aString) this._account.LOG(aString),
@@ -964,17 +964,17 @@ const YahooPacketHandler = {
   // TODO - Make use of the icon checksum to allow icon caching.
   0xbd: function(aPacket) {
     // Extract the checksum from the URL parameter chksum.
     let buddyName = aPacket.getValue(4);
     let url = aPacket.getValue(20);
     let parameter = "chksum=";
     // The "chksum" parameter is the only parameter in the URL.
     let checksum = url.substring(url.indexOf(parameter) + parameter.length);
-    
+
     let buddy = this.getBuddy(buddyName);
     // We only download the new icon if no older checksum exists, or if the
     // older checksum differs, indicating an updated icon.
     if (buddy && buddy.iconChecksum !== checksum) {
       buddy.buddyIconFilename = url;
       buddy.iconChecksum = checksum;
     }
   },
@@ -991,17 +991,17 @@ const YahooPacketHandler = {
                                       kBuddyStatuses[aPacket.getValue(10)];
 
     let message = aPacket.hasKey(19) ? aPacket.getValue(19) : "";
     this.setBuddyStatus(name, status, message);
   },
 
   // Buddy avatar (icon) update.
   0xc7: function(aPacket) {
-    // Strangely, in some non-official clients, when someone updates their 
+    // Strangely, in some non-official clients, when someone updates their
     // profile icon we are sent two avatar update packets: one with a default
     // status containing little information, and another with a Server Ack
     // status containing the info we need. So we only accept packets with a
     // Server Ack status to prevent errors.
     if (aPacket.status != kPacketStatuses.ServerAck)
       return;
     // Key 4 contains the name of the buddy who updated their icon.
     this._session.requestBuddyIcon(aPacket.getValue(4));