by Federico Dossena
Version 4.2.1, May 15 2017
https://github.com/adolfintel/speedtest/
In this document, we will introduce an XHR based HTML5 Speedtest and see how to use it. This test measures download speed, upload speed, ping and jitter.
First of all, the requirements to run this test:
If this looks good, let's proceed and see how to use the test.
To install the test on your server, upload the following files:
speedtest_worker.min.jsgarbage.phpgetIP.phpempty.phpYou may also want to upload one of the examples to test it.
Later we'll see how to use the test without PHP.
Important: keep all the files together; all paths are relative to the js file
To run the test, you need to do 3 things:
var w = new Worker("speedtest_worker.min.js")
Important: use the minified version, it's smaller!
First, we set up a timer that fetches the status of the worker continuously:
var timer = setInterval(function () {
w.postMessage('status')
}, 100)
Then we write a response handler that receives the status and updates the page. Later we'll see the details of the format of the response.
w.onmessage = function (event) {
var data = event.data.split(';')
var testState = data[0]
var dlStatus = data[1]
var ulStatus = data[2]
var pingStatus = data[3]
var jitterStatus = data[5]
var clientIp = data[4]
if (testState >= 4) {
clearInterval(timer) // test is finished or aborted
}
// .. update your page here ..
}
The response from the worker is composed of values separated by ; (semicolon) in this
format:
testState;dlStatus;ulStatus;pingStatus;clientIp;jitterStatus
0 = Test starting1 = Download test in progress2 = Ping + Jitter test in progress3 = Upload test in progress4 = Test finished5 = Test abortedTo start the test, send the start command to the worker:
w.postMessage('start')
This starts the test with the default settings, which is usually the best choice. If you want, you can change these settings and pass them to the worker as JSON with like this:
w.postMessage('start {"param1": "value1", "param2": "value2", ...}')
15>=515>=1035>=20garbage.phpempty.phpempty.phpgetIP.phptrue20>=1010>=33>=1falsefalse
Fetch API are used if the following conditions are met:The test can be aborted at any time by sending an abort command to the worker:
w.postMessage('abort')
This will terminate all network activity and stop the worker.
Important: do not simply kill the worker while it's running, as it will leave pending XHR requests!
If your server does not support PHP, or you're using something newer like Node.js, you can still use this test by replacing garbage.php, empty.php and getIP.php with equivalents.
garbage.phpA replacement for garbage.php must generate incompressible garbage data.
A large file (10-100 Mbytes) is a possible replacement. You can get one here.
If you're using Node.js or some other server, your replacement should accept the ckSize parameter (via GET) which tells it how many megabytes of garbage to generate.
It is important here to turn off compression, and generate incompressible data.
A symlink to /dev/urandom is also ok.
empty.phpYour replacement must simply respond with a HTTP code 200 and send nothing else. You may want to send additional headers to disable caching.
getIP.phpYour replacement must simply respond with the client's IP as plaintext. Nothing fancy.
You need to start the test with your replacements like this:
w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_ping": "newEmptyURL", "url_getIp": "newIpURL"}')
Since this is an open source project, you can modify it.
To make changes to the speedtest itself, edit speedtest_worker.js
To create the minified version, use UglifyJS like this:
uglifyjs -c --screw-ie8 speedtest_worker.js > speedtest_worker.min.js
Pull requests are much appreciated. If you don't use github (or git), simply contact me.
Important: please add your name to modified versions to distinguish them from the main project.
This software is under the GNU LGPL license, Version 3 or newer.
To put it short: you are free to use, study, modify, and redistribute this software and modified versions of it, for free or for money. You can also use it in proprietary software but all changes to this software must remain under the same GNU LGPL license.