Comparing version 0.1.2 to 0.2.0
@@ -1,2 +0,3 @@ | ||
var nat = require('../nat-upnp'); | ||
var nat = require('../nat-upnp'), | ||
async = require('async'); | ||
@@ -6,2 +7,3 @@ var client = exports; | ||
function Client() { | ||
this.ssdp = nat.ssdp.create(); | ||
}; | ||
@@ -44,3 +46,4 @@ | ||
['NewPortMappingDescription', options.description || 'node:nat:upnp'], | ||
['NewLeaseDuration', options.ttl || 60 * 30] | ||
['NewLeaseDuration', typeof options.ttl === 'number' ? | ||
options.ttl : 60 * 30] | ||
], callback); | ||
@@ -67,2 +70,81 @@ }); | ||
Client.prototype.getMappings = function getMappings(options, callback) { | ||
if (typeof options === 'function') { | ||
callback = options; | ||
options = null; | ||
} | ||
if (!options) options = {}; | ||
this.findGateway(function(err, gateway, address) { | ||
if (err) return callback(err); | ||
var i = 0, | ||
end = false, | ||
results = []; | ||
async.whilst(function() { | ||
return !end; | ||
}, function(callback) { | ||
gateway.run('GetGenericPortMappingEntry', [ | ||
['NewPortMappingIndex', i++] | ||
], function(err, data) { | ||
if (err) { | ||
end = true; | ||
return callback(null); | ||
} | ||
var key; | ||
Object.keys(data).some(function(k) { | ||
if (!/:GetGenericPortMappingEntryResponse/.test(k)) return false; | ||
key = k; | ||
return true; | ||
}); | ||
data = data[key]; | ||
var result = { | ||
public: { | ||
host: typeof data.NewRemoteHost === 'string' && | ||
data.NewRemoteHost || '', | ||
port: parseInt(data.NewExternalPort, 10) | ||
}, | ||
private: { | ||
host: data.NewInternalClient, | ||
port: parseInt(data.NewInternalPort, 10) | ||
}, | ||
protocol: data.NewProtocol.toLowerCase(), | ||
enabled: data.NewEnabled == 1, | ||
description: data.NewPortMappingDescription, | ||
ttl: parseInt(data.NewLeaseDuration, 10) | ||
}; | ||
result.local = result.private.host === address; | ||
results.push(result); | ||
callback(null); | ||
}); | ||
}, function(err) { | ||
if (err) return callback(err); | ||
if (options.local) { | ||
results = results.filter(function(item) { | ||
return item.local; | ||
}); | ||
} | ||
if (options.description) { | ||
results = results.filter(function(item) { | ||
if (options.description instanceof RegExp) { | ||
return item.description.match(options.description) !== null; | ||
} else { | ||
return item.description.indexOf(options.description) !== -1; | ||
} | ||
}); | ||
} | ||
callback(null, results); | ||
}) | ||
}); | ||
}; | ||
Client.prototype.externalIp = function externalIp(callback) { | ||
@@ -88,8 +170,8 @@ this.findGateway(function(err, gateway, address) { | ||
Client.prototype.findGateway = function findGateway(callback) { | ||
var ssdp = nat.ssdp.create(), | ||
p = ssdp.search('urn:schemas-upnp-org:device:InternetGatewayDevice:1'); | ||
var p = this.ssdp.search( | ||
'urn:schemas-upnp-org:device:InternetGatewayDevice:1' | ||
); | ||
p.on('device', function(info, address) { | ||
p.emit('end'); | ||
ssdp.close(); | ||
@@ -100,1 +182,5 @@ // Create gateway | ||
}; | ||
Client.prototype.close = function close() { | ||
this.ssdp.close(); | ||
}; |
{ | ||
"name": "nat-upnp", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"main": "lib/nat-upnp", | ||
@@ -19,4 +19,5 @@ "author": "Fedor Indutny <fedor@indutny.com>", | ||
"xml2js": "~0.1.14", | ||
"request": "~2.10.0" | ||
"request": "~2.10.0", | ||
"async": "~0.1.22" | ||
} | ||
} |
@@ -24,2 +24,8 @@ # NAT UPnP | ||
client.getMappings(function(err, results) { | ||
}); | ||
client.getMappings({ local: true }, function(err, results) { | ||
}); | ||
client.externalIp(function(err, ip) { | ||
@@ -26,0 +32,0 @@ }); |
var assert = require('assert'), | ||
async = require('async'), | ||
net = require('net'), | ||
@@ -7,2 +8,3 @@ natUpnp = require('..'); | ||
var c; | ||
beforeEach(function() { | ||
@@ -12,2 +14,6 @@ c = natUpnp.createClient(); | ||
afterEach(function() { | ||
c.close(); | ||
}); | ||
it('should add port mapping/unmapping', function(callback) { | ||
@@ -18,3 +24,3 @@ var public = ~~(Math.random() * 65536); | ||
private: ~~(Math.random() * 65536), | ||
ttl: 5 | ||
ttl: 0 | ||
}, function(err) { | ||
@@ -30,2 +36,27 @@ assert.equal(err, null); | ||
it('should find port after mapping', function(callback) { | ||
var public = ~~(Math.random() * 65536); | ||
c.portMapping({ | ||
public: public, | ||
private: ~~(Math.random() * 65536), | ||
description: 'node:nat:upnp:search-test', | ||
ttl: 0 | ||
}, function(err) { | ||
assert.equal(err, null); | ||
c.getMappings({ local: true, description: /search-test/ }, | ||
function(err, list) { | ||
assert.equal(err, null); | ||
assert(list.length > 0); | ||
async.forEach(list, function(item, callback) { | ||
c.portUnmapping(item, function(err) { | ||
assert.equal(err, null); | ||
callback(); | ||
}); | ||
}, callback); | ||
}); | ||
}); | ||
}); | ||
it('should get external ip address', function(callback) { | ||
@@ -32,0 +63,0 @@ c.externalIp(function(err, ip) { |
17968
499
58
3
+ Addedasync@~0.1.22
+ Addedasync@0.1.22(transitive)