From 717772ac2d7168cbdd5c93d1492cf452537ff40c Mon Sep 17 00:00:00 2001 From: robertdurst Date: Thu, 24 May 2018 11:17:52 -0700 Subject: [PATCH 1/6] Add federation timeout --- src/stellar_toml_resolver.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/stellar_toml_resolver.js b/src/stellar_toml_resolver.js index 917ea6d27..aa6ce2346 100644 --- a/src/stellar_toml_resolver.js +++ b/src/stellar_toml_resolver.js @@ -26,19 +26,27 @@ export class StellarTomlResolver { * @param {string} domain Domain to get stellar.toml file for * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! + * @param {number} [opts.timeout] - Allow a timeout, default: 0. Allows user to avoid nasty lag due to TOML resolve issue. * @returns {Promise} */ static resolve(domain, opts = {}) { let allowHttp = Config.isAllowHttp(); + let timeout = 0; + if (typeof opts.allowHttp !== 'undefined') { allowHttp = opts.allowHttp; } + if (typeof opts.timeout === 'number') { + timeout = opts.timeout; + } + let protocol = 'https'; if (allowHttp) { protocol = 'http'; } - return axios.get(`${protocol}://${domain}/.well-known/stellar.toml`, {maxContentLength: STELLAR_TOML_MAX_SIZE}) + + return axios.get(`${protocol}://${domain}/.well-known/stellar.toml`, {maxContentLength: STELLAR_TOML_MAX_SIZE, timeout}) .then(response => { try { let tomlObject = toml.parse(response.data); From 96acbe29e152d2cae1f53d9e61fec6990ef6091e Mon Sep 17 00:00:00 2001 From: robertdurst Date: Sun, 27 May 2018 05:53:10 -0700 Subject: [PATCH 2/6] Added timeout to global config and added two timeout tests to StellarTomlResolver tests --- src/config.js | 23 ++++++++++++++++++++- src/stellar_toml_resolver.js | 2 +- test/unit/stellar_toml_resolver_test.js | 27 +++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/config.js b/src/config.js index b0a0947a4..e7908a8a3 100644 --- a/src/config.js +++ b/src/config.js @@ -1,7 +1,8 @@ import clone from 'lodash/clone'; let defaultConfig = { - allowHttp: false + allowHttp: false, + timeout: 0 }; let config = clone(defaultConfig); @@ -13,11 +14,13 @@ let config = clone(defaultConfig); * ``` * import {Config} from 'stellar-sdk'; * Config.setAllowHttp(true); + * Config.setTimout(5000); * ``` * * Usage browser: * ``` * StellarSdk.Config.setAllowHttp(true); + * StellarSdk.Config.setTimout(5000); * ``` * @static */ @@ -32,6 +35,16 @@ class Config { config.allowHttp = value; } + /** + * Sets `timeout` flag globally. When set to anything besides 0, StellarTOMLResolver will timeout after specified time (ms). + * Default: 0. + * @param {number} value + * @static + */ + static setTimeout(value) { + config.timeout = value; + } + /** * Returns the value of `allowHttp` flag. * @static @@ -40,6 +53,14 @@ class Config { return clone(config.allowHttp); } + /** + * Returns the value of `timeout` flag. + * @static + */ + static hasTimeout() { + return clone(config.timeout); + } + /** * Sets all global config flags to default values. * @static diff --git a/src/stellar_toml_resolver.js b/src/stellar_toml_resolver.js index aa6ce2346..9653f56c6 100644 --- a/src/stellar_toml_resolver.js +++ b/src/stellar_toml_resolver.js @@ -31,7 +31,7 @@ export class StellarTomlResolver { */ static resolve(domain, opts = {}) { let allowHttp = Config.isAllowHttp(); - let timeout = 0; + let timeout = Config.hasTimeout(); if (typeof opts.allowHttp !== 'undefined') { allowHttp = opts.allowHttp; diff --git a/test/unit/stellar_toml_resolver_test.js b/test/unit/stellar_toml_resolver_test.js index 88e97048a..57c2cc7f6 100644 --- a/test/unit/stellar_toml_resolver_test.js +++ b/test/unit/stellar_toml_resolver_test.js @@ -106,5 +106,32 @@ FEDERATION_SERVER="https://api.stellar.org/federation" .then(() => tempServer.close()); }); }); + + it("rejects after given timeout when global Config.timeout flag is set", function (done) { + StellarSdk.Config.setTimeout(1000); + + StellarSdk.StellarTomlResolver.resolve('acme.com') + .should.be.rejectedWith(/timeout of 1000ms exceeded/) + .notify(done); + }); + + it("rejects after given timeout when timeout specified in StellarTomlResolver opts param", function (done) { + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + setTimeout(() => { + res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); + res.end(response); + }, 10000); + }).listen(4444, () => { + StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true, timeout: 1000}) + .should.be.rejectedWith(/timeout of 1000ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); }); }); From 6aa24d631858a470ced84ee7fb328fce4d1c9ca6 Mon Sep 17 00:00:00 2001 From: robertdurst Date: Mon, 28 May 2018 16:01:51 -0700 Subject: [PATCH 3/6] Added timeout opts to federation, added test to federation and cleaned up a few things --- src/config.js | 2 +- src/federation_server.js | 4 +++- src/stellar_toml_resolver.js | 2 +- test/unit/federation_server_test.js | 19 +++++++++++++++++++ test/unit/stellar_toml_resolver_test.js | 18 +++++++++++++++--- 5 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/config.js b/src/config.js index e7908a8a3..c339b30fd 100644 --- a/src/config.js +++ b/src/config.js @@ -57,7 +57,7 @@ class Config { * Returns the value of `timeout` flag. * @static */ - static hasTimeout() { + static getTimeout() { return clone(config.timeout); } diff --git a/src/federation_server.js b/src/federation_server.js index 386439899..903f49958 100644 --- a/src/federation_server.js +++ b/src/federation_server.js @@ -71,6 +71,7 @@ export class FederationServer { * @param {string} value Stellar Address (ex. `bob*stellar.org`) * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! + * @param {number} [opts.timeout] - Allow a timeout, default: 0. Allows user to avoid nasty lag due to TOML resolve issue. * @returns {Promise} */ static resolve(value, opts = {}) { @@ -109,10 +110,11 @@ export class FederationServer { * @param {string} domain Domain to get federation server for * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! + * @param {number} [opts.timeout] - Allow a timeout, default: 0. Allows user to avoid nasty lag due to TOML resolve issue. * @returns {Promise} */ static createForDomain(domain, opts = {}) { - return StellarTomlResolver.resolve(domain) + return StellarTomlResolver.resolve(domain, opts) .then(tomlObject => { if (!tomlObject.FEDERATION_SERVER) { return Promise.reject(new Error('stellar.toml does not contain FEDERATION_SERVER field')); diff --git a/src/stellar_toml_resolver.js b/src/stellar_toml_resolver.js index 9653f56c6..a49b7adff 100644 --- a/src/stellar_toml_resolver.js +++ b/src/stellar_toml_resolver.js @@ -31,7 +31,7 @@ export class StellarTomlResolver { */ static resolve(domain, opts = {}) { let allowHttp = Config.isAllowHttp(); - let timeout = Config.hasTimeout(); + let timeout = Config.getTimeout(); if (typeof opts.allowHttp !== 'undefined') { allowHttp = opts.allowHttp; diff --git a/test/unit/federation_server_test.js b/test/unit/federation_server_test.js index f3d8f4583..5669e1c30 100644 --- a/test/unit/federation_server_test.js +++ b/test/unit/federation_server_test.js @@ -145,6 +145,25 @@ FEDERATION_SERVER="https://api.stellar.org/federation" StellarSdk.FederationServer.createForDomain('acme.com').should.be.rejectedWith(/stellar.toml does not contain FEDERATION_SERVER field/).and.notify(done); }); + + it("rejects after given timeout when timeout specified in opts param", function (done) { + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + setTimeout(() => { + res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); + res.end(response); + }, 10000); + }).listen(4444, () => { + StellarSdk.FederationServer.createForDomain("localhost:4444", {allowHttp: true, timeout: 1000}) + .should.be.rejectedWith(/timeout of 1000ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); }); describe('FederationServer.resolve', function () { diff --git a/test/unit/stellar_toml_resolver_test.js b/test/unit/stellar_toml_resolver_test.js index 57c2cc7f6..ca9b466d0 100644 --- a/test/unit/stellar_toml_resolver_test.js +++ b/test/unit/stellar_toml_resolver_test.js @@ -110,9 +110,21 @@ FEDERATION_SERVER="https://api.stellar.org/federation" it("rejects after given timeout when global Config.timeout flag is set", function (done) { StellarSdk.Config.setTimeout(1000); - StellarSdk.StellarTomlResolver.resolve('acme.com') - .should.be.rejectedWith(/timeout of 1000ms exceeded/) - .notify(done); + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + setTimeout(() => { + res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); + res.end(response); + }, 10000); + }).listen(4444, () => { + StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true}) + .should.be.rejectedWith(/timeout of 1000ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); }); it("rejects after given timeout when timeout specified in StellarTomlResolver opts param", function (done) { From bb82eed2ddc1148d6d31a665fdc558412cd06a04 Mon Sep 17 00:00:00 2001 From: robertdurst Date: Wed, 30 May 2018 14:51:01 -0700 Subject: [PATCH 4/6] Add timeout opt to Server, add opts to federation_server methods, and add timeout to call_builder --- src/call_builder.js | 12 ++++++++++-- src/federation_server.js | 38 +++++++++++++++++++++++++++++--------- src/server.js | 1 + 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/call_builder.js b/src/call_builder.js index aaead637c..b7c160d25 100644 --- a/src/call_builder.js +++ b/src/call_builder.js @@ -13,10 +13,18 @@ let toBluebird = require("bluebird").resolve; * * This is an **abstract** class. Do not create this object directly, use {@link Server} class. * @param {string} serverUrl + * @param {object} [opts] + * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. * @class CallBuilder */ export class CallBuilder { - constructor(serverUrl) { + constructor(serverUrl, opts = {}) { + this.timeout = 0; + + if (typeof opts.timeout === 'number') { + this.timeout = opts.timeout; + } + this.url = serverUrl; this.filter = []; this.originalSegments = this.url.segment() || []; @@ -163,7 +171,7 @@ export class CallBuilder { // Temp fix for: https://github.com/stellar/js-stellar-sdk/issues/15 url.addQuery('c', Math.random()); - var promise = axios.get(url.toString()) + var promise = axios.get(url.toString(), {timeout: this.timeout}) .then(response => response.data) .catch(this._handleNetworkError); return toBluebird(promise); diff --git a/src/federation_server.js b/src/federation_server.js index 903f49958..cd0be530d 100644 --- a/src/federation_server.js +++ b/src/federation_server.js @@ -20,6 +20,7 @@ export const FEDERATION_RESPONSE_MAX_SIZE = 100 * 1024; * @param {string} domain Domain this server represents * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! You can also use {@link Config} class to set this globally. + * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. */ export class FederationServer { constructor(serverURL, domain, opts = {}) { @@ -127,9 +128,11 @@ export class FederationServer { * Returns a Promise that resolves to federation record if the user was found for a given Stellar address. * @see Federation doc * @param {string} address Stellar address (ex. `bob*stellar.org`). If `FederationServer` was instantiated with `domain` param only username (ex. `bob`) can be passed. - * @returns {Promise} + * @param {object} [opts] + * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! + * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. */ - resolveAddress(address) { + resolveAddress(address, opts = {}) { if (address.indexOf('*') < 0) { if (!this.domain) { return Promise.reject(new Error('Unknown domain. Make sure `address` contains a domain (ex. `bob*stellar.org`) or pass `domain` parameter when instantiating the server object.')); @@ -137,33 +140,50 @@ export class FederationServer { address = `${address}*${this.domain}`; } let url = this.serverURL.query({type: 'name', q: address}); - return this._sendRequest(url); + return this._sendRequest(url, opts); } /** * Returns a Promise that resolves to federation record if the user was found for a given account ID. * @see Federation doc * @param {string} accountId Account ID (ex. `GBYNR2QJXLBCBTRN44MRORCMI4YO7FZPFBCNOKTOBCAAFC7KC3LNPRYS`) + * @param {object} [opts] + * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! + * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. * @returns {Promise} */ - resolveAccountId(accountId) { + resolveAccountId(accountId, opts = {}) { let url = this.serverURL.query({type: 'id', q: accountId}); - return this._sendRequest(url); + return this._sendRequest(url, opts); } /** * Returns a Promise that resolves to federation record if the sender of the transaction was found for a given transaction ID. * @see Federation doc * @param {string} transactionId Transaction ID (ex. `3389e9f0f1a65f19736cacf544c2e825313e8447f569233bb8db39aa607c8889`) + * @param {object} [opts] + * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! + * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. * @returns {Promise} */ - resolveTransactionId(transactionId) { + resolveTransactionId(transactionId, opts = {}) { let url = this.serverURL.query({type: 'txid', q: transactionId}); - return this._sendRequest(url); + return this._sendRequest(url, opts); } - _sendRequest(url) { - return axios.get(url.toString(), {maxContentLength: FEDERATION_RESPONSE_MAX_SIZE}) + _sendRequest(url, opts = {}) { + let allowHttp = Config.isAllowHttp(); + let timeout = Config.getTimeout(); + + if (typeof opts.allowHttp !== 'undefined') { + allowHttp = opts.allowHttp; + } + + if (typeof opts.timeout === 'number') { + timeout = opts.timeout; + } + + return axios.get(url.toString(), {maxContentLength: FEDERATION_RESPONSE_MAX_SIZE, timeout}) .then(response => { if (typeof response.data.memo != "undefined" && typeof response.data.memo != 'string') { throw new Error("memo value should be of type string"); diff --git a/src/server.js b/src/server.js index ddc0dc73b..de4d2bc8a 100644 --- a/src/server.js +++ b/src/server.js @@ -32,6 +32,7 @@ export const SUBMIT_TRANSACTION_TIMEOUT = 60*1000; * @param {string} serverURL Horizon Server URL (ex. `https://horizon-testnet.stellar.org`). * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! You can also use {@link Config} class to set this globally. + * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. */ export class Server { constructor(serverURL, opts = {}) { From d8529c89d99a53e8a15a767764ef702689469f95 Mon Sep 17 00:00:00 2001 From: robertdurst Date: Mon, 4 Jun 2018 16:05:30 -0700 Subject: [PATCH 5/6] Add more federation server tests and remove non-stellartomlresolver code --- src/call_builder.js | 12 +-- src/config.js | 2 +- src/federation_server.js | 36 ++----- src/server.js | 1 - test/unit/federation_server_test.js | 127 ++++++++++++++++++++---- test/unit/stellar_toml_resolver_test.js | 8 +- 6 files changed, 125 insertions(+), 61 deletions(-) diff --git a/src/call_builder.js b/src/call_builder.js index b7c160d25..2974e7537 100644 --- a/src/call_builder.js +++ b/src/call_builder.js @@ -1,5 +1,6 @@ import {NotFoundError, NetworkError, BadRequestError} from "./errors"; import forEach from 'lodash/forEach'; +import { Config } from "./config"; let URI = require("urijs"); let URITemplate = require("urijs/src/URITemplate"); @@ -13,17 +14,10 @@ let toBluebird = require("bluebird").resolve; * * This is an **abstract** class. Do not create this object directly, use {@link Server} class. * @param {string} serverUrl - * @param {object} [opts] - * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. * @class CallBuilder */ export class CallBuilder { - constructor(serverUrl, opts = {}) { - this.timeout = 0; - - if (typeof opts.timeout === 'number') { - this.timeout = opts.timeout; - } + constructor(serverUrl) { this.url = serverUrl; this.filter = []; @@ -171,7 +165,7 @@ export class CallBuilder { // Temp fix for: https://github.com/stellar/js-stellar-sdk/issues/15 url.addQuery('c', Math.random()); - var promise = axios.get(url.toString(), {timeout: this.timeout}) + var promise = axios.get(url.toString()) .then(response => response.data) .catch(this._handleNetworkError); return toBluebird(promise); diff --git a/src/config.js b/src/config.js index c339b30fd..9ddcd51cc 100644 --- a/src/config.js +++ b/src/config.js @@ -36,7 +36,7 @@ class Config { } /** - * Sets `timeout` flag globally. When set to anything besides 0, StellarTOMLResolver will timeout after specified time (ms). + * Sets `timeout` flag globally. When set to anything besides 0, the request will timeout after specified time (ms). * Default: 0. * @param {number} value * @static diff --git a/src/federation_server.js b/src/federation_server.js index cd0be530d..7717fcf29 100644 --- a/src/federation_server.js +++ b/src/federation_server.js @@ -20,7 +20,6 @@ export const FEDERATION_RESPONSE_MAX_SIZE = 100 * 1024; * @param {string} domain Domain this server represents * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! You can also use {@link Config} class to set this globally. - * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. */ export class FederationServer { constructor(serverURL, domain, opts = {}) { @@ -128,11 +127,9 @@ export class FederationServer { * Returns a Promise that resolves to federation record if the user was found for a given Stellar address. * @see Federation doc * @param {string} address Stellar address (ex. `bob*stellar.org`). If `FederationServer` was instantiated with `domain` param only username (ex. `bob`) can be passed. - * @param {object} [opts] - * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! - * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. + * @returns {Promise} */ - resolveAddress(address, opts = {}) { + resolveAddress(address) { if (address.indexOf('*') < 0) { if (!this.domain) { return Promise.reject(new Error('Unknown domain. Make sure `address` contains a domain (ex. `bob*stellar.org`) or pass `domain` parameter when instantiating the server object.')); @@ -140,48 +137,33 @@ export class FederationServer { address = `${address}*${this.domain}`; } let url = this.serverURL.query({type: 'name', q: address}); - return this._sendRequest(url, opts); + return this._sendRequest(url); } /** * Returns a Promise that resolves to federation record if the user was found for a given account ID. * @see Federation doc * @param {string} accountId Account ID (ex. `GBYNR2QJXLBCBTRN44MRORCMI4YO7FZPFBCNOKTOBCAAFC7KC3LNPRYS`) - * @param {object} [opts] - * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! - * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. * @returns {Promise} */ - resolveAccountId(accountId, opts = {}) { + resolveAccountId(accountId) { let url = this.serverURL.query({type: 'id', q: accountId}); - return this._sendRequest(url, opts); + return this._sendRequest(url); } /** * Returns a Promise that resolves to federation record if the sender of the transaction was found for a given transaction ID. * @see Federation doc * @param {string} transactionId Transaction ID (ex. `3389e9f0f1a65f19736cacf544c2e825313e8447f569233bb8db39aa607c8889`) - * @param {object} [opts] - * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! - * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. * @returns {Promise} */ - resolveTransactionId(transactionId, opts = {}) { + resolveTransactionId(transactionId) { let url = this.serverURL.query({type: 'txid', q: transactionId}); - return this._sendRequest(url, opts); + return this._sendRequest(url); } - _sendRequest(url, opts = {}) { - let allowHttp = Config.isAllowHttp(); - let timeout = Config.getTimeout(); - - if (typeof opts.allowHttp !== 'undefined') { - allowHttp = opts.allowHttp; - } - - if (typeof opts.timeout === 'number') { - timeout = opts.timeout; - } + _sendRequest(url) { + let timeout = this.timeout | Config.getTimeout(); return axios.get(url.toString(), {maxContentLength: FEDERATION_RESPONSE_MAX_SIZE, timeout}) .then(response => { diff --git a/src/server.js b/src/server.js index de4d2bc8a..ddc0dc73b 100644 --- a/src/server.js +++ b/src/server.js @@ -32,7 +32,6 @@ export const SUBMIT_TRANSACTION_TIMEOUT = 60*1000; * @param {string} serverURL Horizon Server URL (ex. `https://horizon-testnet.stellar.org`). * @param {object} [opts] * @param {boolean} [opts.allowHttp] - Allow connecting to http servers, default: `false`. This must be set to false in production deployments! You can also use {@link Config} class to set this globally. - * @param {number} [opts.timeout] - Allow a timeout, default: 0. In ms. */ export class Server { constructor(serverURL, opts = {}) { diff --git a/test/unit/federation_server_test.js b/test/unit/federation_server_test.js index 5669e1c30..4a2917842 100644 --- a/test/unit/federation_server_test.js +++ b/test/unit/federation_server_test.js @@ -145,25 +145,6 @@ FEDERATION_SERVER="https://api.stellar.org/federation" StellarSdk.FederationServer.createForDomain('acme.com').should.be.rejectedWith(/stellar.toml does not contain FEDERATION_SERVER field/).and.notify(done); }); - - it("rejects after given timeout when timeout specified in opts param", function (done) { - // Unable to create temp server in a browser - if (typeof window != 'undefined') { - return done(); - } - var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); - let tempServer = http.createServer((req, res) => { - setTimeout(() => { - res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); - res.end(response); - }, 10000); - }).listen(4444, () => { - StellarSdk.FederationServer.createForDomain("localhost:4444", {allowHttp: true, timeout: 1000}) - .should.be.rejectedWith(/timeout of 1000ms exceeded/) - .notify(done) - .then(() => tempServer.close()); - }); - }); }); describe('FederationServer.resolve', function () { @@ -246,5 +227,113 @@ FEDERATION_SERVER="https://api.stellar.org/federation" .then(() => tempServer.close()); }); }); + + }); + + describe('FederationServer timeout', function () { + + it("times out when resolveAddress response lags", function (done) { + StellarSdk.Config.setTimeout(100); + + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + res.setHeader('Content-Type', 'application/json; charset=UTF-8'); + setTimeout(() => { + res.end(response); + }, 10000); + }).listen(4444, () => { + new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true}) + .resolveAddress('bob*stellar.org') + .should.be.rejectedWith(/timeout of 100ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); + + it("times out when resolveAccountId response lags", function (done) { + StellarSdk.Config.setTimeout(100); + + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + res.setHeader('Content-Type', 'application/json; charset=UTF-8'); + setTimeout(() => { + res.end(response); + }, 10000); + }).listen(4444, () => { + new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true}) + .resolveAccountId('GB5XVAABEQMY63WTHDQ5RXADGYF345VWMNPTN2GFUDZT57D57ZQTJ7PS') + .should.be.rejectedWith(/timeout of 100ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); + + it("times out when resolveTransactionId response lags", function (done) { + StellarSdk.Config.setTimeout(100); + + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + res.setHeader('Content-Type', 'application/json; charset=UTF-8'); + setTimeout(() => { + res.end(response); + }, 10000); + }).listen(4444, () => { + new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true}) + .resolveTransactionId('3389e9f0f1a65f19736cacf544c2e825313e8447f569233bb8db39aa607c8889') + .should.be.rejectedWith(/timeout of 100ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); + + it("times out when createForDomain response lags", function (done) { + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + setTimeout(() => { + res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); + res.end(response); + }, 1000); + }).listen(4444, () => { + StellarSdk.FederationServer.createForDomain("localhost:4444", {allowHttp: true, timeout: 100}) + .should.be.rejectedWith(/timeout of 100ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); + + it("times out when resolve response lags", function (done) { + // Unable to create temp server in a browser + if (typeof window != 'undefined') { + return done(); + } + var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { + setTimeout(() => { + res.end(response); + }, 10000); + }).listen(4444, () => { + StellarSdk.FederationServer + .resolve('bob*localhost:4444', {allowHttp: true, timeout: 100}) + .should.eventually.be.rejectedWith(/timeout of 100ms exceeded/) + .notify(done) + .then(() => tempServer.close()); + }); + }); }); }); diff --git a/test/unit/stellar_toml_resolver_test.js b/test/unit/stellar_toml_resolver_test.js index ca9b466d0..bb7214b0f 100644 --- a/test/unit/stellar_toml_resolver_test.js +++ b/test/unit/stellar_toml_resolver_test.js @@ -108,7 +108,7 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }); it("rejects after given timeout when global Config.timeout flag is set", function (done) { - StellarSdk.Config.setTimeout(1000); + StellarSdk.Config.setTimeout(100); if (typeof window != 'undefined') { return done(); @@ -121,7 +121,7 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }, 10000); }).listen(4444, () => { StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true}) - .should.be.rejectedWith(/timeout of 1000ms exceeded/) + .should.be.rejectedWith(/timeout of 100ms exceeded/) .notify(done) .then(() => tempServer.close()); }); @@ -139,8 +139,8 @@ FEDERATION_SERVER="https://api.stellar.org/federation" res.end(response); }, 10000); }).listen(4444, () => { - StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true, timeout: 1000}) - .should.be.rejectedWith(/timeout of 1000ms exceeded/) + StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true, timeout: 100}) + .should.be.rejectedWith(/timeout of 100ms exceeded/) .notify(done) .then(() => tempServer.close()); }); From acf091cb78ac50ecf341ab29a790d875bd0be247 Mon Sep 17 00:00:00 2001 From: robertdurst Date: Mon, 4 Jun 2018 21:14:30 -0700 Subject: [PATCH 6/6] Cleanup extra code in tests --- src/call_builder.js | 2 -- test/unit/federation_server_test.js | 47 +++++++++---------------- test/unit/stellar_toml_resolver_test.js | 15 +++----- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/src/call_builder.js b/src/call_builder.js index 2974e7537..aaead637c 100644 --- a/src/call_builder.js +++ b/src/call_builder.js @@ -1,6 +1,5 @@ import {NotFoundError, NetworkError, BadRequestError} from "./errors"; import forEach from 'lodash/forEach'; -import { Config } from "./config"; let URI = require("urijs"); let URITemplate = require("urijs/src/URITemplate"); @@ -18,7 +17,6 @@ let toBluebird = require("bluebird").resolve; */ export class CallBuilder { constructor(serverUrl) { - this.url = serverUrl; this.filter = []; this.originalSegments = this.url.segment() || []; diff --git a/test/unit/federation_server_test.js b/test/unit/federation_server_test.js index 4a2917842..af866ea21 100644 --- a/test/unit/federation_server_test.js +++ b/test/unit/federation_server_test.js @@ -230,21 +230,17 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }); - describe('FederationServer timeout', function () { - - it("times out when resolveAddress response lags", function (done) { + describe('FederationServer times out when response lags and timeout set', function () { + it("resolveAddress times out", function (done) { StellarSdk.Config.setTimeout(100); // Unable to create temp server in a browser if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - res.setHeader('Content-Type', 'application/json; charset=UTF-8'); - setTimeout(() => { - res.end(response); - }, 10000); + setTimeout(() => {}, 10000); }).listen(4444, () => { new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true}) .resolveAddress('bob*stellar.org') @@ -254,19 +250,16 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }); }); - it("times out when resolveAccountId response lags", function (done) { + it("resolveAccountId times out", function (done) { StellarSdk.Config.setTimeout(100); // Unable to create temp server in a browser if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - res.setHeader('Content-Type', 'application/json; charset=UTF-8'); - setTimeout(() => { - res.end(response); - }, 10000); + setTimeout(() => {}, 10000); }).listen(4444, () => { new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true}) .resolveAccountId('GB5XVAABEQMY63WTHDQ5RXADGYF345VWMNPTN2GFUDZT57D57ZQTJ7PS') @@ -276,19 +269,16 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }); }); - it("times out when resolveTransactionId response lags", function (done) { + it("resolveTransactionId times out", function (done) { StellarSdk.Config.setTimeout(100); // Unable to create temp server in a browser if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - res.setHeader('Content-Type', 'application/json; charset=UTF-8'); - setTimeout(() => { - res.end(response); - }, 10000); + setTimeout(() => {}, 10000); }).listen(4444, () => { new StellarSdk.FederationServer('http://localhost:4444/federation', 'stellar.org', {allowHttp: true}) .resolveTransactionId('3389e9f0f1a65f19736cacf544c2e825313e8447f569233bb8db39aa607c8889') @@ -298,17 +288,14 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }); }); - it("times out when createForDomain response lags", function (done) { + it("createForDomain times out", function (done) { // Unable to create temp server in a browser if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - setTimeout(() => { - res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); - res.end(response); - }, 1000); + setTimeout(() => {}, 1000); }).listen(4444, () => { StellarSdk.FederationServer.createForDomain("localhost:4444", {allowHttp: true, timeout: 100}) .should.be.rejectedWith(/timeout of 100ms exceeded/) @@ -317,16 +304,14 @@ FEDERATION_SERVER="https://api.stellar.org/federation" }); }); - it("times out when resolve response lags", function (done) { + it("resolve times out", function (done) { // Unable to create temp server in a browser if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.FEDERATION_RESPONSE_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - setTimeout(() => { - res.end(response); - }, 10000); + setTimeout(() => {}, 10000); }).listen(4444, () => { StellarSdk.FederationServer .resolve('bob*localhost:4444', {allowHttp: true, timeout: 100}) diff --git a/test/unit/stellar_toml_resolver_test.js b/test/unit/stellar_toml_resolver_test.js index bb7214b0f..cfa3b82bf 100644 --- a/test/unit/stellar_toml_resolver_test.js +++ b/test/unit/stellar_toml_resolver_test.js @@ -110,15 +110,13 @@ FEDERATION_SERVER="https://api.stellar.org/federation" it("rejects after given timeout when global Config.timeout flag is set", function (done) { StellarSdk.Config.setTimeout(100); + // Unable to create temp server in a browser if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - setTimeout(() => { - res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); - res.end(response); - }, 10000); + setTimeout(() => {}, 10000); }).listen(4444, () => { StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true}) .should.be.rejectedWith(/timeout of 100ms exceeded/) @@ -132,12 +130,9 @@ FEDERATION_SERVER="https://api.stellar.org/federation" if (typeof window != 'undefined') { return done(); } - var response = Array(StellarSdk.STELLAR_TOML_MAX_SIZE+10).join('a'); + let tempServer = http.createServer((req, res) => { - setTimeout(() => { - res.setHeader('Content-Type', 'text/x-toml; charset=UTF-8'); - res.end(response); - }, 10000); + setTimeout(() => {}, 10000); }).listen(4444, () => { StellarSdk.StellarTomlResolver.resolve("localhost:4444", {allowHttp: true, timeout: 100}) .should.be.rejectedWith(/timeout of 100ms exceeded/)