diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 5f72c58..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -doc.odt -cktest.html diff --git a/doc.md b/doc.md index 613a070..c4ad91d 100644 --- a/doc.md +++ b/doc.md @@ -1,7 +1,7 @@ # HTML5 Speedtest > by Federico Dossena -> Version 4.2, April 26 2017 +> Version 4.2.1, May 15 2017 > [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/) @@ -31,7 +31,7 @@ To install the test on your server, upload the following files: * `speedtest_worker.min.js` * `garbage.php` * `getIP.php` -* `empty.dat` +* `empty.php` You may also want to upload one of the examples to test it. Later we'll see how to use the test without PHP. @@ -139,11 +139,11 @@ w.postMessage('start {"param1": "value1", "param2": "value2", ...}') * __url_dl__: path to garbage.php or a large file to use for the download test * Default: `garbage.php` * __Important:__ path is relative to js file -* __url_ul__: path to ab empty file or empty.dat to use for the upload test - * Default: `empty.dat` +* __url_ul__: path to ab empty file or empty.php to use for the upload test + * Default: `empty.php` * __Important:__ path is relative to js file -* __url_ping__: path to an empty file or empty.dat to use for the ping test - * Default: `empty.dat` +* __url_ping__: path to an empty file or empty.php to use for the ping test + * Default: `empty.php` * __Important:__ path is relative to js file * __url_getIp__: path to getIP.php or replacement * Default: `getIP.php` @@ -186,7 +186,7 @@ __Important:__ do not simply kill the worker while it's running, as it will leav ## Using the test without PHP -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` and `getIP.php`. +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. ### Replacements @@ -199,6 +199,9 @@ If you're using Node.js or some other server, your replacement should accept the It is important here to turn off compression, and generate incompressible data. A symlink to `/dev/urandom` is also ok. +#### Replacement for `empty.php` +Your replacement must simply respond with a HTTP code 200 and send nothing else. You may want to send additional headers to disable caching. + #### Replacement for `getIP.php` Your replacement must simply respond with the client's IP as plaintext. Nothing fancy. @@ -206,7 +209,7 @@ Your replacement must simply respond with the client's IP as plaintext. Nothing You need to start the test with your replacements like this: ```js -w.postMessage('start {"url_dl": "newGarbageURL", "url_getIp": "newIpURL"}') +w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_ping": "newEmptyURL", "url_getIp": "newIpURL"}') ``` diff --git a/empty.dat b/empty.dat deleted file mode 100644 index e69de29..0000000 diff --git a/empty.php b/empty.php new file mode 100644 index 0000000..7395f6c --- /dev/null +++ b/empty.php @@ -0,0 +1,6 @@ + \ No newline at end of file diff --git a/example2.html b/example2.html index af945df..cf228ba 100644 --- a/example2.html +++ b/example2.html @@ -85,7 +85,7 @@ jitter.textContent = data[5] ip.textContent = 'Your IP: ' + data[4] } - w.postMessage('start {"url_dl": "garbage.php", "url_ul": "empty.dat", "url_ping": "empty.dat", "time_dl": "10", "time_ul": "15", "count_ping": "30"}') // start with custom parameters. paths are relative to js file. you can omit parameters that you don't want to change + w.postMessage('start {"url_dl": "garbage.php", "url_ul": "empty.php", "url_ping": "empty.php", "time_dl": "10", "time_ul": "15", "count_ping": "30"}') // start with custom parameters. paths are relative to js file. you can omit parameters that you don't want to change diff --git a/example4.html b/example4.html index 13f8160..09519ab 100644 --- a/example4.html +++ b/example4.html @@ -85,7 +85,7 @@ document.getElementById('ip').textContent = 'Your IP: ' + data[4] updateGauge(ggjitter, data[5]) } - w.postMessage('start {"time_ul": "10", "time_dl": "10", "count_ping": "50", "url_dl": "garbage.php", "url_ul": "empty.dat", "url_ping": "empty.dat", "url_getIp": "getIP.php"}') + w.postMessage('start {"time_ul": "10", "time_dl": "10", "count_ping": "50", "url_dl": "garbage.php", "url_ul": "empty.php", "url_ping": "empty.php", "url_getIp": "getIP.php"}') } function abortTest() { if (w) w.postMessage('abort') diff --git a/speedtest_worker.js b/speedtest_worker.js index 8a1bcca..19bc8aa 100644 --- a/speedtest_worker.js +++ b/speedtest_worker.js @@ -1,5 +1,5 @@ /* - HTML5 Speedtest v4.1 + HTML5 Speedtest v4.2.1 by Federico Dossena https://github.com/adolfintel/speedtest/ GNU LGPLv3 License @@ -19,8 +19,8 @@ var settings = { time_dl: 15, // duration of download test in seconds count_ping: 35, // number of pings to perform in ping test url_dl: 'garbage.php', // path to a large file or garbage.php, used for download test. must be relative to this js file - url_ul: 'empty.dat', // path to an empty file, used for upload test. must be relative to this js file - url_ping: 'empty.dat', // path to an empty file, used for ping test. must be relative to this js file + url_ul: 'empty.php', // path to an empty file, used for upload test. must be relative to this js file + url_ping: 'empty.php', // path to an empty file, used for ping test. must be relative to this js file url_getIp: 'getIP.php', // path to getIP.php relative to this js file, or a similar thing that outputs the client's ip xhr_dlMultistream: 10, // number of download streams to use (can be different if enable_quirks is active) xhr_ulMultistream: 3, // number of upload streams to use (can be different if enable_quirks is active) diff --git a/speedtest_worker.min.js b/speedtest_worker.min.js index 5e43566..fab73a0 100644 --- a/speedtest_worker.min.js +++ b/speedtest_worker.min.js @@ -1 +1 @@ -function clearRequests(){if(xhr){for(var i=0;isettings.time_ul||failed)&&((failed||isNaN(ulStatus))&&(ulStatus="Fail"),clearRequests(),clearInterval(interval),done())}}.bind(this),200)}}function pingTest(done){if(!ptCalled){ptCalled=!0;var prevT=null,ping=0,jitter=0,i=0,prevInstspd=0;xhr=[];var doPing=function(){prevT=(new Date).getTime(),xhr[0]=new XMLHttpRequest,xhr[0].onload=function(){if(0===i)prevT=(new Date).getTime();else{var instspd=((new Date).getTime()-prevT)/2,instjitter=Math.abs(instspd-prevInstspd);1===i?ping=instspd:(ping=.9*ping+.1*instspd,jitter=instjitter>jitter?.2*jitter+.8*instjitter:.9*jitter+.1*instjitter),prevInstspd=instspd}pingStatus=ping.toFixed(2),jitterStatus=jitter.toFixed(2),i++,iloadDiff||(totLoaded+=loadDiff,prevLoaded=event.loaded)}.bind(this),xhr[i].onload=function(){try{xhr[i].abort()}catch(e){}testStream(i,0)}.bind(this),xhr[i].onerror=function(){failed=!0;try{xhr[i].abort()}catch(e){}delete xhr[i]}.bind(this);try{settings.xhr_dlUseBlob?xhr[i].responseType="blob":xhr[i].responseType="arraybuffer"}catch(e){}xhr[i].open("GET",settings.url_dl+"?r="+Math.random()+"&ckSize="+settings.garbagePhp_chunkSize,!0),xhr[i].send()}}.bind(this),1+delay)}.bind(this),i=0;it)){var speed=totLoaded/(t/1e3);dlStatus=(8*speed/925e3).toFixed(2),(t/1e3>settings.time_dl||failed)&&((failed||isNaN(dlStatus))&&(dlStatus="Fail"),clearRequests(),clearInterval(interval),done())}}.bind(this),200)}}function ulTest(done){if(!ulCalled){ulCalled=!0;var totLoaded=0,startT=(new Date).getTime(),failed=!1;xhr=[];for(var testStream=function(i,delay){setTimeout(function(){if(3===testStatus){var prevLoaded=0,x=new XMLHttpRequest;xhr[i]=x;var ie11workaround;try{xhr[i].upload.onprogress,ie11workaround=!1}catch(e){ie11workaround=!0}ie11workaround?(xhr[i].onload=function(){totLoaded+=262144,testStream(i,0)},xhr[i].onerror=function(){failed=!0;try{xhr[i].abort()}catch(e){}delete xhr[i]},xhr[i].open("POST",settings.url_ul+"?r="+Math.random(),!0),xhr[i].setRequestHeader("Content-Encoding","identity"),xhr[i].send(reqsmall)):(xhr[i].upload.onprogress=function(event){if(3!==testStatus)try{x.abort()}catch(e){}var loadDiff=event.loaded<=0?0:event.loaded-prevLoaded;isNaN(loadDiff)||!isFinite(loadDiff)||0>loadDiff||(totLoaded+=loadDiff,prevLoaded=event.loaded)}.bind(this),xhr[i].upload.onload=function(){testStream(i,0)}.bind(this),xhr[i].upload.onerror=function(){failed=!0;try{xhr[i].abort()}catch(e){}delete xhr[i]}.bind(this),xhr[i].open("POST",settings.url_ul+"?r="+Math.random(),!0),xhr[i].setRequestHeader("Content-Encoding","identity"),xhr[i].send(req))}}.bind(this),1)}.bind(this),i=0;it)){var speed=totLoaded/(t/1e3);ulStatus=(8*speed/925e3).toFixed(2),(t/1e3>settings.time_ul||failed)&&((failed||isNaN(ulStatus))&&(ulStatus="Fail"),clearRequests(),clearInterval(interval),done())}}.bind(this),200)}}function pingTest(done){if(!ptCalled){ptCalled=!0;var prevT=null,ping=0,jitter=0,i=0,prevInstspd=0;xhr=[];var doPing=function(){prevT=(new Date).getTime(),xhr[0]=new XMLHttpRequest,xhr[0].onload=function(){if(0===i)prevT=(new Date).getTime();else{var instspd=((new Date).getTime()-prevT)/2,instjitter=Math.abs(instspd-prevInstspd);1===i?ping=instspd:(ping=.9*ping+.1*instspd,jitter=instjitter>jitter?.2*jitter+.8*instjitter:.9*jitter+.1*instjitter),prevInstspd=instspd}pingStatus=ping.toFixed(2),jitterStatus=jitter.toFixed(2),i++,ii;i++)req.push(r);req=new Blob(req),r=new ArrayBuffer(262144);try{r=new Float32Array(r);for(var i=0;i