From c1c5809b43205918717be0da9f9355d531f84414 Mon Sep 17 00:00:00 2001 From: dosse91 Date: Fri, 9 Mar 2018 14:30:13 +0100 Subject: [PATCH 01/14] Added ETH address in README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0312c31..520c8e1 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,9 @@ See the examples or doc.md Please see the ```docker``` branch ## Donate -If you want to support this project, you can [send a donation via PayPal](https://www.paypal.me/sineisochronic). +If you want to support this project, you can +[Send a donation via PayPal](https://www.paypal.me/sineisochronic). +Send ETH at this address: 0x8A5273d4e2618c4cff2C62d8EB731701FceEd8E3 ## License Copyright (C) 2016-2018 Federico Dossena From fb573933033828a7e74ae476831216c0e78b23cc Mon Sep 17 00:00:00 2001 From: dosse91 Date: Sat, 17 Mar 2018 11:16:01 +0100 Subject: [PATCH 02/14] Updated README.md --- .gitignore | 1 + README.md | 1 + 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 52b8dff..c0f3bef 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ ugly.bat +wishlist.txt diff --git a/README.md b/README.md index 520c8e1..a3197e7 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ Only modern browsers are supported (IE11, latest Edge, latest Chrome, latest Fir ## Quick installation videos * [Debian 9.0 with Apache](https://fdossena.com/?p=speedtest/quickstart_deb.frag) * [Windows Server 2016 with IIS](https://fdossena.com/?p=speedtest/quickstart_win.frag) +* [Ubuntu (External)](https://freedif.org/how-to-install-selfhosted-speedtest) Also, here's an [example config on Ubuntu 16 LTS](https://github.com/adolfintel/speedtest/issues/50) From e0dfcae1fc25c8340f0b27fd0a23b60bca2789f4 Mon Sep 17 00:00:00 2001 From: dosse Date: Wed, 21 Mar 2018 17:01:44 +0100 Subject: [PATCH 03/14] Introduced fix for broken upload test in Chromium-based mobile browsers (since version 65) --- doc.md | 6 +++++- speedtest_worker.js | 29 +++++++++++++++++------------ speedtest_worker.min.js | 2 +- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/doc.md b/doc.md index 5b67e68..1b08aec 100644 --- a/doc.md +++ b/doc.md @@ -1,7 +1,7 @@ # HTML5 Speedtest > by Federico Dossena -> Version 4.5.3, February 23, 2018 +> Version 4.5.4, March 21, 2018 > [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/) @@ -237,6 +237,10 @@ w.postMessage('start '+JSON.stringify(params)) * Default: `3` * Recommended: `>=1` * Default override: 1 on Firefox if enable_quirks is true +* __xhr_ul_blob_megabytes__: size in megabytes of the blobs sent during the upload test + * Default: `20` + * Default override: 4 on Chromium-based mobile browsers (limitation introduced around version 65). This will be forced + * Default override: IE11 and Edge currently use a different method for the upload test. This parameter is ignored * __xhr_multistreamDelay__: how long should the multiple streams be delayed (in ms) * Default: `300` * Recommended: `>=100`, `<=700` diff --git a/speedtest_worker.js b/speedtest_worker.js index 8ef3063..451000c 100644 --- a/speedtest_worker.js +++ b/speedtest_worker.js @@ -1,5 +1,5 @@ /* - HTML5 Speedtest v4.5.3 + HTML5 Speedtest v4.5.4 by Federico Dossena https://github.com/adolfintel/speedtest/ GNU LGPLv3 License @@ -39,6 +39,7 @@ var settings = { xhr_multistreamDelay: 300, //how much concurrent requests should be delayed xhr_ignoreErrors: 1, // 0=fail on errors, 1=attempt to restart a stream if it fails, 2=ignore all errors xhr_dlUseBlob: false, // if set to true, it reduces ram usage but uses the hard drive (useful with large garbagePhp_chunkSize and/or high xhr_dlMultistream) + xhr_ul_blob_megabytes: 20, //size in megabytes of the upload blobs sent in the upload test (forced to 4 on chrome mobile) garbagePhp_chunkSize: 20, // size of chunks sent by garbage.php (can be different if enable_quirks is active) enable_quirks: true, // enable quirks for specific browsers. currently it overrides settings to optimize for specific browsers, unless they are already being overridden with the start command ping_allowPerformanceApi: true, // if enabled, the ping test will attempt to calculate the ping more precisely using the Performance API. Currently works perfectly in Chrome, badly in Edge, and not at all in Firefox. If Performance API is not supported or the result is obviously wrong, a fallback is provided. @@ -109,6 +110,10 @@ this.addEventListener('message', function (e) { //Edge 15 introduced a bug that causes onprogress events to not get fired, we have to use the "small chunks" workaround that reduces accuracy settings.forceIE11Workaround = true } + if (/Chrome.(\d+)/i.test(ua)&&/Android|iPhone|iPad|iPod|Windows Phone/i.test(ua)){ //cheap af + //Chrome mobile introduced a limitation somewhere around version 65, we have to limit XHR upload size to 4 megabytes + settings.xhr_ul_blob_megabytes=4; + } //telemetry_level has to be parsed and not just copied if(typeof s.telemetry_level !== 'undefined') settings.telemetry_level = s.telemetry_level === 'basic' ? 1 : s.telemetry_level === 'full' ? 2 : 0; // telemetry level //transform test_order to uppercase, just in case @@ -252,22 +257,22 @@ function dlTest (done) { }.bind(this), 200) } // upload test, calls done function whent it's over -// garbage data for upload test -var r = new ArrayBuffer(1048576) -try { r = new Float32Array(r); for (var i = 0; i < r.length; i++)r[i] = Math.random() } catch (e) { } -var req = [] -var reqsmall = [] -for (var i = 0; i < 20; i++) req.push(r) -req = new Blob(req) -r = new ArrayBuffer(262144) -try { r = new Float32Array(r); for (var i = 0; i < r.length; i++)r[i] = Math.random() } catch (e) { } -reqsmall.push(r) -reqsmall = new Blob(reqsmall) var ulCalled = false // used to prevent multiple accidental calls to ulTest function ulTest (done) { tlog('ulTest') if (ulCalled) return; else ulCalled = true // ulTest already called? +// garbage data for upload test + var r = new ArrayBuffer(1048576) + try { r = new Float32Array(r); for (var i = 0; i < r.length; i++)r[i] = Math.random() } catch (e) { } + var req = [] + var reqsmall = [] + for (var i = 0; i < settings.xhr_ul_blob_megabytes; i++) req.push(r) + req = new Blob(req) + r = new ArrayBuffer(262144) + try { r = new Float32Array(r); for (var i = 0; i < r.length; i++)r[i] = Math.random() } catch (e) { } + reqsmall.push(r) + reqsmall = new Blob(reqsmall) var totLoaded = 0.0, // total number of transmitted bytes startT = new Date().getTime(), // timestamp when test was started graceTimeDone = false, //set to true after the grace time is past diff --git a/speedtest_worker.min.js b/speedtest_worker.min.js index d4e3668..ba2b216 100644 --- a/speedtest_worker.min.js +++ b/speedtest_worker.min.js @@ -1 +1 @@ -function tlog(s){log+=Date.now()+": "+s+"\n"}function twarn(s){log+=Date.now()+" WARN: "+s+"\n",console.warn(s)}function url_sep(url){return url.match(/\?/)?"&":"?"}function clearRequests(){if(tlog("stopping pending XHRs"),xhr){for(var i=0;iloadDiff||(totLoaded+=loadDiff,prevLoaded=event.loaded)}.bind(this),xhr[i].onload=function(){tlog("dl stream finished "+i);try{xhr[i].abort()}catch(e){}testStream(i,0)}.bind(this),xhr[i].onerror=function(){tlog("dl stream failed "+i),0===settings.xhr_ignoreErrors&&(failed=!0);try{xhr[i].abort()}catch(e){}delete xhr[i],1===settings.xhr_ignoreErrors&&testStream(i,0)}.bind(this);try{settings.xhr_dlUseBlob?xhr[i].responseType="blob":xhr[i].responseType="arraybuffer"}catch(e){}xhr[i].open("GET",settings.url_dl+url_sep(settings.url_dl)+"r="+Math.random()+"&ckSize="+settings.garbagePhp_chunkSize,!0),xhr[i].send()}}.bind(this),1+delay)}.bind(this),i=0;it))if(graceTimeDone){var speed=totLoaded/(t/1e3);dlStatus=(8*speed*settings.overheadCompensationFactor/(settings.useMebibits?1048576:1e6)).toFixed(2),(t/1e3>settings.time_dl&&dlStatus>0||failed)&&((failed||isNaN(dlStatus))&&(dlStatus="Fail"),clearRequests(),clearInterval(interval),dlProgress=1,tlog("dlTest finished "+dlStatus),done())}else t>1e3*settings.time_dlGraceTime&&(totLoaded>0&&(startT=(new Date).getTime(),totLoaded=0),graceTimeDone=!0)}.bind(this),200)}}function ulTest(done){if(tlog("ulTest"),!ulCalled){ulCalled=!0;var totLoaded=0,startT=(new Date).getTime(),graceTimeDone=!1,failed=!1;xhr=[];for(var testStream=function(i,delay){setTimeout(function(){if(3===testStatus){tlog("ul test stream started "+i+" "+delay);var prevLoaded=0,x=new XMLHttpRequest;xhr[i]=x;var ie11workaround;if(settings.forceIE11Workaround)ie11workaround=!0;else try{xhr[i].upload.onprogress,ie11workaround=!1}catch(e){ie11workaround=!0}ie11workaround?(xhr[i].onload=function(){tlog("ul stream progress event (ie11wa)"),totLoaded+=reqsmall.size,testStream(i,0)},xhr[i].onerror=function(){tlog("ul stream failed (ie11wa)"),0===settings.xhr_ignoreErrors&&(failed=!0);try{xhr[i].abort()}catch(e){}delete xhr[i],1===settings.xhr_ignoreErrors&&testStream(i,0)},xhr[i].open("POST",settings.url_ul+url_sep(settings.url_ul)+"r="+Math.random(),!0),xhr[i].setRequestHeader("Content-Encoding","identity"),xhr[i].send(reqsmall)):(xhr[i].upload.onprogress=function(event){if(tlog("ul stream progress event "+i+" "+event.loaded),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(){tlog("ul stream finished "+i),testStream(i,0)}.bind(this),xhr[i].upload.onerror=function(){tlog("ul stream failed "+i),0===settings.xhr_ignoreErrors&&(failed=!0);try{xhr[i].abort()}catch(e){}delete xhr[i],1===settings.xhr_ignoreErrors&&testStream(i,0)}.bind(this),xhr[i].open("POST",settings.url_ul+url_sep(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))if(graceTimeDone){var speed=totLoaded/(t/1e3);ulStatus=(8*speed*settings.overheadCompensationFactor/(settings.useMebibits?1048576:1e6)).toFixed(2),(t/1e3>settings.time_ul&&ulStatus>0||failed)&&((failed||isNaN(ulStatus))&&(ulStatus="Fail"),clearRequests(),clearInterval(interval),ulProgress=1,tlog("ulTest finished "+ulStatus),done())}else t>1e3*settings.time_ulGraceTime&&(totLoaded>0&&(startT=(new Date).getTime(),totLoaded=0),graceTimeDone=!0)}.bind(this),200)}}function pingTest(done){if(tlog("pingTest"),!ptCalled){ptCalled=!0;var prevT=null,ping=0,jitter=0,i=0,prevInstspd=0;xhr=[];var doPing=function(){tlog("ping"),pingProgress=i/settings.count_ping,prevT=(new Date).getTime(),xhr[0]=new XMLHttpRequest,xhr[0].onload=function(){if(tlog("pong"),0===i)prevT=(new Date).getTime();else{var instspd=(new Date).getTime()-prevT;if(settings.ping_allowPerformanceApi)try{var p=performance.getEntries();p=p[p.length-1];var d=p.responseStart-p.requestStart;0>=d&&(d=p.duration),d>0&&instspd>d&&(instspd=d)}catch(e){tlog("Performance API not supported, using estimate")}var 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++,tlog("PING: "+pingStatus+" JITTER: "+jitterStatus),i1?log:""),xhr.send(fd)}catch(ex){var postData="dl="+encodeURIComponent(dlStatus)+"&ul="+encodeURIComponent(ulStatus)+"&ping="+encodeURIComponent(pingStatus)+"&jitter="+encodeURIComponent(jitterStatus)+"&log="+encodeURIComponent(settings.telemetry_level>1?log:"");xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),xhr.send(postData)}}}var testStatus=-1,dlStatus="",ulStatus="",pingStatus="",jitterStatus="",clientIp="",dlProgress=0,ulProgress=0,pingProgress=0,log="",settings={test_order:"IP_D_U",time_ul:15,time_dl:15,time_ulGraceTime:3,time_dlGraceTime:1.5,count_ping:35,url_dl:"garbage.php",url_ul:"empty.php",url_ping:"empty.php",url_getIp:"getIP.php",getIp_ispInfo:!0,getIp_ispInfo_distance:"km",xhr_dlMultistream:10,xhr_ulMultistream:3,xhr_multistreamDelay:300,xhr_ignoreErrors:1,xhr_dlUseBlob:!1,garbagePhp_chunkSize:20,enable_quirks:!0,ping_allowPerformanceApi:!0,overheadCompensationFactor:1.06,useMebibits:!1,telemetry_level:0,url_telemetry:"telemetry.php"},xhr=null,interval=null,test_pointer=0;this.addEventListener("message",function(e){var params=e.data.split(" ");if("status"===params[0]&&postMessage(testStatus+";"+dlStatus+";"+ulStatus+";"+pingStatus+";"+clientIp+";"+jitterStatus+";"+dlProgress+";"+ulProgress+";"+pingProgress),"start"===params[0]&&-1===testStatus){testStatus=0;try{var s={};try{var ss=e.data.substring(5);ss&&(s=JSON.parse(ss))}catch(e){twarn("Error parsing custom settings JSON. Please check your syntax")}for(var key in s)"undefined"!=typeof settings[key]?settings[key]=s[key]:twarn("Unknown setting ignored: "+key);if(settings.enable_quirks||"undefined"!=typeof s.enable_quirks&&s.enable_quirks){var ua=navigator.userAgent;/Firefox.(\d+\.\d+)/i.test(ua)&&"undefined"==typeof s.xhr_ulMultistream&&(settings.xhr_ulMultistream=1),/Edge.(\d+\.\d+)/i.test(ua)&&"undefined"==typeof s.xhr_dlMultistream&&(settings.xhr_dlMultistream=3),/Chrome.(\d+)/i.test(ua)&&self.fetch&&"undefined"==typeof s.xhr_dlMultistream&&(settings.xhr_dlMultistream=5)}/Edge.(\d+\.\d+)/i.test(ua)&&(settings.forceIE11Workaround=!0),"undefined"!=typeof s.telemetry_level&&(settings.telemetry_level="basic"===s.telemetry_level?1:"full"===s.telemetry_level?2:0),settings.test_order=settings.test_order.toUpperCase()}catch(e){twarn("Possible error in custom test settings. Some settings may not be applied. Exception: "+e)}tlog(JSON.stringify(settings)),test_pointer=0;var iRun=!1,dRun=!1,uRun=!1,pRun=!1,runNextTest=function(){if(5!=testStatus){if(test_pointer>=settings.test_order.length)return testStatus=4,void sendTelemetry();switch(settings.test_order.charAt(test_pointer)){case"I":if(test_pointer++,iRun)return void runNextTest();iRun=!0,getIp(runNextTest);break;case"D":if(test_pointer++,dRun)return void runNextTest();dRun=!0,testStatus=1,dlTest(runNextTest);break;case"U":if(test_pointer++,uRun)return void runNextTest();uRun=!0,testStatus=3,ulTest(runNextTest);break;case"P":if(test_pointer++,pRun)return void runNextTest();pRun=!0,testStatus=2,pingTest(runNextTest);break;case"_":test_pointer++,setTimeout(runNextTest,1e3);break;default:test_pointer++}}};runNextTest()}"abort"===params[0]&&(tlog("manually aborted"),clearRequests(),runNextTest=null,interval&&clearInterval(interval),settings.telemetry_level>1&&sendTelemetry(),testStatus=5,dlStatus="",ulStatus="",pingStatus="",jitterStatus="")});var ipCalled=!1,dlCalled=!1,r=new ArrayBuffer(1048576);try{r=new Float32Array(r);for(var i=0;ii;i++)req.push(r);req=new Blob(req),r=new ArrayBuffer(262144);try{r=new Float32Array(r);for(var i=0;i=settings.test_order.length)return testStatus=4,void sendTelemetry();switch(settings.test_order.charAt(test_pointer)){case"I":if(test_pointer++,l)return void g();l=!0,getIp(g);break;case"D":if(test_pointer++,a)return void g();a=!0,testStatus=1,dlTest(g);break;case"U":if(test_pointer++,o)return void g();o=!0,testStatus=3,ulTest(g);break;case"P":if(test_pointer++,u)return void g();u=!0,testStatus=2,pingTest(g);break;case"_":test_pointer++,setTimeout(g,1e3);break;default:test_pointer++}}};g()}"abort"===e[0]&&(tlog("manually aborted"),clearRequests(),g=null,interval&&clearInterval(interval),settings.telemetry_level>1&&sendTelemetry(),testStatus=5,dlStatus="",ulStatus="",pingStatus="",jitterStatus="")});var ipCalled=!1;function getIp(t){tlog("getIp"),ipCalled||(ipCalled=!0,(xhr=new XMLHttpRequest).onload=function(){tlog("IP: "+xhr.responseText),clientIp=xhr.responseText,t()},xhr.onerror=function(){tlog("getIp failed"),t()},xhr.open("GET",settings.url_getIp+url_sep(settings.url_getIp)+(settings.getIp_ispInfo?"isp=true"+(settings.getIp_ispInfo_distance?"&distance="+settings.getIp_ispInfo_distance+"&":"&"):"&")+"r="+Math.random(),!0),xhr.send())}var dlCalled=!1;function dlTest(t){if(tlog("dlTest"),!dlCalled){dlCalled=!0;var e=0,r=(new Date).getTime(),s=!1,n=!1;xhr=[];for(var i=function(t,r){setTimeout(function(){if(1===testStatus){tlog("dl test stream started "+t+" "+r);var s=0,l=new XMLHttpRequest;xhr[t]=l,xhr[t].onprogress=function(r){if(tlog("dl stream progress event "+t+" "+r.loaded),1!==testStatus)try{l.abort()}catch(t){}var n=r.loaded<=0?0:r.loaded-s;isNaN(n)||!isFinite(n)||n<0||(e+=n,s=r.loaded)}.bind(this),xhr[t].onload=function(){tlog("dl stream finished "+t);try{xhr[t].abort()}catch(t){}i(t,0)}.bind(this),xhr[t].onerror=function(){tlog("dl stream failed "+t),0===settings.xhr_ignoreErrors&&(n=!0);try{xhr[t].abort()}catch(t){}delete xhr[t],1===settings.xhr_ignoreErrors&&i(t,0)}.bind(this);try{settings.xhr_dlUseBlob?xhr[t].responseType="blob":xhr[t].responseType="arraybuffer"}catch(t){}xhr[t].open("GET",settings.url_dl+url_sep(settings.url_dl)+"r="+Math.random()+"&ckSize="+settings.garbagePhp_chunkSize,!0),xhr[t].send()}}.bind(this),1+r)}.bind(this),l=0;lsettings.time_dl&&dlStatus>0||n)&&((n||isNaN(dlStatus))&&(dlStatus="Fail"),clearRequests(),clearInterval(interval),dlProgress=1,tlog("dlTest finished "+dlStatus),t())):i>1e3*settings.time_dlGraceTime&&(e>0&&(r=(new Date).getTime(),e=0),s=!0))}.bind(this),200)}}var ulCalled=!1;function ulTest(t){if(tlog("ulTest"),!ulCalled){ulCalled=!0;var e=new ArrayBuffer(1048576);try{e=new Float32Array(e);for(var r=0;rsettings.time_ul&&ulStatus>0||o)&&((o||isNaN(ulStatus))&&(ulStatus="Fail"),clearRequests(),clearInterval(interval),ulProgress=1,tlog("ulTest finished "+ulStatus),t())):e>1e3*settings.time_ulGraceTime&&(i>0&&(l=(new Date).getTime(),i=0),a=!0))}.bind(this),200)}}var ptCalled=!1;function pingTest(t){if(tlog("pingTest"),!ptCalled){ptCalled=!0;var e=null,r=0,s=0,n=0,i=0;xhr=[];var l=function(){tlog("ping"),pingProgress=n/settings.count_ping,e=(new Date).getTime(),xhr[0]=new XMLHttpRequest,xhr[0].onload=function(){if(tlog("pong"),0===n)e=(new Date).getTime();else{var a=(new Date).getTime()-e;if(settings.ping_allowPerformanceApi)try{var o=performance.getEntries(),u=(o=o[o.length-1]).responseStart-o.requestStart;u<=0&&(u=o.duration),u>0&&us?.2*s+.8*g:.9*s+.1*g),i=a}pingStatus=r.toFixed(2),jitterStatus=s.toFixed(2),n++,tlog("PING: "+pingStatus+" JITTER: "+jitterStatus),n1?log:""),xhr.send(t)}catch(t){var e="dl="+encodeURIComponent(dlStatus)+"&ul="+encodeURIComponent(ulStatus)+"&ping="+encodeURIComponent(pingStatus)+"&jitter="+encodeURIComponent(jitterStatus)+"&log="+encodeURIComponent(settings.telemetry_level>1?log:"");xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),xhr.send(e)}}} \ No newline at end of file From cd1168f78b2ac1d42a2639afcb117f12031561dc Mon Sep 17 00:00:00 2001 From: dosse91 Date: Sun, 22 Apr 2018 19:26:54 +0200 Subject: [PATCH 04/14] Updated README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index a3197e7..ce4106f 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,9 @@ See the examples or doc.md ## Docker Please see the ```docker``` branch +## Node.js backend +A Node.js implementation is available in the ```node``` branch, maintained by [dunklesToast](https://github.com/dunklesToast). + ## Donate If you want to support this project, you can [Send a donation via PayPal](https://www.paypal.me/sineisochronic). From 12b90dd47a36e402bbfd8fe067012ec6c1fd3d82 Mon Sep 17 00:00:00 2001 From: "V. D'AGOSTINO" Date: Wed, 25 Apr 2018 16:52:12 +0200 Subject: [PATCH 05/14] CSV support for telemetry (#133) Added CSV support for telemetry (#133) --- doc.md | 8 +++++++- telemetry.php | 21 +++++++++++++++++++++ telemetry_settings.php | 6 +++++- 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/doc.md b/doc.md index 1b08aec..5f85248 100644 --- a/doc.md +++ b/doc.md @@ -319,7 +319,7 @@ w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_p Telemetry currently requires PHP and either MySQL, PostgreSQL or SQLite. To set up the telemetry, we need to do 4 things: * copy `telemetry.php` and `telemetry_settings.php` -* edit `telemetry_settings.php` to add your database settings +* edit `telemetry_settings.php` to add your database settings or the csv filename and date timezone if CSV is used instead of database storage. * create the database * enable telemetry @@ -352,6 +352,12 @@ $PostgreSql_hostname="DB_HOSTNAME"; //database address, usually localhost $PostgreSql_databasename="DB_NAME"; //the name of the database where you loaded telemetry_postgresql.sql ``` +If you choose to use CSV file, you must set the Csv_File and timezone variables. +```php +$Csv_File="myReportFile.csv"; +$timezone='Europe/Paris'; +``` + ### Enabling telemetry Edit your test page; where you start the worker, you need to specify the `telemetry_level`. There are 3 levels: diff --git a/telemetry.php b/telemetry.php index 3b19adf..ce456ec 100644 --- a/telemetry.php +++ b/telemetry.php @@ -49,4 +49,25 @@ if($db_type=="mysql"){ $stmt->execute(array($ip,$ua,$lang,$dl,$ul,$ping,$jitter,$log)) or die("3"); $conn = null; } +elseif($db_type=="csv"){ + // Prepare the csv formatted string + date_default_timezone_set($timezone); + $date = date('Y-m-d H:i:s'); + $str = '"' . $date . '",'; + $str .= '"' . $ip . '",'; + $str .= '"' . $ua . '",'; + $str .= '"' . $dl . '",'; + $str .= '"' . $ul . '",'; + $str .= '"' . $ping . '",'; + $str .= '"' . $jitter . '"' . "\n"; + + // Set header if this is a new file + if (!file_exists($Csv_File)) { + $header = '"date","ip","ua","download","upload","ping","jitter"' . "\n"; + file_put_contents($Csv_File, $header, FILE_APPEND); + } + + // Writting line to file + file_put_contents($Csv_File, $str, FILE_APPEND); +} ?> diff --git a/telemetry_settings.php b/telemetry_settings.php index e27098d..4bb9b62 100644 --- a/telemetry_settings.php +++ b/telemetry_settings.php @@ -1,6 +1,6 @@ From d9c3ba36f9a5202f6c15394cad85b67fa23cdd49 Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 16:56:53 +0200 Subject: [PATCH 06/14] Updated README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ce4106f..15badde 100644 --- a/README.md +++ b/README.md @@ -40,9 +40,9 @@ Please see the ```docker``` branch A Node.js implementation is available in the ```node``` branch, maintained by [dunklesToast](https://github.com/dunklesToast). ## Donate -If you want to support this project, you can -[Send a donation via PayPal](https://www.paypal.me/sineisochronic). -Send ETH at this address: 0x8A5273d4e2618c4cff2C62d8EB731701FceEd8E3 +[![Donate with Liberapay](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/fdossena/donate) +[Donate with PayPal](https://www.paypal.me/sineisochronic) +Send ETH at this address: ```0x8A5273d4e2618c4cff2C62d8EB731701FceEd8E3``` ## License Copyright (C) 2016-2018 Federico Dossena From ec7dce1ee0737ac014330b7fa257428086494994 Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 16:58:58 +0200 Subject: [PATCH 07/14] Updated README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 15badde..48bdd2f 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,9 @@ Only modern browsers are supported (IE11, latest Edge, latest Chrome, latest Fir Also, here's an [example config on Ubuntu 16 LTS](https://github.com/adolfintel/speedtest/issues/50) ## How to use in your site -See the examples or doc.md +* See the examples +* [Read the wiki](https://github.com/adolfintel/speedtest/wiki) +* Read doc.md ## Docker Please see the ```docker``` branch From 1acc75a09732c80c64fce315b10496d7e18d35ec Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 17:02:55 +0200 Subject: [PATCH 08/14] Updated doc.md --- doc.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc.md b/doc.md index 5f85248..838f89a 100644 --- a/doc.md +++ b/doc.md @@ -1,7 +1,7 @@ # HTML5 Speedtest > by Federico Dossena -> Version 4.5.4, March 21, 2018 +> Version 4.5.5, April 25, 2018 > [https://github.com/adolfintel/speedtest/](https://github.com/adolfintel/speedtest/) @@ -319,7 +319,7 @@ w.postMessage('start {"url_dl": "newGarbageURL", "url_ul": "newEmptyURL", "url_p Telemetry currently requires PHP and either MySQL, PostgreSQL or SQLite. To set up the telemetry, we need to do 4 things: * copy `telemetry.php` and `telemetry_settings.php` -* edit `telemetry_settings.php` to add your database settings or the csv filename and date timezone if CSV is used instead of database storage. +* edit `telemetry_settings.php` to add your database or CSV settings * create the database * enable telemetry @@ -376,7 +376,7 @@ Also, see example-telemetry.html At the moment there is no front-end to see the telemetry data; you can connect to the database and see the collected results in the `speedtest_users` table. ## Troubleshooting -These are the most common issues reported by users, and how to fix them. If you still need help, contact me at [dosse91@paranoici.org](mailto:dosse91@paranoici.org). +These are the most common issues reported by users, and how to fix them. If you still need help, contact me at [info@fdossena.com](mailto:info@fdossena.com). #### Download test gives very low result Are garbage.php and empty.php (or your replacements) reachable? @@ -427,4 +427,4 @@ 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. -Contact me at [dosse91@paranoici.org](mailto:dosse91@paranoici.org) for other licensing models. +Contact me at [info@fdossena.com](mailto:info@fdossena.com) for other licensing models. From b811a4d4b295c58d110d9a5d518e49c20f7ecd9e Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 17:04:06 +0200 Subject: [PATCH 09/14] Updated doc.md --- doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc.md b/doc.md index 838f89a..405647f 100644 --- a/doc.md +++ b/doc.md @@ -416,7 +416,7 @@ To create the minified version, use UglifyJS like this: uglifyjs -c speedtest_worker.js > speedtest_worker.min.js ``` -Pull requests are very appreciated. If you don't use github (or git), simply contact me at [dosse91@paranoici.org](mailto:dosse91@paranoici.org). +Pull requests are very appreciated. If you don't use github (or git), simply contact me at [info@fdossena.com](mailto:info@fdossena.com). __Important:__ please add your name to modified versions to distinguish them from the main project. From baaf2a85c4a1238a8e1184c18ce0ab8335f872c7 Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 17:07:25 +0200 Subject: [PATCH 10/14] Updated doc.md --- doc.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc.md b/doc.md index 405647f..b67d316 100644 --- a/doc.md +++ b/doc.md @@ -316,7 +316,7 @@ 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"}') ``` ## Telemetry -Telemetry currently requires PHP and either MySQL, PostgreSQL or SQLite. +Telemetry currently requires PHP and either MySQL, PostgreSQL or SQLite. Alternatively, it is possible to save to a CSV file. To set up the telemetry, we need to do 4 things: * copy `telemetry.php` and `telemetry_settings.php` * edit `telemetry_settings.php` to add your database or CSV settings @@ -330,7 +330,7 @@ If you see a table called `speedtest_users`, empty, you did it right. ### Configuring `telemetry.php` Open telemetry_settings.php with notepad or a similar text editor. -Set your preferred database, ``$db_type="mysql";``, ``$db_type="sqlite";`` or ``$db_type="postgresql";`` +Set your preferred database, ``$db_type="mysql";``, ``$db_type="sqlite";``, ``$db_type="postgresql";`` or or ``$db_type="csv";`` If you choose to use Sqlite3, you must set the path to your database file: ```php $Sqlite_db_file = "../telemetry.sql"; @@ -352,7 +352,7 @@ $PostgreSql_hostname="DB_HOSTNAME"; //database address, usually localhost $PostgreSql_databasename="DB_NAME"; //the name of the database where you loaded telemetry_postgresql.sql ``` -If you choose to use CSV file, you must set the Csv_File and timezone variables. +If you choose to use a CSV file, you must set the Csv_File and timezone variables. ```php $Csv_File="myReportFile.csv"; $timezone='Europe/Paris'; From e3d0558324aa783a4f85e34c593524e4723a525e Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 17:08:55 +0200 Subject: [PATCH 11/14] Updated doc.md --- doc.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc.md b/doc.md index b67d316..dd03a41 100644 --- a/doc.md +++ b/doc.md @@ -357,6 +357,7 @@ If you choose to use a CSV file, you must set the Csv_File and timezone variable $Csv_File="myReportFile.csv"; $timezone='Europe/Paris'; ``` +__Note__: CSV currently only supports basic telemetry, the log will not be saved ### Enabling telemetry Edit your test page; where you start the worker, you need to specify the `telemetry_level`. From 5cae01960becb903718da7db0c1bc1f9f32c5c1f Mon Sep 17 00:00:00 2001 From: dosse91 Date: Wed, 25 Apr 2018 17:12:05 +0200 Subject: [PATCH 12/14] Updated doc.md --- doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc.md b/doc.md index dd03a41..edbb95c 100644 --- a/doc.md +++ b/doc.md @@ -324,7 +324,7 @@ To set up the telemetry, we need to do 4 things: * enable telemetry ### Creating the database -This step is only for MySQL and PostgreSQL. Skip this if you want to use SQLite. +This step is only for MySQL and PostgreSQL. Log into your database using phpMyAdmin or a similar software and import the appropriate sql file into an empty database. For MySQL databases use `telemetry_mysql.sql` and for PostgreSQL databases use `telemetry_postgesql.sql`. If you see a table called `speedtest_users`, empty, you did it right. From 8c27da939b4af5190f3b78b82f4cfd958527fbb4 Mon Sep 17 00:00:00 2001 From: "V. D'AGOSTINO" Date: Wed, 25 Apr 2018 21:03:18 +0200 Subject: [PATCH 13/14] Avoid requesting ipinfo.io and generating a php error when the connection is from localhost (#135) --- getIP.php | 150 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 62 deletions(-) diff --git a/getIP.php b/getIP.php index 97bfe53..7c414c2 100644 --- a/getIP.php +++ b/getIP.php @@ -1,68 +1,94 @@ From 752cf462b3176a4ed58252f14e73a73aac99e320 Mon Sep 17 00:00:00 2001 From: dosse91 Date: Sun, 29 Apr 2018 13:53:02 +0200 Subject: [PATCH 14/14] Updated doc.md --- doc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc.md b/doc.md index edbb95c..8c492c9 100644 --- a/doc.md +++ b/doc.md @@ -404,7 +404,7 @@ Make sure your server is sending the ```Connection:keep-alive``` header * On IE11, a same origin policy error is erroneously triggered under unknown conditions. Seems to be related to running the test from unusual URLs like a top level domain (for instance http://abc/speedtest). These are bugs in IE11's implementation of the same origin policy, not in the speedtest itself. * On IE11, under unknown circumstances, on some systems the test can only be run once, after which speedtest_worker.js will not be loaded by IE until the browser is restarted. This is a rare bug in IE11. ### Firefox-Specific -* On some Linux systems with hardware acceleration turned off, the page rendering makes the browser lag, reducing the accuracy of the ping/jitter test +* On some Linux systems with hardware acceleration turned off, the page rendering makes the browser lag, reducing the accuracy of the ping/jitter test, and potentially even the download and upload tests on very fast connections. ## Making changes Since this is an open source project, you can modify it.