external-ip
Advanced tools
Comparing version 0.1.5 to 0.2.0
103
index.js
'use strict'; | ||
var extIP = require('./lib/extIP'); | ||
var utils = require('./lib/utils'); | ||
module.exports = function (extConf) { | ||
extConf = extConf || {}; | ||
var isValid = utils.validateConfig(extConf); | ||
if (isValid.errors.length) { | ||
console.error(isValid.errors); | ||
process.exit(1); | ||
} | ||
// Check: https://github.com/mjhasbach/MOIRA | ||
var defConf = { | ||
getIP: 'sequential', // parallel | ||
replace: false, | ||
services: [ | ||
'http://ifconfig.co/x-real-ip', | ||
'http://icanhazip.com/', | ||
'http://ifconfig.me/ip', | ||
'http://ip.appspot.com/', | ||
'http://curlmyip.com/', | ||
'http://ident.me/', | ||
'http://whatismyip.akamai.com/', | ||
'http://tnx.nl/ip', | ||
'http://myip.dnsomatic.com/', | ||
'http://ipecho.net/plain' | ||
], | ||
timeout: 500 | ||
}; | ||
var config = utils.mergeConfig(extConf, defConf); | ||
var services = extIP.setup(config).services; | ||
var getIP = { | ||
sequential: function (cb) { | ||
var errors = []; | ||
utils.asyncLoop({ | ||
iterations: services.length, | ||
exec: function (i, stop, next) { | ||
services[i].getIP(function (err, ip) { | ||
if (err) { | ||
err = services[i].url + ' : ' + err; | ||
errors.push(err); | ||
next(); | ||
} else { | ||
stop(ip); | ||
} | ||
}); | ||
}, | ||
done: function (ip) { | ||
cb.apply(null, ip ? [null, ip] : [errors, null]); | ||
} | ||
}); | ||
}, | ||
parallel: function (cb) { | ||
var done = false; | ||
var errors = []; | ||
var requests; | ||
var abort = function (requests) { | ||
process.nextTick(function () { | ||
requests.forEach(function (request) { | ||
request.abort(); | ||
}); | ||
}); | ||
}; | ||
var onResponse = function (err, ip) { | ||
if (done) { | ||
return; | ||
} | ||
if (err) { | ||
errors.push(err); | ||
} | ||
if(ip) { | ||
done = true; | ||
abort(requests); //async | ||
return cb(null, ip); | ||
} | ||
if (errors.length === services.length) { | ||
done = true; | ||
abort(requests); //async | ||
return cb(errors, null); | ||
} | ||
}; | ||
requests = services.map(function (service) { | ||
return service.getIP(onResponse); | ||
}); | ||
} | ||
}; | ||
return getIP[config.getIP]; | ||
}; | ||
module.exports = require('./lib/extIP'); |
124
lib/extIP.js
'use strict'; | ||
var request = require('request'); | ||
var requests = require('./requests'); | ||
var utils = require('./utils'); | ||
module.exports.setup = function (config) { | ||
module.exports = function (extConf) { | ||
extConf = extConf || {}; | ||
var isValid = utils.validateConfig(extConf); | ||
var addValidation = function (request) { | ||
return function (cb) { | ||
return request(function (err, body) { | ||
if (err) { | ||
return cb(err, null); | ||
} | ||
// if the body is null use an empty string | ||
body = (body || '').toString().replace('\n', ''); | ||
return cb.apply(null, utils.isIP(body) ? [null, body] : [new Error('Invalid IP'), null]); | ||
if (isValid.errors.length) { | ||
console.error(isValid.errors); | ||
process.exit(1); | ||
} | ||
}); | ||
}; | ||
// Check: https://github.com/mjhasbach/MOIRA | ||
var defConf = { | ||
getIP: 'sequential', // parallel | ||
replace: false, | ||
services: [ | ||
'http://ifconfig.co/x-real-ip', | ||
'http://icanhazip.com/', | ||
'http://ifconfig.me/ip', | ||
'http://ip.appspot.com/', | ||
'http://curlmyip.com/', | ||
'http://ident.me/', | ||
'http://whatismyip.akamai.com/', | ||
'http://tnx.nl/ip', | ||
'http://myip.dnsomatic.com/', | ||
'http://ipecho.net/plain' | ||
], | ||
timeout: 1000 | ||
}; | ||
var requestFactory = function (request, url) { | ||
return function (cb) { | ||
return request.get({ | ||
url: url, | ||
timeout: config.timeout, | ||
headers: { | ||
'User-Agent': 'curl/' | ||
var config = utils.mergeConfig(extConf, defConf); | ||
var services = requests.setup(config).services; | ||
var getIP = { | ||
sequential: function (cb) { | ||
var errors = []; | ||
utils.asyncLoop({ | ||
iterations: services.length, | ||
exec: function (i, stop, next) { | ||
services[i].getIP(function (err, ip) { | ||
if (err) { | ||
err = services[i].url + ' : ' + err; | ||
errors.push(err); | ||
next(); | ||
} else { | ||
stop(ip); | ||
} | ||
}); | ||
}, | ||
done: function (ip) { | ||
cb.apply(null, ip ? [null, ip] : [errors, null]); | ||
} | ||
}, function (err, res, body) { | ||
cb.apply(null, err ? [err, null] : [null, body]); | ||
}); | ||
}; | ||
}; | ||
}, | ||
var initializeServices = function (services) { | ||
return services.map(function (url) { | ||
return { | ||
getIP: addValidation(requestFactory(request, url)), | ||
url: url | ||
parallel: function (cb) { | ||
var done = false; | ||
var errors = []; | ||
var requests; | ||
var abort = function (requests) { | ||
process.nextTick(function () { | ||
requests.forEach(function (request) { | ||
request.abort(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
}; | ||
return { | ||
addValidation: addValidation, | ||
requestFactory: requestFactory, | ||
initializeServices: initializeServices, | ||
services: initializeServices(config.services) | ||
var onResponse = function (err, ip) { | ||
if (done) { | ||
return; | ||
} | ||
if (err) { | ||
errors.push(err); | ||
} | ||
if(ip) { | ||
done = true; | ||
abort(requests); //async | ||
return cb(null, ip); | ||
} | ||
if (errors.length === services.length) { | ||
done = true; | ||
abort(requests); //async | ||
return cb(errors, null); | ||
} | ||
}; | ||
requests = services.map(function (service) { | ||
return service.getIP(onResponse); | ||
}); | ||
} | ||
}; | ||
return getIP[config.getIP]; | ||
}; |
{ | ||
"name": "external-ip", | ||
"version": "0.1.5", | ||
"version": "0.2.0", | ||
"description": "A node.js library to get your external ip from multiple services", | ||
@@ -9,2 +9,5 @@ "main": "index.js", | ||
}, | ||
"bin": { | ||
"external-ip": "lib/cli.js" | ||
}, | ||
"repository": { | ||
@@ -22,2 +25,8 @@ "type": "git", | ||
"author": "J.Chaniotis", | ||
"contributors": [ | ||
{ | ||
"name": "Nikolas Andronopoulos", | ||
"email": "nikolas.andronopoulos@gmail.com" | ||
} | ||
], | ||
"license": "ISC", | ||
@@ -29,2 +38,3 @@ "bugs": { | ||
"dependencies": { | ||
"commander": "^2.3.0", | ||
"request": "^2.40.0", | ||
@@ -31,0 +41,0 @@ "revalidator": "^0.2.0" |
@@ -1,2 +0,2 @@ | ||
#external-ip [![Build Status](https://travis-ci.org/J-Chaniotis/external-ip.svg?branch=master)](https://travis-ci.org/J-Chaniotis/external-ip) [![Dependency Status](https://david-dm.org/J-Chaniotis/external-ip.svg)](https://david-dm.org/J-Chaniotis/external-ip) | ||
#external-ip [![Build Status](https://travis-ci.org/J-Chaniotis/external-ip.svg?branch=master)](https://travis-ci.org/J-Chaniotis/external-ip) ![Dependencies](https://david-dm.org/J-chaniotis/external-ip.svg) | ||
@@ -58,3 +58,3 @@ ![XKCD 865](http://imgs.xkcd.com/comics/nanobots.png) | ||
external-ip exposes a constructor function that accepts a configuration object with the following optional properties: | ||
* **services:** `Array` of urls that return the ip in the document body, required if replace is set to true | ||
* **services:** `Array` of urls that return the ip in the html body, required if replace is set to true | ||
* **replace:** `Boolean` if true, replaces the internal array of services with the user defined, if false, extends it, default: `false` | ||
@@ -71,8 +71,26 @@ * **timeout:** Timeout per request in ms, default `500` | ||
##CLI | ||
install as a global package with `npm install -g external-ip`. | ||
``` | ||
$ external-ip -h | ||
Usage: external-ip [options] | ||
Options: | ||
-h, --help output usage information | ||
-R, --replace replace services set with -s insted of adding | ||
-s, --services <url> url of service that returns the IP in the HTML body, one per -s, required if using -R | ||
-t, --timeout <msec> set timeout per request | ||
-P, --parallel set to parallel mode | ||
This program prints the external IP of the machine. | ||
All arguments are optional. | ||
Examples: | ||
$ external-ip | ||
$ external-ip -P -t 1500 -R -s http://icanhazip.com/ -s http://ifconfig.me/ip | ||
``` | ||
##Test | ||
Change your working directory to the project's root, `npm install` to get the development dependencies and then run `npm test` | ||
##Todo | ||
maybe a CLI | ||
##Links | ||
@@ -79,0 +97,0 @@ * [moira](https://www.npmjs.org/package/moira) |
23805
15
522
97
3
+ Addedcommander@^2.3.0
+ Addedcommander@2.20.3(transitive)