diff --git a/.eslintrc b/.eslintrc index 7b409e1..6ad4041 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,7 +8,8 @@ "expect": true }, "rules": { - "security/detect-object-injection": 0 + "security/detect-object-injection": 0, + "no-unused-expressions": 0 }, "extends": [ "emarsys" diff --git a/lib/request.js b/lib/request.js index fc8e262..92b5edb 100644 --- a/lib/request.js +++ b/lib/request.js @@ -1,6 +1,8 @@ 'use strict'; const Escher = require('escher-auth'); +const http = require('http'); +const https = require('https'); const Options = require('./requestOption'); const Wrapper = require('./wrapper'); const SuiteRequestError = require('./requestError'); @@ -21,6 +23,11 @@ class SuiteRequest { this._escher = new Escher(escherConfig); this._options = requestOptions; + + if (requestOptions.keepAlive) { + this.httpAgent = new http.Agent({ keepAlive: true }); + this.httpsAgent = new https.Agent({ keepAlive: true }); + } } get(path) { @@ -72,7 +79,9 @@ class SuiteRequest { return Object.assign({}, defaultOptions, { method: method, url: realPath, - path: realPath + path: realPath, + httpAgent: this.httpAgent, + httpsAgent: this.httpsAgent }); } diff --git a/lib/request.spec.js b/lib/request.spec.js index b3f779e..77a9fff 100644 --- a/lib/request.spec.js +++ b/lib/request.spec.js @@ -3,6 +3,8 @@ const SuiteRequest = require('./request'); const axios = require('axios'); const Escher = require('escher-auth'); +const http = require('http'); +const https = require('https'); describe('SuiteRequest', function() { const serviceConfig = { @@ -138,4 +140,31 @@ describe('SuiteRequest', function() { const firstCall = Escher.prototype.signRequest.getCall(0); expect(firstCall.args[1]).to.eql(JSON.stringify(payload)); }); + + it('should not create http agents by default', function() { + suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions); + + expect(suiteRequest.httpAgent).to.be.undefined; + expect(suiteRequest.httpsAgent).to.be.undefined; + }); + + it('should create http agents when connection is keep alive', function() { + requestOptions = new SuiteRequest.Options(serviceConfig.host, Object.assign({ keepAlive: true }, serviceConfig)); + + suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions); + + expect(suiteRequest.httpAgent).to.be.an.instanceOf(http.Agent); + expect(suiteRequest.httpsAgent).to.be.an.instanceOf(https.Agent); + }); + + it('should pass http agents to wrapper', function*() { + requestOptions = new SuiteRequest.Options(serviceConfig.host, Object.assign({ keepAlive: true }, serviceConfig)); + suiteRequest = SuiteRequest.create('key-id', 'secret', requestOptions); + + yield suiteRequest.post('/path', { name: 'Almanach' }); + + const requestArgument = requestStub.args[0][0]; + expect(requestArgument.httpAgent).to.eql(suiteRequest.httpAgent); + expect(requestArgument.httpsAgent).to.eql(suiteRequest.httpsAgent); + }); }); diff --git a/lib/requestOption.js b/lib/requestOption.js index 8bf4c8c..a5ffcb4 100644 --- a/lib/requestOption.js +++ b/lib/requestOption.js @@ -36,6 +36,7 @@ class SuiteRequestOption { this.timeout = 'timeout' in options ? options.timeout : 15000; this.allowEmptyResponse = false; this.maxContentLength = options.maxContentLength || 10 * MEGA_BYTE; + this.keepAlive = !!options.keepAlive; if (!options) { options = {}; diff --git a/lib/wrapper.js b/lib/wrapper.js index fc572f6..36020e0 100644 --- a/lib/wrapper.js +++ b/lib/wrapper.js @@ -34,7 +34,9 @@ class RequestWrapper { transformResponse: [body => body], maxContentLength: this.requestOptions.maxContentLength, validateStatus: () => true, - cancelToken: source.token + cancelToken: source.token, + httpAgent: this.requestOptions.httpAgent, + httpsAgent: this.requestOptions.httpsAgent }; return axios