fixes a small bug in tests

This commit is contained in:
Zachary Boyd 2018-09-14 21:09:50 -04:00
parent 0b82ad9cb5
commit 3a869f46bf
12 changed files with 187 additions and 323 deletions

View file

@ -1,6 +1,6 @@
# Changelog
## [4.0.2] - 2018-09-13
## [4.0.2] - 2018-09-15
### Added
- Adds API documentation. To generate run `npm run docs` and open under `docs/index.html`
@ -8,6 +8,7 @@
### Changed
- Much of the README has been moved to [the wiki](https://github.com/znetstar/tor-router/wiki)
- Updates granax to 3.1.4 which fixes a bug on MacOS
- The constructor on `ControlServer` now takes an nconf instance as the first argument and a logger as the second
## [4.0.1] - 2018-09-11

135
package-lock.json generated
View file

@ -104,10 +104,13 @@
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
},
"asn1": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
"dev": true
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
"dev": true,
"requires": {
"safer-buffer": "~2.1.0"
}
},
"assert-plus": {
"version": "1.0.0",
@ -146,9 +149,9 @@
"dev": true
},
"aws4": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
"integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==",
"version": "1.8.0",
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
"dev": true
},
"babylon": {
@ -162,9 +165,9 @@
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"bcrypt-pbkdf": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
"dev": true,
"optional": true,
"requires": {
@ -181,15 +184,6 @@
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
},
"boom": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
"integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
"dev": true,
"requires": {
"hoek": "4.x.x"
}
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@ -454,26 +448,6 @@
"which": "^1.2.9"
}
},
"cryptiles": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
"integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
"dev": true,
"requires": {
"boom": "5.x.x"
},
"dependencies": {
"boom": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
"integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
"dev": true,
"requires": {
"hoek": "4.x.x"
}
}
}
},
"css-select": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
@ -625,13 +599,14 @@
}
},
"ecc-jsbn": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
"dev": true,
"optional": true,
"requires": {
"jsbn": "~0.1.0"
"jsbn": "~0.1.0",
"safer-buffer": "^2.1.0"
}
},
"enabled": {
@ -719,9 +694,9 @@
"dev": true
},
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
"dev": true
},
"extsprintf": {
@ -1123,18 +1098,6 @@
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
"dev": true
},
"hawk": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
"integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
"dev": true,
"requires": {
"boom": "4.x.x",
"cryptiles": "3.x.x",
"hoek": "4.x.x",
"sntp": "2.x.x"
}
},
"he": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
@ -1146,12 +1109,6 @@
"resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz",
"integrity": "sha1-CH4fELBGky/IWU3Z5tN4r8nR5aw="
},
"hoek": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz",
"integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==",
"dev": true
},
"hooker": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
@ -1594,18 +1551,18 @@
"integrity": "sha1-dTHjnUlJwoGma4xabgJl6LBYlNo="
},
"mime-db": {
"version": "1.33.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==",
"version": "1.36.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.36.0.tgz",
"integrity": "sha512-L+xvyD9MkoYMXb1jAmzI/lWYAxAMCPvIBSWur0PZ5nOf5euahRLVqH//FKW9mWp2lkqUgYiXPgkzfMUFi4zVDw==",
"dev": true
},
"mime-types": {
"version": "2.1.18",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"version": "2.1.20",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.20.tgz",
"integrity": "sha512-HrkrPaP9vGuWbLK1B1FfgAkbqNjIuy4eHlIYnFi7kamZyLLrGlo2mpcx0bBmNpKqBtYtAfGbodDddIgddSJC2A==",
"dev": true,
"requires": {
"mime-db": "~1.33.0"
"mime-db": "~1.36.0"
}
},
"mimic-fn": {
@ -2101,9 +2058,9 @@
}
},
"request": {
"version": "2.85.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.85.0.tgz",
"integrity": "sha512-8H7Ehijd4js+s6wuVPLjwORxD4zeuyjYugprdOXlPSqaApmL/QOy+EB/beICHVCHkGMKNh5rvihb5ov+IDw4mg==",
"version": "2.87.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
"integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
"dev": true,
"requires": {
"aws-sign2": "~0.7.0",
@ -2114,7 +2071,6 @@
"forever-agent": "~0.6.1",
"form-data": "~2.3.1",
"har-validator": "~5.0.3",
"hawk": "~6.0.2",
"http-signature": "~1.2.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
@ -2124,7 +2080,6 @@
"performance-now": "^2.1.0",
"qs": "~6.5.1",
"safe-buffer": "^5.1.1",
"stringstream": "~0.0.5",
"tough-cookie": "~2.3.3",
"tunnel-agent": "^0.6.0",
"uuid": "^3.1.0"
@ -2268,15 +2223,6 @@
"integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==",
"dev": true
},
"sntp": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
"integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
"dev": true,
"requires": {
"hoek": "4.x.x"
}
},
"socks": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/socks/-/socks-2.2.1.tgz",
@ -2360,9 +2306,9 @@
"dev": true
},
"sshpk": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
"integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
"version": "1.14.2",
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz",
"integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=",
"dev": true,
"requires": {
"asn1": "~0.2.3",
@ -2372,6 +2318,7 @@
"ecc-jsbn": "~0.1.1",
"getpass": "^0.1.1",
"jsbn": "~0.1.0",
"safer-buffer": "^2.0.2",
"tweetnacl": "~0.14.0"
}
},
@ -2403,12 +2350,6 @@
"safe-buffer": "~5.1.0"
}
},
"stringstream": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
"integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
"dev": true
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -2551,9 +2492,9 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"uuid": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
"integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==",
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
"dev": true
},
"validate-npm-package-license": {

View file

@ -21,7 +21,7 @@
"grunt": "^1.0.3",
"grunt-jsdoc": "^2.3.0",
"mocha": "^5.2.0",
"request": "^2.79.0",
"request": "^2.87.0",
"request-promise": "^4.2.2",
"requestretry": "^2.0.2",
"socks-proxy-agent": "^4.0.1"

View file

@ -55,31 +55,13 @@ class ControlServer {
*/
let server = this.server = new rpc.Server();
/**
* @borrows ControlServer#createTorPool as ControlServer~createTorPool
* @function ControlServer~createTorPool
*/
server.expose('createTorPool', this.createTorPool.bind(this));
/**
* @borrows ControlServer#createSOCKSServer as ControlServer~createSOCKSServer
* @function ControlServer~createSOCKSServer
*/
server.expose('createSOCKSServer', this.createSOCKSServer.bind(this));
/**
* @borrows ControlServer#createDNSServer as ControlServer~createDNSServer
* @function ControlServer~createDNSServer
*/
server.expose('createDNSServer', this.createDNSServer.bind(this));
/**
* @borrows ControlServer#createHTTPServer as ControlServer~createHTTPServer
* @function ControlServer~createHTTPServer
*/
server.expose('createHTTPServer', this.createHTTPServer.bind(this));
/**
* Returns a list of all instances currently in the pool.
* @function ControlServer~queryInstances
* @returns {ControlServer~InstanceInfo[]}
*/
server.expose('queryInstances', (() => {
return this.tor_pool.instances.map(ControlServer.instance_info);
@ -87,9 +69,6 @@ class ControlServer {
/**
* Returns information on an instance identified by the {@link TorProcess#instance_name} field.
* @function ControlServer~queryInstanceByName
* @param {string} instance_name - Name of the instance.
* @returns {ControlServer~InstanceInfo}
*/
server.expose('queryInstanceByName', ((instance_name) => {
let instance = this.tor_pool.instance_by_name(instance_name);
@ -102,9 +81,6 @@ class ControlServer {
/**
* Returns information on an instance identified by its index in the pool.
* @function ControlServer~queryInstanceAt
* @param {number} instance_index - Index of the instance in the pool.
* @returns {ControlServer~InstanceInfo}
*/
server.expose('queryInstanceAt', ((index) => {
if (!this.tor_pool)
@ -120,33 +96,22 @@ class ControlServer {
/**
* Returns a list of the names of all of the instances in the pool.
* @function ControlServer~queryInstanceNames
* @returns {string[]}
*/
server.expose('queryInstanceNames', (() => this.tor_pool.instance_names).bind(this));
/**
* Returns a list of the names of all of the current groups.
* @function ControlServer~queryGroupNames
* @returns {string[]}
*/
server.expose('queryGroupNames', (() => Array.from(this.tor_pool.group_names)).bind(this));
/**
* Returns a list of the instances that exist in a given group.
* @function ControlServer~queryGroupNames
* @param {string} group - Group the search in.
* @returns {InstanceInfo[]}
*/
server.expose('queryInstancesByGroup', ((group) => this.tor_pool.instances_by_group(group).map(ControlServer.instance_info)).bind(this));
/**
* Creates instances from a number, an array of instance definitions or a single instance definition.
* If a number is provided, creates n many instances.
* @function ControlServer~createInstances
* @param {InstanceDefinition[]|InstanceDefinition|number} instances_to_create - Array of definitions, single definition, or number of instances,
* @async
* @returns {Promise<InstanceInfo[]>} - The instances that were created
*/
server.expose('createInstances', (async (instances_to_create) => {
let instances = await this.tor_pool.create(instances_to_create);
@ -156,10 +121,6 @@ class ControlServer {
/**
* Creates instances from an array of instance definitions or a single instance definition.
* @function ControlServer~addInstances
* @param {InstanceDefinition[]|InstanceDefinition} instances_to_create - Array of definitions or single definition.
* @async
* @returns {Promise<InstanceInfo[]>} - The instances that were created
*/
server.expose('addInstances', (async (defs) => {
let instances = await this.tor_pool.add(defs);
@ -169,65 +130,46 @@ class ControlServer {
/**
* Removes a number of instances from the pool.
* @function ControlServer~removeInstances
* @borrows TorPool#remove as ControlServer~removeInstances
*/
server.expose('removeInstances', this.tor_pool.remove.bind(this.tor_pool));
/**
* Remove an instance at the index provided from the pool.
* @function ControlServer~removeInstanceAt
* @borrows remove_at#remove as ControlServer~removeInstanceAt
*/
server.expose('removeInstanceAt', this.tor_pool.remove_at.bind(this.tor_pool));
/**
* Remove an instance from the pool by the {@link TorProcess#instance_name} field.
* @function ControlServer~removeInstanceByName
* @borrows TorPool#remove_by_name as ControlServer~removeInstanceByName
*/
server.expose('removeInstanceByName', this.tor_pool.remove_by_name.bind(this.tor_pool));
/**
* Gets new identities for all instances in the pool.
* @function ControlServer~newIdentites
* @borrows TorPool#new_identites as ControlServer~newIdentites
*/
server.expose('newIdentites', this.tor_pool.new_identites.bind(this.tor_pool));
/**
* Get a new identity for the instance at the index provided in the pool.
* @function ControlServer~newIdentityAt
* @borrows TorPool#new_identity_at as ControlServer~newIdentityAt
*/
server.expose('newIdentityAt', this.tor_pool.new_identity_at.bind(this.tor_pool));
/**
* Get a new identity for the instance by the {@link TorProcess#instance_name} field.
* @function ControlServer~newIdentityByName
* @borrows TorPool#new_identity_by_name as ControlServer~newIdentityByName
*/
server.expose('newIdentityByName', this.tor_pool.new_identity_by_name.bind(this.tor_pool));
/**
* Gets new identities for all instances in the group.
* @function ControlServer~newIdentitiesByGroup
* @borrows TorPool#new_identites_by_group as ControlServer~newIdentitiesByGroup
*/
server.expose('newIdentitiesByGroup', this.tor_pool.new_identites_by_group.bind(this.tor_pool));
/**
* Gets the next instance in the pool using the load balance method.
* @function ControlServer~nextInstance
* @returns {InstanceInfo} - The next instance in the pool.
*/
server.expose('nextInstance', (() => ControlServer.instance_info(this.tor_pool.next())).bind(this));
/**
* Gets the next instance in the group using the load balance method.
* @function ControlServer~nextInstanceByGroup
* @param {string} group - The group in question.
* @returns {InstanceInfo} - The next instance in the group.
*/
server.expose('nextInstanceByGroup', ((group) => {
return ControlServer.instance_info(this.tor_pool.next_by_group(group));
@ -235,16 +177,11 @@ class ControlServer {
/**
* Kills the processes of all instances in the pool.
* @function ControlServer~closeInstances
* @borrows TorPool#exit as ControlServer~closeInstances
*/
server.expose('closeInstances', this.tor_pool.exit.bind(this.tor_pool));
/**
* Sets a property in the application configuration.
* @function ControlServer~setConfig
* @param {string} key - Name of the property to set.
* @param {string} value - Value to set the property to.
*/
server.expose('setConfig', ((key, value) => {
this.nconf.set(key, value);
@ -252,9 +189,6 @@ class ControlServer {
/**
* Gets a property in the application configuration.
* @function ControlServer~getConfig
* @param {string} key - Name of the property to set.
* @returns {*} - Value of the property
*/
server.expose('getConfig', ((key) => {
return this.nconf.get(key);
@ -262,10 +196,6 @@ class ControlServer {
/**
* Saves the application configuration to the underlying store (usually a JSON file).
* @function ControlServer~saveConfig
* @async
* @throws If the save operation fails.
* @returns {Promise}
*/
server.expose('saveConfig', (async () => {
await new Promise((resolve, reject) => {
@ -278,10 +208,6 @@ class ControlServer {
/**
* Loads the application configuration from the underlying store (usually a JSON file).
* @function ControlServer~loadConfig
* @async
* @throws If the load operation fails.
* @returns {Promise}
*/
server.expose('loadConfig', (async () => {
await new Promise((resolve, reject) => {
@ -294,10 +220,6 @@ class ControlServer {
/**
* Sets a configuration property on all instances in the pool.
* @function ControlServer~setTorConfig
* @async
* @param {Object} config - An object containing properties to be set.
* @returns {Promise}
*/
server.expose('setTorConfig', (async (config) => {
await Promise.all(Object.keys(config).map((key) => {
@ -309,11 +231,6 @@ class ControlServer {
/**
* Sets a configuration property on all instances in a group.
* @function ControlServer~setTorConfigByGroup
* @async
* @param {string} group - Group to set properties on.
* @param {Object} config - An object containing properties to be set.
* @returns {Promise}
*/
server.expose('setTorConfigByGroup', (async (group, config) => {
await Promise.all(Object.keys(config).map((key) => {
@ -325,8 +242,6 @@ class ControlServer {
/**
* Retrieves the current load balance method for the pool
* @function ControlServer~getLoadBalanceMethod
* @returns {string} - The load balance method
*/
server.expose('getLoadBalanceMethod', (() => {
return this.tor_pool.load_balance_method;
@ -334,8 +249,6 @@ class ControlServer {
/**
* Sets the current load balance method for the pool
* @function ControlServer~getLoadBalanceMethod
* @param {string} load_balance_method - The load balance method to set
*/
server.expose('setLoadBalanceMethod', ((loadBalanceMethod) => {
this.tor_pool.load_balance_method = loadBalanceMethod;
@ -344,85 +257,61 @@ class ControlServer {
/**
* Retrieve a configuration property for an instance identified by the {@link TorProcess#instance_name} field.
* @function ControlServer~getInstanceConfigByName
* @borrows TorPool#getInstanceConfigByName as ControlServer~get_config_by_name
*/
server.expose('getInstanceConfigByName', this.tor_pool.get_config_by_name.bind(this.tor_pool));
/**
* Retrieves a configuration property for an instance by its index in the pool.
* @function ControlServer~get_config_at
* @borrows TorPool#get_config_at as ControlServer~get_config_at
*/
server.expose('getInstanceConfigAt', this.tor_pool.get_config_at.bind(this.tor_pool));
/**
* Sets a configuration property for an instance identified by the {@link TorProcess#instance_name} field.
* @function ControlServer~setInstanceConfigByName
* @borrows TorPool#set_config_by_name as ControlServer~setInstanceConfigByName
*/
server.expose('setInstanceConfigByName', this.tor_pool.set_config_by_name.bind(this.tor_pool));
/**
* Sets a configuration property for an instance identified by its index in the pool.
* @function ControlServer~setInstanceConfigAt
* @borrows TorPool#set_config_at as ControlServer~setInstanceConfigAt
*/
server.expose('setInstanceConfigAt', this.tor_pool.set_config_at.bind(this.tor_pool));
/**
* Sends a signal to all instances in the pool
* @function ControlServer~signalAllInstances
* @borrows TorPool#signal_all as ControlServer~signalAllInstances
*/
server.expose('signalAllInstances', this.tor_pool.signal_all.bind(this.tor_pool));
/**
* Sends a signal to an instance identified by its index in the pool.
* @function ControlServer~signalInstanceAt
* @borrows TorPool#signal_at as ControlServer~signalInstanceAt
*/
server.expose('signalInstanceAt', this.tor_pool.signal_at.bind(this.tor_pool));
/**
* Sends a signal to an instance identified by the {@link TorProcess#instance_name} field.
* @function ControlServer~signalInstanceByName
* @borrows TorPool#signal_by_name as ControlServer~signalInstanceByName
*/
server.expose('signalInstanceByName', this.tor_pool.signal_by_name.bind(this.tor_pool));
/**
* Sends a singal to all instances in a group.
* @function ControlServer~signalInstancesByGroup
* @borrows TorPool#signal_by_group as ControlServer~signalInstancesByGroup
*/
server.expose('signalInstancesByGroup', this.tor_pool.signal_by_group.bind(this.tor_pool));
/**
* Adds an instance to a group identified by its {@link TorProcess#instance_name} field.
* @function ControlServer~addInstanceToGroupByName
* @borrows TorPool#add_instance_to_group_by_name as ControlServer~addInstanceToGroupByName
*/
server.expose('addInstanceToGroupByName', this.tor_pool.add_instance_to_group_by_name.bind(this.tor_pool));
/**
* Adds an instance to a group identified by its index in the pool.
* @function ControlServer~addInstanceToGroupAt
* @borrows TorPool#add_instance_to_group_at as ControlServer~addInstanceToGroupAt
*/
server.expose('addInstanceToGroupAt', this.tor_pool.add_instance_to_group_at.bind(this.tor_pool));
/**
* Removes an instance from a group identified by its {@link TorProcess#instance_name} field.
* @function ControlServer~removeInstanceFromGroupByName
* @borrows TorPool#remove_instance_from_group_by_name as ControlServer~removeInstanceFromGroupByName
*/
server.expose('removeInstanceFromGroupByName', this.tor_pool.remove_instance_from_group_by_name.bind(this.tor_pool));
/**
* Remove an instance from a group identified by its index in the pool.
* @function ControlServer~removeInstanceFromGroupAt
* @borrows TorPool#remove_instance_from_group_at as ControlServer~removeInstanceFromGroupAt
*/
server.expose('removeInstanceFromGroupAt', this.tor_pool.remove_instance_from_group_at .bind(this.tor_pool));
}

View file

@ -637,7 +637,7 @@ class TorPool extends EventEmitter {
* @async
* @param {string} name - Name of the instance.
* @param {string} keyword - Name of the configuration property.
* @param {*} value - Value to set the configuration property to.
* @param {any} value - Value to set the configuration property to.
*
* @returns {Promise}
* @throws When no instance matched the provided name.
@ -674,7 +674,7 @@ class TorPool extends EventEmitter {
* @async
* @param {number} index - Index of the instance in the pool.
* @param {string} keyword - Name of the configuration property.
* @param {*} value - Value to set the configuration property to.
* @param {any} value - Value to set the configuration property to.
*
* @returns {Promise}
* @throws When no instance exists at the provided index.
@ -692,7 +692,7 @@ class TorPool extends EventEmitter {
* @async
* @param {string} group - Name of the group.
* @param {string} keyword - Name of the configuration property.
* @param {*} value - Value to set the configuration property to.
* @param {any} value - Value to set the configuration property to.
*
* @returns {Promise}
* @throws When the provided group does not exist.
@ -706,7 +706,7 @@ class TorPool extends EventEmitter {
*
* @async
* @param {string} keyword - Name of the configuration property.
* @param {*} value - Value to set the configuration property to.
* @param {any} value - Value to set the configuration property to.
*
* @returns {Promise}
*/

View file

@ -226,7 +226,7 @@ class TorProcess extends EventEmitter {
* @async
* @throws Will throw an error if not connected to the control protocol.
* @param {string} keyword - The name of the configuration property to retrieve.
* @param {*} value - Value to set the property to.
* @param {any} value - Value to set the property to.
*
* @returns {Promise}
*/

View file

@ -6,13 +6,14 @@ const _ = require('lodash');
const Promise = require('bluebird');
const { TorPool, HTTPServer, TorProcess } = require('../');
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME, RETRY_DELAY, RETRY_STRATEGY, MAX_ATTEMPTS } = require('./constants');
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME, RETRY_DELAY, RETRY_STRATEGY, MAX_ATTEMPTS, SHUTDOWN_DELAY, SHUTDOWN_TIMEOUT } = require('./constants');
const request = require('requestretry').defaults({
promiseFactory: ((resolver) => new Promise(resolver)),
maxAttempts: MAX_ATTEMPTS,
retryStrategy: RETRY_STRATEGY,
retryDelay: RETRY_DELAY
retryDelay: RETRY_DELAY,
timeout: PAGE_LOAD_TIME
});
nconf.use('memory');
@ -69,17 +70,16 @@ describe('HTTPServer', function () {
})
});
after('shutdown server', function () {
httpServer.close();
after('shutdown server and shutdown tor pool', function (done) {
this.timeout(SHUTDOWN_TIMEOUT);
setTimeout(async () => {
httpServer.close();
await httpServerTorPool.exit();
done();
}, SHUTDOWN_DELAY);
});
after('shutdown tor pool', async function () {
await httpServerTorPool.exit();
});
});
return
describe('#handle_connect_connections(req, inbound_socket, head)', function () {
let httpServerTorPool;
let httpServer;
@ -128,12 +128,13 @@ describe('HTTPServer', function () {
});
});
after('shutdown server', function () {
httpServer.close();
});
after('shutdown tor pool', async function () {
await httpServerTorPool.exit();
after('shutdown server and shutdown tor pool', function (done) {
this.timeout(SHUTDOWN_TIMEOUT);
setTimeout(async () => {
httpServer.close();
await httpServerTorPool.exit();
done();
}, SHUTDOWN_DELAY);
});
});
@ -163,29 +164,27 @@ describe('HTTPServer', function () {
it(`should service a request for example.com through the instance named ${instance_def.Name}`, function (done) {
this.timeout(PAGE_LOAD_TIME);
let req;
let connectionHandler = (instance, source) => {
assert.equal(instance.instance_name, instance_def.Name);
assert.isTrue(source.by_name);
req.cancel();
httpServer.removeAllListeners('instance_connection');;
done();
};
httpServer.on('instance_connection', connectionHandler);
req = request({
request({
url: 'http://example.com',
proxy: `http://${instance_def.Name}:@127.0.0.1:${httpPort}`
proxy: `http://${instance_def.Name}:@127.0.0.1:${httpPort}`,
timeout: PAGE_LOAD_TIME
})
.catch(done)
});
it(`four requests made to example.com through the group named "foo" should come from the instances in "foo"`, function (done) {
(async () => {
this.timeout(PAGE_LOAD_TIME + (WAIT_FOR_CREATE));
this.timeout((PAGE_LOAD_TIME * 4) + (WAIT_FOR_CREATE));
await httpServerTorPool.add([
{
@ -266,12 +265,13 @@ describe('HTTPServer', function () {
}
});
after('shutdown server', function () {
httpServer.close();
});
after('shutdown tor pool', async function () {
await httpServerTorPool.exit();
after('shutdown server and shutdown tor pool', function (done) {
this.timeout(SHUTDOWN_TIMEOUT);
setTimeout(async () => {
httpServer.close();
await httpServerTorPool.exit();
done();
}, SHUTDOWN_DELAY);
});
});
@ -314,14 +314,14 @@ describe('HTTPServer', function () {
req = request({
url: 'https://example.com',
proxy: `http://${instance_def.Name}:@127.0.0.1:${httpPort}`,
proxy: `http://${instance_def.Name}:@127.0.0.1:${httpPort}`
})
.catch(done);
});
it(`four requests made to example.com through the group named "foo" should come from instances in the "foo" group`, function (done) {
(async () => {
this.timeout(PAGE_LOAD_TIME + (WAIT_FOR_CREATE));
this.timeout((PAGE_LOAD_TIME * 4) + (WAIT_FOR_CREATE));
await httpServerTorPool.add([
{
@ -333,8 +333,6 @@ describe('HTTPServer', function () {
httpServer.proxy_by_name.mode = "group";
})()
.then(async () => {
let request = require('request-promise').defaults({ proxy: `http://foo:@127.0.0.1:${httpPort}` });
let names_requested = [];
let connectionHandler = (instance, source) => {
@ -356,7 +354,8 @@ describe('HTTPServer', function () {
let i = 0;
while (i < httpServerTorPool.instances.length) {
await request({
url: 'https://example.com'
url: 'https://example.com',
proxy: `http://foo:@127.0.0.1:${httpPort}`
});
i++;
}
@ -368,10 +367,12 @@ describe('HTTPServer', function () {
.catch(done);
});
const regular_request = require('request-promise');
it(`shouldn't be able to send a request without a username`, async function() {
let f = () => {};
try {
await request({
await regular_request({
url: 'https://example.com',
proxy: `http://127.0.0.1:${httpPort}`,
timeout: PAGE_LOAD_TIME
@ -386,10 +387,11 @@ describe('HTTPServer', function () {
it(`shouldn't be able to send a request with an incorrect username`, async function() {
let f = () => {};
try {
await request({
await regular_request({
url: 'https://example.com',
proxy: `http://blah-blah-blah:@127.0.0.1:${httpPort}`,
timeout: PAGE_LOAD_TIME
timeout: PAGE_LOAD_TIME,
retryStrategy: request.RetryStrategies.NetworkError
});
} catch (error) {
f = () => { throw error };
@ -398,12 +400,13 @@ describe('HTTPServer', function () {
}
});
after('shutdown server', function () {
httpServer.close();
});
after('shutdown tor pool', async function () {
await httpServerTorPool.exit();
after('shutdown server and shutdown tor pool', function (done) {
this.timeout(SHUTDOWN_TIMEOUT);
setTimeout(async () => {
httpServer.close();
await httpServerTorPool.exit();
done();
}, SHUTDOWN_DELAY);
});
});
});

View file

@ -3,17 +3,18 @@ const nconf = new Provider();
const getPort = require('get-port');
const { HttpAgent, auth } = require('socksv5');
const { assert } = require('chai');
const SocksProxyAgent = require('socks-proxy-agent');
const _ = require('lodash');
const SocksProxyAgent = require('socks-proxy-agent');
const { TorPool, SOCKSServer, TorProcess } = require('../');
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME, RETRY_DELAY, RETRY_STRATEGY, MAX_ATTEMPTS } = require('./constants');
const { WAIT_FOR_CREATE, PAGE_LOAD_TIME, RETRY_DELAY, RETRY_STRATEGY, MAX_ATTEMPTS, SHUTDOWN_DELAY, SHUTDOWN_TIMEOUT } = require('./constants');
const request = require('requestretry').defaults({
promiseFactory: ((resolver) => new Promise(resolver)),
maxAttempts: MAX_ATTEMPTS,
retryStrategy: RETRY_STRATEGY,
retryDelay: RETRY_DELAY
retryDelay: RETRY_DELAY,
timeout: PAGE_LOAD_TIME
});
nconf.use('memory');
@ -43,7 +44,12 @@ describe('SOCKSServer', function () {
await request({
url: 'http://example.com',
agent: new SocksProxyAgent(`socks5h://127.0.0.1:${socksPort}`)
agent: new HttpAgent({
proxyHost: '127.0.0.1',
proxyPort: socksPort,
localDNS: false,
auths: [ auth.None() ]
})
});
});
@ -62,17 +68,26 @@ describe('SOCKSServer', function () {
request({
url: 'http://example.com',
agent: new SocksProxyAgent(`socks5h://127.0.0.1:${socksPort}`)
agent: new HttpAgent({
proxyHost: '127.0.0.1',
proxyPort: socksPort,
localDNS: false,
auths: [ auth.None() ]
})
})
.catch(done)
});
after('shutdown server and shutdown tor pool', async function () {
socksServer.close();
await socksServerTorPool.exit();
after('shutdown server and shutdown tor pool', function (done) {
this.timeout(SHUTDOWN_TIMEOUT);
setTimeout(async () => {
socksServer.close();
await socksServerTorPool.exit();
done();
}, SHUTDOWN_DELAY);
});
});
describe('#authenticate_user(username, password)', function () {
let socksPort;
let socksServerTorPool;
@ -107,18 +122,22 @@ describe('SOCKSServer', function () {
};
socksServer.on('instance_connection', connectionHandler);
request({
url: 'http://example.com',
agent: new SocksProxyAgent(`socks5h://${instance_def.Name}:doesnotmatter@127.0.0.1:${socksPort}`)
agent: new HttpAgent({
proxyHost: '127.0.0.1',
proxyPort: socksPort,
localDNS: false,
auths: [ auth.UserPassword(instance_def.Name, "doesn't mater") ]
})
})
.catch(done);
});
return
it(`four requests made to example.com through the group named "foo" should come from the instances in "foo"`, function (done) {
(async () => {
this.timeout(PAGE_LOAD_TIME + (WAIT_FOR_CREATE));
this.timeout((PAGE_LOAD_TIME * 4) + (WAIT_FOR_CREATE));
await socksServerTorPool.add([
{
@ -153,7 +172,12 @@ describe('SOCKSServer', function () {
while (i < socksServerTorPool.instances.length) {
await request({
url: 'http://example.com',
agent: new SocksProxyAgent(`socks5h://foo:doesnotmatter@127.0.0.1:${socksPort}`)
agent: new HttpAgent({
proxyHost: '127.0.0.1',
proxyPort: socksPort,
localDNS: false,
auths: [ auth.UserPassword('foo', "doesn't mater") ]
})
});
i++;
}
@ -165,49 +189,45 @@ describe('SOCKSServer', function () {
.catch(done);
});
// it(`shouldn't be able to send a request without a username`, async function() {
// let f = () => {};
// try {
// await request({
// url: 'http://example.com',
// agent: new HttpAgent({
// proxyHost: '127.0.0.1',
// proxyPort: socksPort,
// localDNS: false,
// auths: [ auth.None() ]
// }),
// timeout: PAGE_LOAD_TIME
// });
// } catch (error) {
// f = () => { throw error };
// } finally {
// assert.throws(f);
// }
// });
const regular_request = require('request-promise');
// it(`shouldn't be able to send a request with an incorrect username`, async function() {
// let f = () => {};
// try {
// await request({
// url: 'http://example.com',
// agent: new HttpAgent({
// proxyHost: '127.0.0.1',
// proxyPort: socksPort,
// localDNS: false,
// auths: [ auth.UserPassword("foo", "bar") ]
// }),
// timeout: PAGE_LOAD_TIME
// });
// } catch (error) {
// f = () => { throw error };
// } finally {
// assert.throws(f);
// }
// });
it(`shouldn't be able to send a request without a username`, async function() {
let f = () => {};
try {
await regular_request({
url: 'http://example.com',
agent: new SocksProxyAgent(`socks5h://127.0.0.1:${socksPort}`),
timeout: PAGE_LOAD_TIME
});
} catch (error) {
f = () => { throw error };
} finally {
assert.throws(f);
}
});
after('shutdown server and shutdown tor pool', async function () {
socksServer.close();
await socksServerTorPool.exit();
it(`shouldn't be able to send a request with an incorrect username`, async function() {
let f = () => {};
try {
await regular_request({
url: 'http://example.com',
agent: new SocksProxyAgent(`socks5h://blah-blah-blah:@127.0.0.1:${socksPort}`),
timeout: PAGE_LOAD_TIME
});
} catch (error) {
f = () => { throw error };
} finally {
assert.throws(f);
}
});
after('shutdown server and shutdown tor pool', function (done) {
this.timeout(SHUTDOWN_TIMEOUT);
setTimeout(async () => {
socksServer.close();
await socksServerTorPool.exit();
done();
}, SHUTDOWN_DELAY);
});
});

View file

@ -41,6 +41,7 @@ describe('TorPool', function () {
});
describe('#create_instance(instance_defintion)', function () {
let instance_defintion = {
Name: 'instance-1',
Config: {
@ -70,6 +71,7 @@ describe('TorPool', function () {
});
it('should not be able to create an instance with an existing name', async function () {
this.timeout(WAIT_FOR_CREATE * 2);
let fn = () => {}
try {

View file

@ -75,35 +75,40 @@ describe('TorProcess', function () {
});
it('should create the child process', async function () {
this.timeout(WAIT_FOR_CREATE);
this.timeout(5000);
await tor.create();
});
it('should signal when it is listening on the control port', function (done) {
this.timeout(5000);
if (tor.control_port_listening)
return done();
tor.once('control_listen', done);
});
it('should signal when connected to the control port', function (done) {
this.timeout(5000);
if (tor.control_port_connected)
return done();
tor.once('controller_ready', done);
});
it('should signal when it is listening on the socks port', function (done) {
this.timeout(5000);
if (tor.socks_port_listening)
return done();
tor.once('socks_listen', done);
});
it('should signal when it is listening on the dns port', function (done) {
this.timeout(5000);
if (tor.dns_port_listening)
return done();
tor.once('dns_listen', done);
});
it('should signal when bootstrapped', function (done) {
this.timeout(WAIT_FOR_CREATE);
tor.once('error', done);
if (tor.bootstrapped)
return done();
@ -111,6 +116,7 @@ describe('TorProcess', function () {
});
after('exit tor', async function () {
this.timeout(5000);
await tor.exit();
});
});

View file

@ -1,7 +1,9 @@
module.exports = {
WAIT_FOR_CREATE: 600000,
PAGE_LOAD_TIME: 60000,
RETRY_DELAY: 500,
MAX_ATTEMPTS: 10,
RETRY_STRATEGY: require('requestretry').RetryStrategies.HTTPOrNetworkError
PAGE_LOAD_TIME: 75000,
RETRY_DELAY: 5000,
MAX_ATTEMPTS: 15,
RETRY_STRATEGY: require('requestretry').RetryStrategies.HTTPOrNetworkError,
SHUTDOWN_DELAY: 5000,
SHUTDOWN_TIMEOUT: (this.SHUTDOWN_DELAY * 2)
};

View file

@ -1,9 +1,9 @@
describe("TorRouter", function () {
// require('./TorProcess');
// require('./TorPool');
require('./TorProcess');
require('./TorPool');
require('./SOCKSServer');
require('./HTTPServer');
// require('./DNSServer');
// require('./ControlServer');
// require('./RPCInterface');
require('./DNSServer');
require('./ControlServer');
require('./RPCInterface');
});