12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- //
- // GeoIP lookup service
- //
- // GeoIP cache TTL in ms
- var CACHE_TTL = (60 * 60 * 24 * 60 * 1000); // 60 days
- var config = require(__dirname + '/config.js');
- if (!config.maxmind) {
- console.error('FATAL: only MaxMind GeoIP2 is currently supported and is not configured in config.js');
- process.exit(1);
- }
- var geo = require('geoip2ws')(config.maxmind);
- var cache = require('levelup')(__dirname + '/cache.leveldb');
- function lookup(ip,callback)
- {
- cache.get(ip,function(err,cachedEntryJson) {
- if ((!err)&&(cachedEntryJson)) {
- try {
- var cachedEntry = JSON.parse(cachedEntryJson.toString());
- if (cachedEntry) {
- var ts = cachedEntry.ts;
- var r = cachedEntry.r;
- if ((ts)&&(r)) {
- if ((Date.now() - ts) < CACHE_TTL) {
- r._cached = true;
- return callback(null,r);
- }
- }
- }
- } catch (e) {}
- }
- geo(ip,function(err,result) {
- if (err)
- return callback(err,null);
- if ((!result)||(!result.location))
- return callback(new Error('null result'),null);
- cache.put(ip,JSON.stringify({
- ts: Date.now(),
- r: result
- }),function(err) {
- if (err)
- console.error('Error saving to cache: '+err);
- return callback(null,result);
- });
- });
- });
- };
- var linebuf = '';
- process.stdin.on('readable',function() {
- var chunk;
- while (null !== (chunk = process.stdin.read())) {
- for(var i=0;i<chunk.length;++i) {
- var c = chunk[i];
- if ((c == 0x0d)||(c == 0x0a)) {
- if (linebuf.length > 0) {
- var ip = linebuf;
- lookup(ip,function(err,result) {
- if ((err)||(!result)||(!result.location)) {
- return process.stdout.write(ip+',0,0,0,0,0,0\n');
- } else {
- var lat = parseFloat(result.location.latitude);
- var lon = parseFloat(result.location.longitude);
- // Convert to X,Y,Z coordinates from Earth's origin, Earth-as-sphere approximation.
- var latRadians = lat * 0.01745329251994; // PI / 180
- var lonRadians = lon * 0.01745329251994; // PI / 180
- var cosLat = Math.cos(latRadians);
- var x = Math.round((-6371.0) * cosLat * Math.cos(lonRadians)); // 6371 == Earth's approximate radius in kilometers
- var y = Math.round(6371.0 * Math.sin(latRadians));
- var z = Math.round(6371.0 * cosLat * Math.sin(lonRadians));
- return process.stdout.write(ip+',1,'+lat+','+lon+','+x+','+y+','+z+'\n');
- }
- });
- }
- linebuf = '';
- } else {
- linebuf += String.fromCharCode(c);
- }
- }
- }
- });
- process.stdin.on('end',function() {
- cache.close();
- process.exit(0);
- });
|