diff --git a/js/libtextsecure.js b/js/libtextsecure.js index a701f75de..707cb08a6 100644 --- a/js/libtextsecure.js +++ b/js/libtextsecure.js @@ -38398,7 +38398,6 @@ axolotlInternal.RecipientRecord = function() { TextSecureWebSocket = function (url) { 'use strict'; - var keepAliveTimer; var reconnectSemaphore = 0; var reconnectTimeout = 1000; var socket; @@ -38408,27 +38407,10 @@ TextSecureWebSocket = function (url) { onclose : function() {}, onerror : function() {}, getStatus : function() { return socket.readyState; }, - close : function() { calledClose = true; } + close : function() { calledClose = true; socket.close(); } }; var error; - function resetKeepAliveTimer() { - clearTimeout(keepAliveTimer); - if (calledClose) { return; } - keepAliveTimer = setTimeout(function() { - if (socket.readyState === WebSocket.OPEN) { - socket.send( - new textsecure.protobuf.WebSocketMessage({ - type: textsecure.protobuf.WebSocketMessage.Type.REQUEST, - request: { verb: 'GET', path: '/v1/keepalive' } - }).encode().toArrayBuffer() - ); - } - - resetKeepAliveTimer(); - }, 55000); - }; - function onclose(e) { if (!error && !calledClose) { reconnectSemaphore--; @@ -38448,22 +38430,18 @@ TextSecureWebSocket = function (url) { function onmessage(response) { socketWrapper.onmessage(response); - resetKeepAliveTimer(); }; function send(msg) { - resetKeepAliveTimer(); socket.send(msg); }; function connect() { - clearTimeout(keepAliveTimer); if (++reconnectSemaphore <= 0) { return; } if (socket) { socket.close(); } socket = new WebSocket(url); - socket.onopen = resetKeepAliveTimer; socket.onerror = onerror socket.onclose = onclose; socket.onmessage = onmessage; @@ -38527,6 +38505,10 @@ TextSecureWebSocket = function (url) { window.crypto.getRandomValues(bits); this.id = dcodeIO.Long.fromBits(bits[0], bits[1], true); } + + if (this.body === undefined) { + this.body = null; + } }; var IncomingWebSocketRequest = function(options) { @@ -39507,9 +39489,26 @@ function generateKeys(count, progressCallback) { } } - new WebSocketResource(this.socket, this.handleRequest.bind(this)); + this.wsr = new WebSocketResource(this.socket, this.handleRequest.bind(this)); + this.resetKeepAliveTimer(); + + }, + resetKeepAliveTimer: function() { + clearTimeout(this.keepAliveTimer); + clearTimeout(this.disconnectTimer); + this.keepAliveTimer = setTimeout(function() { + if (this.getStatus() === WebSocket.OPEN) { + this.wsr.sendRequest({ + verb: 'GET', + path: '/v1/keepalive', + success: this.resetKeepAliveTimer.bind(this) + }); + } + this.disconnectTimer = setTimeout(this.socket.close, 30000); + }.bind(this), 55000); }, handleRequest: function(request) { + this.resetKeepAliveTimer(); // TODO: handle different types of requests. for now we only expect // PUT /messages textsecure.crypto.decryptWebsocketMessage(request.body).then(function(plaintext) { diff --git a/libtextsecure/message_receiver.js b/libtextsecure/message_receiver.js index 98960b53f..3dc2e8cd4 100644 --- a/libtextsecure/message_receiver.js +++ b/libtextsecure/message_receiver.js @@ -44,9 +44,26 @@ } } - new WebSocketResource(this.socket, this.handleRequest.bind(this)); + this.wsr = new WebSocketResource(this.socket, this.handleRequest.bind(this)); + this.resetKeepAliveTimer(); + + }, + resetKeepAliveTimer: function() { + clearTimeout(this.keepAliveTimer); + clearTimeout(this.disconnectTimer); + this.keepAliveTimer = setTimeout(function() { + if (this.getStatus() === WebSocket.OPEN) { + this.wsr.sendRequest({ + verb: 'GET', + path: '/v1/keepalive', + success: this.resetKeepAliveTimer.bind(this) + }); + } + this.disconnectTimer = setTimeout(this.socket.close, 30000); + }.bind(this), 55000); }, handleRequest: function(request) { + this.resetKeepAliveTimer(); // TODO: handle different types of requests. for now we only expect // PUT /messages textsecure.crypto.decryptWebsocketMessage(request.body).then(function(plaintext) { diff --git a/libtextsecure/test/message_receiver_test.js b/libtextsecure/test/message_receiver_test.js index 2d50e47c7..fa38969bf 100644 --- a/libtextsecure/test/message_receiver_test.js +++ b/libtextsecure/test/message_receiver_test.js @@ -45,6 +45,21 @@ describe('MessageReceiver', function() { assert.strictEqual(signal.message.body, 'hello'); }); var messageReceiver = new textsecure.MessageReceiver(window); - messageReceiver.connect(); + }); + + it('sends a keepalive once a minute', function(done) { + this.timeout(60000); + var mockServer = new MockServer('ws://localhost:8081'); + mockServer.on('connection', function(server) { + server.on('message', function(data) { + var message = textsecure.protobuf.WebSocketMessage.decode(data); + assert.strictEqual(message.type, textsecure.protobuf.WebSocketMessage.Type.REQUEST); + assert.strictEqual(message.request.verb, 'GET'); + assert.strictEqual(message.request.path, '/v1/keepalive'); + server.close(); + done(); + }); + }); + var messageReceiver = new textsecure.MessageReceiver(window); }); }); diff --git a/libtextsecure/test/websocket_test.js b/libtextsecure/test/websocket_test.js index 008ae937e..ac5c80ad4 100644 --- a/libtextsecure/test/websocket_test.js +++ b/libtextsecure/test/websocket_test.js @@ -75,20 +75,4 @@ describe('TextSecureWebSocket', function() { mockServer.close(); }); - it('sends a keepalive once a minute', function(done) { - this.timeout(60000); - var mockServer = new MockServer('ws://localhost:8081'); - mockServer.on('connection', function(server) { - server.on('message', function(data) { - var message = textsecure.protobuf.WebSocketMessage.decode(data); - assert.strictEqual(message.type, textsecure.protobuf.WebSocketMessage.Type.REQUEST); - assert.strictEqual(message.request.verb, 'GET'); - assert.strictEqual(message.request.path, '/v1/keepalive'); - socket.close(); - server.close(); - done(); - }); - }); - var socket = new TextSecureWebSocket('ws://localhost:8081'); - }); }); diff --git a/libtextsecure/websocket-resources.js b/libtextsecure/websocket-resources.js index b034515e2..265f4f2cb 100644 --- a/libtextsecure/websocket-resources.js +++ b/libtextsecure/websocket-resources.js @@ -51,6 +51,10 @@ window.crypto.getRandomValues(bits); this.id = dcodeIO.Long.fromBits(bits[0], bits[1], true); } + + if (this.body === undefined) { + this.body = null; + } }; var IncomingWebSocketRequest = function(options) { diff --git a/libtextsecure/websocket.js b/libtextsecure/websocket.js index 5d8186869..4073f37f1 100644 --- a/libtextsecure/websocket.js +++ b/libtextsecure/websocket.js @@ -24,7 +24,6 @@ TextSecureWebSocket = function (url) { 'use strict'; - var keepAliveTimer; var reconnectSemaphore = 0; var reconnectTimeout = 1000; var socket; @@ -34,27 +33,10 @@ TextSecureWebSocket = function (url) { onclose : function() {}, onerror : function() {}, getStatus : function() { return socket.readyState; }, - close : function() { calledClose = true; } + close : function() { calledClose = true; socket.close(); } }; var error; - function resetKeepAliveTimer() { - clearTimeout(keepAliveTimer); - if (calledClose) { return; } - keepAliveTimer = setTimeout(function() { - if (socket.readyState === WebSocket.OPEN) { - socket.send( - new textsecure.protobuf.WebSocketMessage({ - type: textsecure.protobuf.WebSocketMessage.Type.REQUEST, - request: { verb: 'GET', path: '/v1/keepalive' } - }).encode().toArrayBuffer() - ); - } - - resetKeepAliveTimer(); - }, 55000); - }; - function onclose(e) { if (!error && !calledClose) { reconnectSemaphore--; @@ -74,22 +56,18 @@ TextSecureWebSocket = function (url) { function onmessage(response) { socketWrapper.onmessage(response); - resetKeepAliveTimer(); }; function send(msg) { - resetKeepAliveTimer(); socket.send(msg); }; function connect() { - clearTimeout(keepAliveTimer); if (++reconnectSemaphore <= 0) { return; } if (socket) { socket.close(); } socket = new WebSocket(url); - socket.onopen = resetKeepAliveTimer; socket.onerror = onerror socket.onclose = onclose; socket.onmessage = onmessage;