diff --git a/app/app.js b/app/app.js index fd2aa51..0fe7df2 100755 --- a/app/app.js +++ b/app/app.js @@ -6,7 +6,6 @@ angular.module('Measure', [ 'gettext', 'Measure.Measure', 'Measure.GaugeService', - 'ng.deviceDetector' ]) .value('ndtServer', {}) diff --git a/app/assets/js/ndt-browser-client.js b/app/assets/js/ndt-browser-client.js deleted file mode 100644 index 5d15dbb..0000000 --- a/app/assets/js/ndt-browser-client.js +++ /dev/null @@ -1,585 +0,0 @@ -/* This is an NDT client, written in javascript. It speaks the websocket - * version of the NDT protocol. The NDT protocol is documented at: - * https://code.google.com/p/ndt/wiki/NDTProtocol - */ - -/*jslint bitwise: true, browser: true, nomen: true, vars: true, indent: 2 */ -/*global Uint8Array, WebSocket */ - -'use strict'; - -function NDTjs(server, serverPort, serverProtocol, serverPath, callbacks, - updateInterval) { - this.server = server; - this.serverPort = serverPort || 3001; - this.serverPath = serverPath || '/ndt_protocol'; - this.serverProtocol = serverProtocol || 'ws'; - this.updateInterval = updateInterval / 1000.0 || false; - this.results = { - c2sRate: undefined, - s2cRate: undefined - }; - this.SEND_BUFFER_SIZE = 1048576; - - // Someone may want to run this test without callbacks (perhaps for - // debugging). Since the callbacks are referenced in various places, just - // create some empty ones if none were specified. - if (callbacks === undefined) { - this.callbacks = { - 'onstart': function () { return false; }, - 'onstatechange': function () { return false; }, - 'onprogress': function () { return false; }, - 'onfinish': function () { return false; }, - 'onerror': function () { return false; }, - }; - } else { - this.callbacks = callbacks; - } - - // Constants used by the entire program. - this.COMM_FAILURE = 0; - this.SRV_QUEUE = 1; - this.MSG_LOGIN = 2; - this.TEST_PREPARE = 3; - this.TEST_START = 4; - this.TEST_MSG = 5; - this.TEST_FINALIZE = 6; - this.MSG_ERROR = 7; - this.MSG_RESULTS = 8; - this.MSG_LOGOUT = 9; - this.MSG_WAITING = 10; - this.MSG_EXTENDED_LOGIN = 11; - - // An array to translate the constants back into strings for debugging. - this.NDT_MESSAGES = []; - this.NDT_MESSAGES[this.COMM_FAILURE] = 'COMM_FAILURE'; - this.NDT_MESSAGES[this.SRV_QUEUE] = 'SRV_QUEUE'; - this.NDT_MESSAGES[this.MSG_LOGIN] = 'MSG_LOGIN'; - this.NDT_MESSAGES[this.TEST_PREPARE] = 'TEST_PREPARE'; - this.NDT_MESSAGES[this.TEST_START] = 'TEST_START'; - this.NDT_MESSAGES[this.TEST_MSG] = 'TEST_MSG'; - this.NDT_MESSAGES[this.TEST_FINALIZE] = 'TEST_FINALIZE'; - this.NDT_MESSAGES[this.MSG_ERROR] = 'MSG_ERROR'; - this.NDT_MESSAGES[this.MSG_RESULTS] = 'MSG_RESULTS'; - this.NDT_MESSAGES[this.MSG_LOGOUT] = 'MSG_LOGOUT'; - this.NDT_MESSAGES[this.MSG_WAITING] = 'MSG_WAITING'; - this.NDT_MESSAGES[this.MSG_EXTENDED_LOGIN] = 'MSG_EXTENDED_LOGIN'; -} - -/** - * Provide feedback to the console or the DOM. - * @param {string} logMessage Message to pass to output mechanism. - * @param {!boolean=} debugging Optional (may be undefined) Determines whether - * to output messages or to operate silently. - */ -NDTjs.prototype.logger = function (logMessage, debugging) { - debugging = debugging || false; - if (debugging === true) { - console.log(logMessage); - } -}; - -/** - * Check that the browser supports the NDT test. - * @returns {boolean} Browser supports necessary functions for test client. - */ -NDTjs.prototype.checkBrowserSupport = function () { - if (self.WebSocket === undefined && self.MozWebSocket === undefined) { - throw this.UnsupportedBrowser('No Websockets'); - } - return true; -}; - -/** - * Makes a login message suitable for sending to the server. The login - * messages specifies the tests to be run. - * @param {number} desiredTests The types of tests requested from the server - * signaled based on a bitwise operation of the test ids. - * @returns {Uint8Array} NDT login message signalling the desired tests. - */ -NDTjs.prototype.makeLoginMessage = function (desiredTests) { - // We must support TEST_STATUS (16) as a 3.5.5+ client, so we make sure - // test 16 is desired. - var i, - loginMessage = 'XXX { "msg": "v3.5.5", "tests": "' + (desiredTests | 16) + - '" }', - loginData = new Uint8Array(loginMessage.length); - - loginData[0] = this.MSG_EXTENDED_LOGIN; - loginData[1] = 0; // Two bytes to represent packet length - loginData[2] = loginMessage.length - 3; - - for (i = 3; i < loginMessage.length; i += 1) { - loginData[i] = loginMessage.charCodeAt(i); - } - return loginData; -}; - -/** - * A generic message creation system for NDT. - * (messageType, message body length [2], message body) - * @params {number} messageType The type of message according to NDT's - * specification. - * @params {string} messageContent The message body. - * @returns {array} An array of bytes suitable for sending on a binary - * websocket. - */ -NDTjs.prototype.makeNdtMessage = function (messageType, messageContent) { - var messageBody, ndtMessage, i; - - messageBody = '{ "msg": "' + messageContent + '" } '; - ndtMessage = new Uint8Array(messageBody.length + 3); - ndtMessage[0] = messageType; - ndtMessage[1] = (messageBody.length >> 8) & 0xFF; - ndtMessage[2] = messageBody.length & 0xFF; - - for (i = 0; i < messageBody.length; i += 1) { - ndtMessage[i + 3] = messageBody.charCodeAt(i); - } - return ndtMessage; -}; - -/** - * Parses messages received from the NDT server. - * @param {object} buffer The complete message received from the NDT server. - * @returns {array} Parsed messaged. - */ -NDTjs.prototype.parseNdtMessage = function (buffer) { - var i, - response = [], - bufferArray = new Uint8Array(buffer), - message = String.fromCharCode.apply(null, - new Uint8Array(buffer.slice(3))); - for (i = 0; i < 3; i += 1) { - response[i] = bufferArray[i]; - } - response.push(message); - return response; -}; - -/** - * Exception related to low-level connectivity failures. - * @param {string} message Specific failure messages passed in the course of - * receiving the exception. - */ -NDTjs.prototype.ConnectionException = function (message) { - this.logger(message); - this.callbacks.onerror(message); -}; - -/** - * Exception related to an unsupported browser. - * @param {string} message Specific failure messages passed in the course of - * receiving the exception. - */ -NDTjs.prototype.UnsupportedBrowser = function (message) { - this.logger(message); - this.callbacks.onerror(message); -}; - -/** - * Exception related to test failures, such as behavior inconsistent with - * expectations. - * @param {string} message Specific failure messages passed in the course of - * receiving the exception. - */ -NDTjs.prototype.TestFailureException = function (message) { - this.logger(message); - this.callbacks.onerror(message); -}; - -/** - * A simple helper function to create websockets consistently. - * @param {string} serverAddress The FQDN or IP of the NDT server. - * @param {Number} serverPort The port expected for the NDT test. - * @param {string} urlPath The path of the resource to request from NDT. - * @param {string} protocol The WebSocket protocol to build for. - * @returns {Websocket} The WebSocket we created; - */ -NDTjs.prototype.createWebsocket = function (serverProtocol, serverAddress, - serverPort, urlPath, protocol) { - var createdWebsocket = new WebSocket(serverProtocol + '://' + - serverAddress + ':' + serverPort + - urlPath, protocol); - createdWebsocket.binaryType = 'arraybuffer'; - return createdWebsocket; -}; - -/** - * A simple helper function to create websockets consistently. - * @param {string} serverAddress The FQDN or IP of the NDT server. - * @param {Number} serverPort The port expected for the NDT test. - * @param {string} urlPath The path of the resource to request from NDT. - * @param {string} protocol The WebSocket protocol to build for. - * @returns {Websocket} The WebSocket we created; - */ -NDTjs.prototype.createBulkWebsocket = function (serverProtocol, serverAddress, - serverPort, urlPath, protocol) { - var createdWebsocket = new WebSocket(serverProtocol + '://' + - serverAddress + ':' + serverPort + - urlPath, protocol); - createdWebsocket.binaryType = 'arraybuffer'; - return createdWebsocket; -}; - -/** - * NDT's Client-to-Server (C2S) Upload Test - * Serves as a closure that will process all messages for the C2S NDT test. - * @returns {boolean} The test is complete and the closure should no longer - * be called. - */ -NDTjs.prototype.ndtC2sTest = function () { - var serverPort, testConnection, testStart, i, - dataToSend = new Uint8Array(this.SEND_BUFFER_SIZE), - that = this, - state = 'WAIT_FOR_TEST_PREPARE', - totalSent = 0, - nextCallback = that.updateInterval, - keepSendingData, - connectionOpen = false; - - for (i = 0; i < dataToSend.length; i += 1) { - // All the characters must be printable, and the printable range of - // ASCII is from 32 to 126. 101 is because we need a prime number. - dataToSend[i] = 32 + (i * 101) % (126 - 32); - } - - /** - * The upload function for C2S, encoded as a callback instead of a loop. - */ - keepSendingData = function () { - var currentTime = Date.now() / 1000.0; - if (connectionOpen) { - // Monitor the buffersize as it sends and refill if it gets too low. - if (testConnection.bufferedAmount < 8192) { - testConnection.send(dataToSend); - totalSent += dataToSend.length; - } - if (that.updateInterval && (currentTime - 0.1) > (testStart + nextCallback)) { - that.results.c2sRate = 8 * (totalSent - testConnection.bufferedAmount) - / 1000 / (currentTime - testStart); - that.callbacks.onprogress('interval_c2s', that.results); - nextCallback += that.updateInterval; - currentTime = Date.now() / 1000.0; - } - } - if (currentTime < testStart + 10) { - setTimeout(keepSendingData, 0); - } else { - return false; - } - }; - - /** - * The closure that processes messages on the control socket for the - * C2S test. - */ - return function (messageType, messageContent) { - that.logger('CALLED C2S with ' + messageType + ' (' + - that.NDT_MESSAGES[messageType] + ') ' + messageContent.msg + - ' in state ' + state); - if (state === 'WAIT_FOR_TEST_PREPARE' && - messageType === that.TEST_PREPARE) { - that.callbacks.onstatechange('preparing_c2s', that.results); - // Register the `onopen` handler on websocket in the same event loop cycle - // so "keepSendingData" can begin as soon as the server sends TEST_START. - serverPort = Number(messageContent.msg); - testConnection = that.createWebsocket( - that.serverProtocol, that.server, serverPort, that.serverPath, 'c2s'); - testConnection.onopen = function() { - connectionOpen = true; - }; - state = 'WAIT_FOR_TEST_START'; - return false; - } - if (state === 'WAIT_FOR_TEST_START' && messageType === that.TEST_START) { - that.callbacks.onstatechange('running_c2s', that.results); - testStart = Date.now() / 1000; - keepSendingData(); - state = 'WAIT_FOR_TEST_MSG'; - return false; - } - if (state === 'WAIT_FOR_TEST_MSG' && messageType === that.TEST_MSG) { - that.results.c2sRate = Number(messageContent.msg); - that.logger('C2S rate calculated by server: ' + that.results.c2sRate); - state = 'WAIT_FOR_TEST_FINALIZE'; - return false; - } - if (state === 'WAIT_FOR_TEST_FINALIZE' && - messageType === that.TEST_FINALIZE) { - that.callbacks.onstatechange('finished_c2s', that.results); - state = 'DONE'; - return true; - } - that.logger('C2S: State = ' + state + ' type = ' + messageType + '(' + - that.NDT_MESSAGES[messageType] + ') message = ', messageContent); - }; -}; - -/** - * NDT's Server-to-Client (S2C) Download Test - * Serves as a closure that will process all messages for the S2C NDT test. - * @param {Websocket} ndtSocket A websocket connection to the NDT server. - * @returns {boolean} The test is complete and the closure should no longer - * be called. - */ -NDTjs.prototype.ndtS2cTest = function (ndtSocket) { - var serverPort, testConnection, testStart, testEnd, errorMessage, - state = 'WAIT_FOR_TEST_PREPARE', - receivedBytes = 0, - nextCallback = this.updateInterval, - that = this; - - /** - * The closure that processes messages on the control socket for the - * C2S test. - */ - return function (messageType, messageContent) { - that.logger('CALLED S2C with ' + messageType + ' (' + - that.NDT_MESSAGES[messageType] + ') in state ' + state); - if (state === 'WAIT_FOR_TEST_PREPARE' && - messageType === that.TEST_PREPARE) { - that.callbacks.onstatechange('preparing_s2c', that.results); - serverPort = Number(messageContent.msg); - testConnection = that.createWebsocket(that.serverProtocol, that.server, - serverPort, that.serverPath, 's2c'); - testConnection.onopen = function () { - that.logger('Successfully opened S2C test connection.'); - testStart = Date.now() / 1000; - }; - testConnection.onmessage = function (response) { - var hdrSize, - currentTime; - if (response.data.byteLength < 126) { - hdrSize = 2; - } else if (response.data.byteLength < 65536) { - hdrSize = 4; - } else { - hdrSize = 10; - } - receivedBytes += (hdrSize + response.data.byteLength); - currentTime = Date.now() / 1000.0; - if (that.updateInterval && currentTime > (testStart + nextCallback)) { - that.results.s2cRate = 8 * receivedBytes / 1000 - / (currentTime - testStart); - that.callbacks.onprogress('interval_s2c', that.results); - nextCallback += that.updateInterval; - currentTime = Date.now() / 1000.0; - } - }; - - testConnection.onerror = function (response) { - errorMessage = that.parseNdtMessage(response.data)[3].msg; - throw that.TestFailureException(errorMessage); - }; - - state = 'WAIT_FOR_TEST_START'; - return false; - } - if (state === 'WAIT_FOR_TEST_START' && messageType === that.TEST_START) { - that.callbacks.onstatechange('running_s2c', that.results); - - state = 'WAIT_FOR_FIRST_TEST_MSG'; - return false; - } - if (state === 'WAIT_FOR_FIRST_TEST_MSG' && messageType === that.TEST_MSG) { - that.logger('Got message: ' + JSON.stringify(messageContent)); - state = 'WAIT_FOR_TEST_MSG_OR_TEST_FINISH'; - - if (testEnd === undefined) { - testEnd = Date.now() / 1000; - } - // Calculation per spec, compared between client and server - // understanding. - that.results.s2cRate = 8 * receivedBytes / 1000 / (testEnd - testStart); - that.logger('S2C rate calculated by client: ' + that.results.s2cRate); - that.logger('S2C rate calculated by server: ' + - messageContent.ThroughputValue); - ndtSocket.send(that.makeNdtMessage(that.TEST_MSG, - String(that.results.s2cRate))); - return false; - } - if (state === 'WAIT_FOR_TEST_MSG_OR_TEST_FINISH' && - messageType === that.TEST_MSG) { - var web100Record = messageContent.msg.split(': '), - web100Variable = web100Record[0], - web100Result = web100Record[1].trim(); - that.results[web100Variable] = web100Result; - return false; - } - if (state === 'WAIT_FOR_TEST_MSG_OR_TEST_FINISH' && - messageType === that.TEST_FINALIZE) { - that.callbacks.onstatechange('finished_s2c', that.results); - that.logger('NDT S2C test is complete: ' + messageContent.msg); - return true; - } - that.logger('S2C: State = ' + state + ' type = ' + messageType + '(' + - that.NDT_MESSAGES[messageType] + ') message = ', messageContent); - }; -}; - -/** - * NDT's META (S2C) Download Test - * Serves as a closure that will process all messages for the META NDT test, - * which provides additional data to the NDT results. - * @param {Websocket} ndtSocket A websocket connection to the NDT server. - * @returns {boolean} The test is complete and the closure should no longer - * be called. - */ -NDTjs.prototype.ndtMetaTest = function (ndtSocket) { - var errorMessage, - that = this, - state = 'WAIT_FOR_TEST_PREPARE'; - - return function (messageType, messageContent) { - if (state === 'WAIT_FOR_TEST_PREPARE' && - messageType === that.TEST_PREPARE) { - that.callbacks.onstatechange('preparing_meta', that.results); - state = 'WAIT_FOR_TEST_START'; - return false; - } - if (state === 'WAIT_FOR_TEST_START' && messageType === that.TEST_START) { - that.callbacks.onstatechange('running_meta', that.results); - // Send one piece of meta data and then an empty meta data packet - ndtSocket.send(that.makeNdtMessage(that.TEST_MSG, - 'client.os.name:NDTjs')); - ndtSocket.send(that.makeNdtMessage(that.TEST_MSG, '')); - state = 'WAIT_FOR_TEST_FINALIZE'; - return false; - } - if (state === 'WAIT_FOR_TEST_FINALIZE' && - messageType === that.TEST_FINALIZE) { - that.callbacks.onstatechange('finished_meta', that.results); - that.logger('NDT META test complete.'); - return true; - } - errorMessage = 'Bad state and message combo for META test: ' + - state + ', ' + messageType + ', ' + messageContent.msg; - throw that.TestFailureException(errorMessage); - }; -}; - -/** - * Start a series of NDT tests. - **/ -NDTjs.prototype.startTest = function () { - var ndtSocket, activeTest, state, errorMessage, i, - testsToRun = [], - that = this; - - this.checkBrowserSupport(); - this.logger('Test started. Waiting for connection to server...'); - this.callbacks.onstart(this.server); - ndtSocket = this.createWebsocket(this.serverProtocol, this.server, - this.serverPort, this.serverPath, 'ndt'); - - /** When the NDT control socket is opened, send a message requesting a - * TEST_S2C, TEST_C2S, and TEST_META. - */ - ndtSocket.onopen = function () { - that.logger('Opened connection on port ' + that.serverPort); - // Sign up for every test except for TEST_MID and TEST_SFW - browsers can't - // open server sockets, which makes those tests impossible, because they - // require the server to open a connection to a port on the client. - ndtSocket.send(that.makeLoginMessage(2 | 4 | 32)); - state = 'LOGIN_SENT'; - }; - - /** Process a message received on the NDT control socket. The message should - * be handed off to the active test (if any), or processed directly if there - * is no active test. - */ - ndtSocket.onmessage = function (response) { - var tests, - message = that.parseNdtMessage(response.data), - messageType = message[0], - messageContent = JSON.parse(message[3]); - - that.logger('type = ' + messageType + ' (' + - that.NDT_MESSAGES[messageType] + ') body = "' + - messageContent.msg + '"'); - if (activeTest === undefined && testsToRun.length > 0) { - activeTest = testsToRun.pop(); - } - if (activeTest !== undefined) { - // Pass the message to the sub-test - that.logger('Calling a subtest'); - if (activeTest(messageType, messageContent) === true) { - activeTest = undefined; - that.logger('Subtest complete'); - } - return; - } - - // If there is an active test, hand off control to the test - // Otherwise, move the coordinator state forwards. - if (state === 'LOGIN_SENT') { - // Response to NDT_LOGIN should be SRV_QUEUE messages until we - // get SRV_QUEUE('0') - if (messageType === that.SRV_QUEUE) { - if (messageContent.msg === '9990') { - // Connection keepalive message - ndtSocket.send(that.makeNdtMessage(that.MSG_WAITING, '')); - } else if (messageContent.msg === '9977') { - // Test failed, leave now. - throw that.TestFailureException('Server terminated test ' + - 'with SRV_QUEUE 9977'); - } - that.logger('Got SRV_QUEUE. Ignoring and waiting for ' + - 'MSG_LOGIN.'); - } else if (messageType === that.MSG_LOGIN) { - if (messageContent.msg[0] !== 'v') { - that.logger('Bad msg ' + messageContent.msg); - } - state = 'WAIT_FOR_TEST_IDS'; - } else { - errorMessage = 'Expected type 1 (SRV_QUEUE) or 2 (MSG_LOGIN)' + - 'but got ' + messageType + ' (' + - that.NDT_MESSAGES[messageType] + ')'; - throw that.TestFailureException(errorMessage); - } - } else if (state === 'WAIT_FOR_TEST_IDS' && - messageType === that.MSG_LOGIN) { - tests = messageContent.msg.split(' '); - for (i = tests.length - 1; i >= 0; i -= 1) { - if (tests[i] === '2') { - testsToRun.push(that.ndtC2sTest()); - } else if (tests[i] === '4') { - testsToRun.push(that.ndtS2cTest(ndtSocket)); - } else if (tests[i] === '32') { - testsToRun.push(that.ndtMetaTest(ndtSocket)); - } else if (tests[i] !== '') { - errorMessage = 'Unknown test type: ' + tests[i]; - throw that.TestFailureException(errorMessage); - } - } - state = 'WAIT_FOR_MSG_RESULTS'; - } else if (state === 'WAIT_FOR_MSG_RESULTS' && - messageType === that.MSG_RESULTS) { - that.logger(messageContent); - var lines = messageContent.msg.split('\n'); - for (i = 0; i < lines.length; i++) { - var line = lines[i]; - var record = line.split(': '); - var variable = record[0]; - var result = record[1]; - that.results[variable] = result; - } - } else if (state === 'WAIT_FOR_MSG_RESULTS' && - messageType === that.MSG_LOGOUT) { - ndtSocket.close(); - that.callbacks.onstatechange('finished_all', that.results); - that.callbacks.onfinish(that.results); - that.logger('All tests successfully completed.'); - } else { - errorMessage = 'No handler for message ' + messageType + - ' in state ' + state; - throw that.TestFailureException(errorMessage); - } - }; - - ndtSocket.onerror = function (response) { - errorMessage = that.parseNdtMessage(response.data)[3].msg; - throw that.TestFailureException(errorMessage); - }; -}; diff --git a/app/assets/js/ndt-controller.js b/app/assets/js/ndt-controller.js deleted file mode 100755 index 6bd070a..0000000 --- a/app/assets/js/ndt-controller.js +++ /dev/null @@ -1,258 +0,0 @@ -// var allowDebug = true; -// CONSTANTS - -// Testing phases - -var PHASE_LOADING = 0; -var PHASE_WELCOME = 1; -var PHASE_PREPARING = 2; -var PHASE_UPLOAD = 3; -var PHASE_DOWNLOAD = 4; -var PHASE_RESULTS = 5; - - -// STATUS VARIABLES -var websocket_client = null; -var currentPhase = PHASE_LOADING; -var currentPage = 'welcome'; -var transitionSpeed = 400; - -// Gauges used for showing download/upload speed -var downloadGauge, uploadGauge; -var gaugeUpdateInterval; -var gaugeMaxValue = 1000; - -function startTest(fqdn) { - // evt.stopPropagation(); - // evt.preventDefault(); - websocket_client = new NDTWrapper(fqdn); - - websocket_client._port = 3010 ; - websocket_client._protocol = 'wss'; - - currentPhase = PHASE_WELCOME; - testNDT().run_test(); - monitorTest(); -} - -function monitorTest() { - var message = testError(); - var currentStatus = testStatus(); - - if (message.match(/not run/) && currentPhase != PHASE_LOADING) { - setPhase(PHASE_WELCOME); - return false; - } - if (message.match(/notStarted/) && currentPhase != PHASE_LOADING) { - setPhase(PHASE_PREPARING); - return false; - } - if (message.match(/completed/) && currentPhase < PHASE_RESULTS) { - setPhase(PHASE_RESULTS); - return true; - } - if (message.match(/failed/) && currentPhase < PHASE_RESULTS) { - setPhase(PHASE_RESULTS); - return false; - } - if (currentStatus.match(/Outbound/) && currentPhase < PHASE_UPLOAD) { - setPhase(PHASE_UPLOAD); - } - if (currentStatus.match(/Inbound/) && currentPhase < PHASE_DOWNLOAD) { - setPhase(PHASE_DOWNLOAD); - } - - if (!currentStatus.match(/Middleboxes/) && !currentStatus.match(/notStarted/) - && !remoteServer().match(/ndt/) && currentPhase == PHASE_PREPARING) { - debug('Remote server is ' + remoteServer()); - setPhase(PHASE_UPLOAD); - } - - if (remoteServer() !== 'unknown' && currentPhase < PHASE_PREPARING) { - setPhase(PHASE_PREPARING); - } - - setTimeout(monitorTest, 1000); -} - - - -// PHASES - -function setPhase(phase) { - switch (phase) { - - case PHASE_WELCOME: - debug('WELCOME'); - showPage('welcome'); - break; - - case PHASE_PREPARING: - // uploadGauge.setValue(0); - // downloadGauge.setValue(0); - debug('PREPARING TEST'); - break; - - case PHASE_UPLOAD: - var pcBuffSpdLimit, rtt, gaugeConfig = []; - debug('UPLOAD TEST'); - - pcBuffSpdLimit = speedLimit(); - rtt = minRoundTrip(); - - if (!isNaN(pcBuffSpdLimit)) { - if (pcBuffSpdLimit > gaugeMaxValue) { - pcBuffSpdLimit = gaugeMaxValue; - } - // gaugeConfig.push({ - // from: 0, to: pcBuffSpdLimit, color: 'rgb(0, 255, 0)' - // }); - // - // gaugeConfig.push({ - // from: pcBuffSpdLimit, to: gaugeMaxValue, color: 'rgb(255, 0, 0)' - // }); - // - // uploadGauge.updateConfig({ - // highlights: gaugeConfig - // }); - // - // downloadGauge.updateConfig({ - // highlights: gaugeConfig - // }); - } - - break; - - case PHASE_DOWNLOAD: - debug('DOWNLOAD TEST'); - break; - - case PHASE_RESULTS: - debug('SHOW RESULTS'); - debug('Testing complete'); - break; - - default: - return false; - } - currentPhase = phase; -} - -// GAUGE - -function initializeGauges() { - var gaugeValues = []; - - for (var i=0; i<=10; i++) { - gaugeValues.push(0.1 * gaugeMaxValue * i); - } - // uploadGauge = new Gauge({ - // renderTo : 'uploadGauge', - // width : 270, - // height : 270, - // units : 'Mb/s', - // title : 'Upload', - // minValue : 0, - // maxValue : gaugeMaxValue, - // majorTicks : gaugeValues, - // highlights : [{ from: 0, to: gaugeMaxValue, color: 'rgb(0, 255, 0)' }] - // });; - - gaugeValues = []; - for (var i=0; i<=10; i++) { - gaugeValues.push(0.1 * gaugeMaxValue * i); - } - // downloadGauge = new Gauge({ - // renderTo : 'downloadGauge', - // width : 270, - // height : 270, - // units : 'Mb/s', - // title : 'Download', - // minValue : 0, - // maxValue : gaugeMaxValue, - // majorTicks : gaugeValues, - // highlights : [{ from: 0, to: gaugeMaxValue, color: 'rgb(0, 255, 0)' }] - // });; -} - -// TESTING JAVA/WEBSOCKET CLIENT - -function testNDT() { - if (websocket_client) { - return websocket_client; - } - - return $('#NDT'); -} - -function testStatus() { - return testNDT().get_status(); -} - -function testError() { - return testNDT().get_errmsg(); -} - -function remoteServer() { - return testNDT().get_host(); -} - -function uploadSpeed(raw) { - var speed = testNDT().getNDTvar('ClientToServerSpeed'); - return raw ? speed : parseFloat(speed); -} - -function downloadSpeed() { - return parseFloat(testNDT().getNDTvar('ServerToClientSpeed')); -} - -function minRoundTrip() { - return parseFloat(testNDT().getNDTvar('MinRTT')); -} - -function jitter() { - return parseFloat(testNDT().getNDTvar('Jitter')); -} - -function speedLimit() { - return parseFloat(testNDT().get_PcBuffSpdLimit()); -} - -function readNDTvar(variable) { - var ret = testNDT().getNDTvar(variable); - return !ret ? '-' : ret; -} - -// UTILITIES - -function debug(message) { - if (typeof allowDebug !== 'undefined') { - if (allowDebug && window.console) console.debug(message); - } -} - -function isPluginLoaded() { - try { - testStatus(); - return true; - } catch(e) { - return false; - } -} - -// Attempts to determine the absolute path of a script, minus the name of the -// script itself. -function getScriptPath() { - var scripts = document.getElementsByTagName('SCRIPT'); - var fileRegex = new RegExp('\/ndt-wrapper\.js$'); - var path = ''; - if (scripts && scripts.length > 0) { - for(var i in scripts) { - if(scripts[i].src && scripts[i].src.match(fileRegex)) { - path = scripts[i].src.replace(fileRegex, ''); - break; - } - } - } - return path.substring(location.origin.length); -}; diff --git a/app/assets/js/ndt-wrapper-ww.js b/app/assets/js/ndt-wrapper-ww.js deleted file mode 100644 index 7fecc25..0000000 --- a/app/assets/js/ndt-wrapper-ww.js +++ /dev/null @@ -1,68 +0,0 @@ -/* This is an NDT client, written in javascript. It speaks the websocket - * version of the NDT protocol. The NDT protocol is documented at: - * https://code.google.com/p/ndt/wiki/NDTProtocol - */ - -/*jslint bitwise: true, browser: true, nomen: true, vars: true */ -/*global Uint8Array, WebSocket */ - -'use strict'; - -importScripts('ndt-browser-client.js'); - -self.addEventListener('message', function (e) { - var msg = e.data; - switch (msg.cmd) { - case 'start': - startNDT(msg.hostname, msg.port, msg.protocol, msg.path, - msg.update_interval); - break; - case 'stop': - self.close(); - break; - default: - // self.postMessage('Unknown command: ' + data.msg); - break; - }; -}, false); - -function startNDT(hostname, port, protocol, path, update_interval) { - var callbacks = { - 'onstart': function(server) { - self.postMessage({ - 'cmd': 'onstart', - 'server': server - }); - }, - 'onstatechange': function(state, results) { - self.postMessage({ - 'cmd': 'onstatechange', - 'state': state, - 'results': results, - }); - }, - 'onprogress': function(state, results) { - self.postMessage({ - 'cmd': 'onprogress', - 'state': state, - 'results': results, - }); - }, - 'onfinish': function(results) { - self.postMessage({ - 'cmd': 'onfinish', - 'results': results - }); - }, - 'onerror': function(error_message) { - self.postMessage({ - 'cmd': 'onerror', - 'error_message': error_message - }); - } - }; - - var client = new NDTjs(hostname, port, protocol, path, callbacks, - update_interval); - client.startTest(); -} diff --git a/app/assets/js/ndt-wrapper.js b/app/assets/js/ndt-wrapper.js deleted file mode 100644 index 828865d..0000000 --- a/app/assets/js/ndt-wrapper.js +++ /dev/null @@ -1,200 +0,0 @@ -/* This is an NDT client, written in javascript. It speaks the websocket - * version of the NDT protocol. The NDT protocol is documented at: - * https://code.google.com/p/ndt/wiki/NDTProtocol - */ - -/*jslint bitwise: true, browser: true, nomen: true, vars: true */ -/*global Uint8Array, WebSocket */ - -'use strict'; - -function NDTWrapper(server) { - var _this = this; - - // XXX: include a way to override this - this.use_web_worker = false; - - /* If they have Web Workers, use it to do the NDT test, unless it's Firefox - * which doesn't support web workers using websockets. This should be - * migrated into something more sane (e.g. a function that spawns an inline worker that - * creates a websocket, and returns true/false if that succeeds */ - var isFirefox = typeof InstallTrigger !== 'undefined'; - var supportsWebWorkers = !!window.Worker; - - if (supportsWebWorkers) { - this.use_web_worker = true; - } - - if (isFirefox) { - this.use_web_worker = false; - } - - this._hostname = server; - this._port = 'https:' == location.protocol ? 3010 : 3001; - this._protocol = 'https:' == location.protocol ? 'wss' : 'ws'; - this._path = '/ndt_protocol'; - this._update_interval = 1000; - - this.reset(); -} - -NDTWrapper.prototype.reset = function () { - if (this.worker) { - this.worker.postMessage({ - 'cmd': 'stop' - }); - - this.worker = null; - } - - if (this.client) { - this.client = null; - } - - this._ndt_vars = { 'ClientToServerSpeed': 0, 'ServerToClientSpeed': 0 }; - this._errmsg = ''; - this._status = 'notStarted'; - this._diagnosis = ''; -}; - -NDTWrapper.prototype.run_test = function () { - var _this = this; - - this.reset(); - - if (this.use_web_worker) { - console.log('Generating new worker'); - // 'new Worker()' only accepts absolute paths to script files, so - // determine the path to the location of the ndt-wrapper.js script, and - // ndt-wrapper-ww.js should be in the same place. - var scriptPath = getScriptPath(); - this.worker = new Worker(scriptPath + '/ndt-wrapper-ww.js'); - this.worker.addEventListener('message', function (e) { - var msg = e.data; - switch (msg.cmd) { - case 'onstart': - _this.onstart_cb(msg.server); - break; - case 'onstatechange': - _this.onstatechange_cb(msg.state, msg.results); - break; - case 'onprogress': - _this.onprogress_cb(msg.state, msg.results); - break; - case 'onfinish': - _this.onfinish_cb(msg.results); - break; - case 'onerror': - _this.onerror_cb(msg.error_message); - break; - } - }, false); - - this.worker.addEventListener('error', function (e) { - _this.onerror_cb(e.lineno, ' in ', e.filename, ': ', e.message); - }, false); - - this.worker.postMessage({ - 'cmd': 'start', - 'hostname': this._hostname, - 'port': this._port, - 'protocol': this._protocol, - 'path': this._path, - 'update_interval': this._update_interval - }); - } - else { - this.callbacks = { - 'onstart': function(server) { - _this.onstart_cb(server); - }, - 'onstatechange': function(state, results) { - _this.onstatechange_cb(state, results); - }, - 'onprogress': function(state, results) { - _this.onprogress_cb(state, results); - }, - 'onfinish': function(passed_results) { - _this.onfinish_cb(passed_results); - }, - 'onerror': function(error_message) { - _this.onerror_cb(error_message); - } - }; - - this.client = new NDTjs(this._hostname, this._port, this._protocol, - this._path, this.callbacks, - this._update_interval); - this.client.startTest(); - } -}; - - -NDTWrapper.prototype.get_status = function () { - return this._status; -}; - -NDTWrapper.prototype.get_diagnosis = function () { - return this._diagnosis; -}; - -NDTWrapper.prototype.get_errmsg = function () { - return this._errmsg; -}; - -NDTWrapper.prototype.get_host = function () { - return this._hostname; -}; - -NDTWrapper.prototype.getNDTvar = function (variable) { - return this._ndt_vars[variable]; -}; - -NDTWrapper.prototype.get_PcBuffSpdLimit = function (variable) { - return Number.NaN; -}; - -NDTWrapper.prototype.onstart_cb = function (server) { -}; - -NDTWrapper.prototype.onstatechange_cb = function (state, results) { - if (state === 'running_s2c') { - this._status = 'Inbound'; - this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000; - } - else if (state === 'finished_s2c') { - this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000; - } - else if (state === 'running_c2s') { - this._status = 'Outbound'; - } - else if (state == 'finished_c2s') { - this._ndt_vars['ClientToServerSpeed'] = results['c2sRate'] / 1000; - } -}; - -NDTWrapper.prototype.onprogress_cb = function (state, results) { - if (state == 'interval_s2c') { - this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000; - } - else if (state === 'interval_c2s') { - this._ndt_vars['ClientToServerSpeed'] = results['c2sRate'] / 1000; - } -}; - -NDTWrapper.prototype.onfinish_cb = function (results) { - this._errmsg = "Test completed"; - this._ndt_vars = results; - this._ndt_vars['ServerToClientSpeed'] = results['s2cRate'] / 1000; - this._ndt_vars['ClientToServerSpeed'] = results['c2sRate'] / 1000; - this._ndt_vars['Jitter'] = results['MaxRTT'] - results['MinRTT']; - this.build_diagnosis(); -}; - -NDTWrapper.prototype.build_diagnosis = function () { - this._diagnosis = JSON.stringify(this._ndt_vars, null, " "); -}; - -NDTWrapper.prototype.onerror_cb = function (error_message) { - this._errmsg = "Test failed: "+error_message; -}; diff --git a/app/measure/measure.html b/app/measure/measure.html index d15fa11..cf4cfbf 100755 --- a/app/measure/measure.html +++ b/app/measure/measure.html @@ -1,9 +1,5 @@
-
-

We're sorry, the Safari browser is not compatible with the NDT - test. Please use a different browser such as Chrome or Firefox instead.

-

Test Your Speed

@@ -19,7 +15,7 @@

Test Your Speed

+ === 'disabled')}"> Begin Again Testing diff --git a/app/measure/measure.js b/app/measure/measure.js index 67fa90a..d3805ca 100755 --- a/app/measure/measure.js +++ b/app/measure/measure.js @@ -3,16 +3,12 @@ angular.module('Measure.Measure', ['ngRoute']) .controller('MeasureCtrl', function($scope, $rootScope, $interval, $timeout, - gettextCatalog, ndtServer, ProgressGauge, deviceDetector) { + gettextCatalog, ndtServer, ProgressGauge) { var ndtSemaphore = false; $scope.measurementComplete = false; - $scope.isSafari = deviceDetector.browser === "safari"; - - console.log(deviceDetector); - ProgressGauge.create(); $scope.currentPhase = ''; $scope.currentSpeed = ''; @@ -21,7 +17,7 @@ angular.module('Measure.Measure', ['ngRoute']) var gaugeProgress, TIME_EXPECTED = 10; - if ($scope.privacyConsent !== true || $scope.isSafari ) { + if ($scope.privacyConsent !== true) { return; } diff --git a/package.json b/package.json index 7c7649f..9f0e772 100755 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "@bower_components/html5-boilerplate": "h5bp/html5-boilerplate#^5.3.0", "@bower_components/jquery": "jquery/jquery-dist#3.0.0", "@bower_components/skel": "n33/skel#~3.0.1", - "@m-lab/ndt7": "0.0.4", + "@m-lab/ndt7": "0.0.5-beta.0", "ng-device-detector": "^5.1.4", "re-tree": "^0.1.7", "ua-device-detector": "^1.1.8" diff --git a/yarn.lock b/yarn.lock index bee4988..4aa2244 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,10 +34,10 @@ version "3.0.1" resolved "https://codeload.github.com/n33/skel/tar.gz/3375acd7ce35f865844b41172ddf91055d87e1c2" -"@m-lab/ndt7@0.0.4": - version "0.0.4" - resolved "https://registry.yarnpkg.com/@m-lab/ndt7/-/ndt7-0.0.4.tgz#48ecd3250bd4d64b508704eddc2b67dd3e0322e5" - integrity sha512-+t0DvWhYi0yFsm6awAaSQTKzpHkaaVU1TGcOmxqt1zlGy/meD3nTEQaISpmZP2/xcSGJEoXdRVVA1zMB02MqeQ== +"@m-lab/ndt7@0.0.5-beta.0": + version "0.0.5-beta.0" + resolved "https://registry.yarnpkg.com/@m-lab/ndt7/-/ndt7-0.0.5-beta.0.tgz#af744704bbee198876d3f8a59e24185ef4c66742" + integrity sha512-PwkoapgaHsn5hZLoADpy0dNTYGE8Cj6mzWfGdWwl8xaiTY95KJB7LsmctaMpan7Ww5IqtTTcUmxc1NlgxNouPw== dependencies: fetch "^1.1.0" isomorphic-ws "^4.0.1"