description and source-codefunction speedTest(options) {
options = options || {};
options.maxTime = options.maxTime || 10000;
options.pingCount = options.pingCount || (options.serverId ? 1 : 5);
options.maxServers = options.maxServers || 1;
var self = new EventEmitter()
, speedInfo = {}
, serversUrls = [
'http://www.speedtest.net/speedtest-servers-static.php',
'http://www.speedtest.net/speedtest-servers-static.php?really=yes',
'https://www.speedtest.net/speedtest-servers-static.php',
'https://www.speedtest.net/speedtest-servers-static.php?really=totally',
'http://www.speedtest.net/speedtest-servers.php',
'http://www.speedtest.net/speedtest-servers.php?really=sure',
'https://www.speedtest.net/speedtest-servers.php',
'https://www.speedtest.net/speedtest-servers.php?really=absolutely'
]
, curServer = 0
, serversUrl
;
function httpOpts(theUrl) {
var o = url.parse(theUrl);
o.headers = options.headers || {};
return o;
}
//Fetch config
getXML(httpOpts('http://www.speedtest.net/speedtest-config.php'), gotConfig);
function gotConfig(err, config) {
if (err) return self.emit('error', err);
config = config && config.settings || {};
function get(name) {
return ((config[name] || [])[0] || {}).$ || {}
}
var client = get('client')
, times = get('times')
, download = get('download')
, upload = get('upload')
;
speedInfo.config = {client: client, times: times, download: download, upload: upload};
self.emit('config', speedInfo.config);
gotData();
}
if (options.serversUrl) {
serversUrl = options.serversUrl;
curServer = -1;
}
function nextServer(err) {
if (curServer >= serversUrls.length) {
return self.emit('error', err || new Error('There was a problem getting the list of servers from SpeedTest.net. Consider using
a custom serversUrl'));
}
if (curServer < 0) {
curServer = serversUrls.length;
} else {
serversUrl = serversUrls[curServer];
curServer++;
}
getXML(httpOpts(serversUrl), gotServers);
}
nextServer();
function gotServers(err, servers) {
if (err || !servers) return nextServer(err);
var s = servers.settings.servers[0].server;
servers = [];
for (var n = 0; n < s.length; n++) {
if (options.serverId && s[n].$.id == options.serverId) {
servers = [s[n].$];
break;
}
servers.push(s[n].$);
}
speedInfo.servers = servers;
self.emit('servers', servers);
gotData()
}
function gotData() {
if (!speedInfo.config || !speedInfo.servers) return; //not ready yet
//order servers by how close they are:
var servers = speedInfo.servers;
for (var n = 0; n < servers.length; n++) {
var server = servers[n]
, dist = distance(speedInfo.config.client, server)
;
server.dist = dist;
server.distMi = dist * 0.621371;
}
servers.sort(function(a, b) {
return (a.dist - b.dist);
});
pingServers(servers, options.pingCount, function(err, bestServers) {
if (!bestServers || !bestServers.length) return self.emit('error', new Error('Could not find a server to test on.'));
speedInfo.bestServers = bestServers;
speedInfo.bestServer = speedInfo.bestServers[0];
self.emit('bestservers', bestServers);
startDownload();
});
}
function startDownload(ix) {
ix = ix || 0;
if (ix >= speedInfo.bestServers.length || ix >= options.maxServers) return startUpload();
var server = speedInfo.bestServers[ix]
, svrurl = server.url
, sizes = [350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000]
, urls = []
, n
, i
, size
;
for (n = 0; n < sizes.length; n++) {
size = sizes[n];
for (i = 0; i < 4; i++) {
urls.push(url.resolve(svrurl, 'random' + size + 'x' + size + '.jpg'));
}
}
self.emit('testserver', server);
downloadSpeed.call(self, urls, options.maxTime, function(err ...