Bug 994337 - Force sending strings over TCPSocket when strings are required. r=asuth
authorJosh Matthews <josh@joshmatthews.net>
Tue, 02 Jun 2015 22:02:27 -0400
changeset 246879 3d1610589d6a81bfc31ead1a0071aed769e0ea0b
parent 246878 85056bd118ed82eb2b2595d1b43b86d0387c6a4c
child 246880 9e1033e7aaf4c37b948c5ed899270f12361805e5
push id28843
push usercbook@mozilla.com
push dateWed, 03 Jun 2015 11:50:02 +0000
treeherdermozilla-central@6c612d7adbf5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs994337
milestone41.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 994337 - Force sending strings over TCPSocket when strings are required. r=asuth
dom/network/TCPSocket.js
dom/network/tests/test_tcpsocket_client_and_server_basics.js
--- a/dom/network/TCPSocket.js
+++ b/dom/network/TCPSocket.js
@@ -685,24 +685,26 @@ TCPSocket.prototype = {
 
   send: function ts_send(data, byteOffset, byteLength) {
     if (this._readyState !== kOPEN) {
       throw new Error("Socket not open.");
     }
 
     if (this._binaryType === "arraybuffer") {
       byteLength = byteLength || data.byteLength;
+    } else {
+      data = data.toString();
+      byteLength = data.length;
     }
 
     if (this._inChild) {
       this._socketBridge.sendSend(data, byteOffset, byteLength, ++this._trackingNumber);
     }
 
-    let length = this._binaryType === "arraybuffer" ? byteLength : data.length;
-    let newBufferedAmount = this.bufferedAmount + length;
+    let newBufferedAmount = this.bufferedAmount + byteLength;
     let bufferFull = newBufferedAmount >= BUFFER_SIZE;
 
     if (bufferFull) {
       // 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.
@@ -717,32 +719,32 @@ 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);
+      new_stream.setData(data, byteLength);
     }
 
     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._ensureCopying();
 
 #ifdef MOZ_WIDGET_GONK
     // Collect transmitted amount for network statistics.
-    this._txBytes += length;
+    this._txBytes += byteLength;
     this._saveNetworkStats(false);
 #endif
 
     return !bufferFull;
   },
 
   suspend: function ts_suspend() {
     if (this._inChild) {
--- a/dom/network/tests/test_tcpsocket_client_and_server_basics.js
+++ b/dom/network/tests/test_tcpsocket_client_and_server_basics.js
@@ -341,16 +341,40 @@ function* test_basics() {
     bigUint8Array.length);
   assertUint8ArraysEqual(serverReceived, bigUint8Array,
                          'server received/client sent');
   // And a close.
   is((yield serverQueue.waitForEvent()).type, 'close',
      'The drain event should fire after a large send that returned true.');
 
 
+  // -- Re-establish connection
+  connectedPromise = waitForConnection(listeningServer);
+  clientSocket = TCPSocket.open('127.0.0.1', serverPort,
+                                { binaryType: 'string' });
+  clientQueue = listenForEventsOnSocket(clientSocket, 'client');
+  is((yield clientQueue.waitForEvent()).type, 'open', 'got open event');
+
+  connectedResult = yield connectedPromise;
+  // destructuring assignment is not yet ES6 compliant, must manually unpack
+  serverSocket = connectedResult.socket;
+  serverQueue = connectedResult.queue;
+
+  // -- Attempt to send non-string data.
+  is(clientSocket.send(bigUint8Array), true,
+     'Client sending a large non-string should only send a small string.');
+  clientSocket.close();
+  // The server will get its data
+  serverReceived = yield serverQueue.waitForDataWithAtLeastLength(
+    bigUint8Array.toString().length);
+  // Then we'll get a close
+  is((yield clientQueue.waitForEvent()).type, 'close',
+     'The close event should fire after the drain event.');
+
+
   // -- Close the listening server (and try to connect)
   // We want to verify that the server actually closes / stops listening when
   // we tell it to.
   listeningServer.close();
 
   // - try and connect, get an error
   clientSocket = TCPSocket.open('127.0.0.1', serverPort,
                                 { binaryType: 'arraybuffer' });