// test settings. can be overridden by sending specific values with the start command
varsettings={
time_ul:15,// duration of upload test in seconds
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_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)
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)
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
allow_fetchAPI:false,// enables Fetch API. currently disabled because it leaks memory like no tomorrow
force_fetchAPI:false// when Fetch API is enabled, it will force usage on every browser that supports it
}
varxhr=null// array of currently active xhr requests
vartotLoaded=0.0// total number of transmitted bytes
varstartT=newDate().getTime()// timestamp when test was started
varfailed=false// set to true if a stream fails
xhr=[]
// function to create an upload stream. streams are slightly delayed so that they will not end at the same time
vartestStream=function(i,delay){
setTimeout(function(){
if(testStatus!==3)return// delayed stream ended up starting after the end of the upload test
varprevLoaded=0// number of bytes transmitted last time onprogress was called
varx=newXMLHttpRequest()
xhr[i]=x
varie11workaround
try{
xhr[i].upload.onprogress
ie11workaround=false
}catch(e){
ie11workaround=true
}
if(ie11workaround){
// IE11 workarond: xhr.upload does not work properly, therefore we send a bunch of small 256k requests and use the onload event as progress. This is not precise, especially on fast connections
xhr[i].onload=function(){
totLoaded+=262144
testStream(i,0)
}
xhr[i].onerror=function(){
// error, abort
failed=true
try{xhr[i].abort()}catch(e){}
delete(xhr[i])
}
xhr[i].open('POST',settings.url_ul+'?r='+Math.random(),true)// random string to prevent caching
xhr[i].setRequestHeader('Content-Encoding','identity')// disable compression (some browsers may refuse it, but data is incompressible anyway)
xhr[i].send(reqsmall)
}else{
// REGULAR version, no workaround
xhr[i].upload.onprogress=function(event){
if(testStatus!==3){try{x.abort()}catch(e){}}// just in case this XHR is still running after the upload test
// progress event, add number of new loaded bytes to totLoaded
varprevInstspd=0// last ping time, used for jitter calculation
xhr=[]
// ping function
vardoPing=function(){
prevT=newDate().getTime()
xhr[0]=newXMLHttpRequest()
xhr[0].onload=function(){
// pong
if(i===0){
prevT=newDate().getTime()// first pong
}else{
varinstspd=(newDate().getTime()-prevT)/2
varinstjitter=Math.abs(instspd-prevInstspd)
if(i===1)ping=instspd;/* first ping, can't tell jiutter yet*/else{
ping=ping*0.9+instspd*0.1// ping, weighted average
jitter=instjitter>jitter?(jitter*0.2+instjitter*0.8):(jitter*0.9+instjitter*0.1)// update jitter, weighted average. spikes in ping values are given more weight.
}
prevInstspd=instspd
}
pingStatus=ping.toFixed(2)
jitterStatus=jitter.toFixed(2)
i++
if(i<settings.count_ping)doPing();elsedone()// more pings to do?
}.bind(this)
xhr[0].onerror=function(){
// a ping failed, cancel test
pingStatus='Fail'
jitterStatus='Fail'
clearRequests()
done()
}.bind(this)
// sent xhr
xhr[0].open('GET',settings.url_ping+'?r='+Math.random(),true)// random string to prevent caching