@algolia/requester-node-http 4.14.1 → 5.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ export * from './src/echoRequester';
2
+ export * from './src/createHttpRequester';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC"}
@@ -2,86 +2,83 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
+ var url = require('url');
6
+ var clientCommon = require('@algolia/client-common');
5
7
  var http = require('http');
6
8
  var https = require('https');
7
- var URL = require('url');
8
9
 
9
- /* eslint functional/prefer-readonly-type: 0 */
10
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
+
12
+ var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
13
+ var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
14
+
15
+ function echoRequester(status = 200) {
16
+ return clientCommon.createEchoRequester({ getURL: (url$1) => new url.URL(url$1), status });
17
+ }
18
+
19
+ // Global agents allow us to reuse the TCP protocol with multiple clients
10
20
  const agentOptions = { keepAlive: true };
11
- const defaultHttpAgent = new http.Agent(agentOptions);
12
- const defaultHttpsAgent = new https.Agent(agentOptions);
13
- function createNodeHttpRequester({ agent: userGlobalAgent, httpAgent: userHttpAgent, httpsAgent: userHttpsAgent, requesterOptions = {}, } = {}) {
14
- const httpAgent = userHttpAgent || userGlobalAgent || defaultHttpAgent;
15
- const httpsAgent = userHttpsAgent || userGlobalAgent || defaultHttpsAgent;
16
- return {
17
- send(request) {
18
- return new Promise(resolve => {
19
- const url = URL.parse(request.url);
20
- const path = url.query === null ? url.pathname : `${url.pathname}?${url.query}`;
21
- const options = {
22
- ...requesterOptions,
23
- agent: url.protocol === 'https:' ? httpsAgent : httpAgent,
24
- hostname: url.hostname,
25
- path,
26
- method: request.method,
27
- headers: {
28
- ...(requesterOptions && requesterOptions.headers ? requesterOptions.headers : {}),
29
- ...request.headers,
30
- },
31
- ...(url.port !== undefined ? { port: url.port || '' } : {}),
32
- };
33
- const req = (url.protocol === 'https:' ? https : http).request(options, response => {
34
- // eslint-disable-next-line functional/no-let
35
- let contentBuffers = [];
36
- response.on('data', chunk => {
37
- contentBuffers = contentBuffers.concat(chunk);
38
- });
39
- response.on('end', () => {
40
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
41
- clearTimeout(connectTimeout);
42
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
43
- clearTimeout(responseTimeout);
44
- resolve({
45
- status: response.statusCode || 0,
46
- content: Buffer.concat(contentBuffers).toString(),
47
- isTimedOut: false,
48
- });
49
- });
21
+ const httpAgent = new http__default["default"].Agent(agentOptions);
22
+ const httpsAgent = new https__default["default"].Agent(agentOptions);
23
+ function createHttpRequester() {
24
+ function send(request) {
25
+ return new Promise((resolve) => {
26
+ let responseTimeout;
27
+ // eslint-disable-next-line prefer-const -- linter thinks this is not reassigned
28
+ let connectTimeout;
29
+ const url$1 = new url.URL(request.url);
30
+ const path = url$1.search === null ? url$1.pathname : `${url$1.pathname}${url$1.search}`;
31
+ const options = {
32
+ agent: url$1.protocol === 'https:' ? httpsAgent : httpAgent,
33
+ hostname: url$1.hostname,
34
+ path,
35
+ method: request.method,
36
+ headers: request.headers,
37
+ ...(url$1.port !== undefined ? { port: url$1.port || '' } : {}),
38
+ };
39
+ const req = (url$1.protocol === 'https:' ? https__default["default"] : http__default["default"]).request(options, (response) => {
40
+ let contentBuffers = [];
41
+ response.on('data', (chunk) => {
42
+ contentBuffers = contentBuffers.concat(chunk);
50
43
  });
51
- const createTimeout = (timeout, content) => {
52
- return setTimeout(() => {
53
- req.abort();
54
- resolve({
55
- status: 0,
56
- content,
57
- isTimedOut: true,
58
- });
59
- }, timeout * 1000);
60
- };
61
- const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
62
- // eslint-disable-next-line functional/no-let
63
- let responseTimeout;
64
- req.on('error', error => {
44
+ response.on('end', () => {
65
45
  clearTimeout(connectTimeout);
66
46
  clearTimeout(responseTimeout);
67
- resolve({ status: 0, content: error.message, isTimedOut: false });
68
- });
69
- req.once('response', () => {
70
- clearTimeout(connectTimeout);
71
- responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
47
+ resolve({
48
+ status: response.statusCode || 0,
49
+ content: Buffer.concat(contentBuffers).toString(),
50
+ isTimedOut: false,
51
+ });
72
52
  });
73
- if (request.data !== undefined) {
74
- req.write(request.data);
75
- }
76
- req.end();
77
53
  });
78
- },
79
- destroy() {
80
- httpAgent.destroy();
81
- httpsAgent.destroy();
82
- return Promise.resolve();
83
- },
84
- };
54
+ const createTimeout = (timeout, content) => {
55
+ return setTimeout(() => {
56
+ req.destroy();
57
+ resolve({
58
+ status: 0,
59
+ content,
60
+ isTimedOut: true,
61
+ });
62
+ }, timeout);
63
+ };
64
+ connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
65
+ req.on('error', (error) => {
66
+ clearTimeout(connectTimeout);
67
+ clearTimeout(responseTimeout);
68
+ resolve({ status: 0, content: error.message, isTimedOut: false });
69
+ });
70
+ req.once('response', () => {
71
+ clearTimeout(connectTimeout);
72
+ responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
73
+ });
74
+ if (request.data !== undefined) {
75
+ req.write(request.data);
76
+ }
77
+ req.end();
78
+ });
79
+ }
80
+ return { send };
85
81
  }
86
82
 
87
- exports.createNodeHttpRequester = createNodeHttpRequester;
83
+ exports.createHttpRequester = createHttpRequester;
84
+ exports.echoRequester = echoRequester;
@@ -0,0 +1,74 @@
1
+ import { URL } from 'url';
2
+ import { createEchoRequester } from '@algolia/client-common';
3
+ import http from 'http';
4
+ import https from 'https';
5
+
6
+ function echoRequester(status = 200) {
7
+ return createEchoRequester({ getURL: (url) => new URL(url), status });
8
+ }
9
+
10
+ // Global agents allow us to reuse the TCP protocol with multiple clients
11
+ const agentOptions = { keepAlive: true };
12
+ const httpAgent = new http.Agent(agentOptions);
13
+ const httpsAgent = new https.Agent(agentOptions);
14
+ function createHttpRequester() {
15
+ function send(request) {
16
+ return new Promise((resolve) => {
17
+ let responseTimeout;
18
+ // eslint-disable-next-line prefer-const -- linter thinks this is not reassigned
19
+ let connectTimeout;
20
+ const url = new URL(request.url);
21
+ const path = url.search === null ? url.pathname : `${url.pathname}${url.search}`;
22
+ const options = {
23
+ agent: url.protocol === 'https:' ? httpsAgent : httpAgent,
24
+ hostname: url.hostname,
25
+ path,
26
+ method: request.method,
27
+ headers: request.headers,
28
+ ...(url.port !== undefined ? { port: url.port || '' } : {}),
29
+ };
30
+ const req = (url.protocol === 'https:' ? https : http).request(options, (response) => {
31
+ let contentBuffers = [];
32
+ response.on('data', (chunk) => {
33
+ contentBuffers = contentBuffers.concat(chunk);
34
+ });
35
+ response.on('end', () => {
36
+ clearTimeout(connectTimeout);
37
+ clearTimeout(responseTimeout);
38
+ resolve({
39
+ status: response.statusCode || 0,
40
+ content: Buffer.concat(contentBuffers).toString(),
41
+ isTimedOut: false,
42
+ });
43
+ });
44
+ });
45
+ const createTimeout = (timeout, content) => {
46
+ return setTimeout(() => {
47
+ req.destroy();
48
+ resolve({
49
+ status: 0,
50
+ content,
51
+ isTimedOut: true,
52
+ });
53
+ }, timeout);
54
+ };
55
+ connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
56
+ req.on('error', (error) => {
57
+ clearTimeout(connectTimeout);
58
+ clearTimeout(responseTimeout);
59
+ resolve({ status: 0, content: error.message, isTimedOut: false });
60
+ });
61
+ req.once('response', () => {
62
+ clearTimeout(connectTimeout);
63
+ responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
64
+ });
65
+ if (request.data !== undefined) {
66
+ req.write(request.data);
67
+ }
68
+ req.end();
69
+ });
70
+ }
71
+ return { send };
72
+ }
73
+
74
+ export { createHttpRequester, echoRequester };
@@ -0,0 +1,3 @@
1
+ import type { Requester } from '@algolia/client-common';
2
+ export declare function createHttpRequester(): Requester;
3
+ //# sourceMappingURL=createHttpRequester.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createHttpRequester.d.ts","sourceRoot":"","sources":["../../../../packages/requester-node-http/src/createHttpRequester.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAc,SAAS,EAAY,MAAM,wBAAwB,CAAC;AAO9E,wBAAgB,mBAAmB,IAAI,SAAS,CAmF/C"}
@@ -0,0 +1,3 @@
1
+ import type { Requester } from '@algolia/client-common';
2
+ export declare function echoRequester(status?: number): Requester;
3
+ //# sourceMappingURL=echoRequester.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"echoRequester.d.ts","sourceRoot":"","sources":["../../../../packages/requester-node-http/src/echoRequester.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAExD,wBAAgB,aAAa,CAAC,MAAM,GAAE,MAAY,GAAG,SAAS,CAE7D"}
package/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './src/echoRequester';
2
+ export * from './src/createHttpRequester';
package/package.json CHANGED
@@ -1,22 +1,34 @@
1
1
  {
2
2
  "name": "@algolia/requester-node-http",
3
- "version": "4.14.1",
4
- "private": false,
3
+ "version": "5.0.0-alpha.1",
5
4
  "description": "Promise-based request library for node using the native http module.",
6
- "repository": {
7
- "type": "git",
8
- "url": "git://github.com/algolia/algoliasearch-client-javascript.git"
9
- },
5
+ "repository": "algolia/algoliasearch-client-javascript",
10
6
  "license": "MIT",
11
- "sideEffects": false,
12
- "main": "index.js",
13
- "module": "dist/requester-node-http.esm.js",
14
- "types": "dist/requester-node-http.d.ts",
7
+ "author": "Algolia",
8
+ "main": "dist/requester-node-http.cjs.js",
9
+ "module": "dist/requester-node-http.esm.node.js",
10
+ "types": "dist/index.d.ts",
15
11
  "files": [
16
- "index.js",
17
- "dist"
12
+ "dist",
13
+ "src",
14
+ "index.ts"
18
15
  ],
16
+ "scripts": {
17
+ "clean": "rm -rf dist/",
18
+ "test": "jest"
19
+ },
19
20
  "dependencies": {
20
- "@algolia/requester-common": "4.14.1"
21
+ "@algolia/client-common": "5.0.0-alpha.1"
22
+ },
23
+ "devDependencies": {
24
+ "@types/jest": "28.1.6",
25
+ "@types/node": "16.11.45",
26
+ "jest": "28.1.3",
27
+ "nock": "13.2.9",
28
+ "ts-jest": "28.0.5",
29
+ "typescript": "4.7.4"
30
+ },
31
+ "engines": {
32
+ "node": ">= 14.0.0"
21
33
  }
22
34
  }
@@ -0,0 +1,226 @@
1
+ import type http from 'http';
2
+ import { Readable } from 'stream';
3
+
4
+ import type { EndRequest } from '@algolia/client-common';
5
+ import nock from 'nock';
6
+
7
+ import { createHttpRequester } from '../..';
8
+ import {
9
+ headers,
10
+ timeoutRequest,
11
+ requestStub,
12
+ testQueryHeader,
13
+ testQueryBaseUrl,
14
+ getStringifiedBody,
15
+ createTestServer,
16
+ } from '../../../../tests/utils';
17
+
18
+ const requester = createHttpRequester();
19
+
20
+ describe('status code handling', () => {
21
+ it('sends requests', async () => {
22
+ const body = getStringifiedBody();
23
+
24
+ nock(testQueryBaseUrl, { reqheaders: headers })
25
+ .post('/foo')
26
+ .query(testQueryHeader)
27
+ .reply(200, body);
28
+
29
+ const response = await requester.send(requestStub);
30
+
31
+ expect(response.content).toEqual(body);
32
+ });
33
+
34
+ it('resolves status 200', async () => {
35
+ const body = getStringifiedBody();
36
+
37
+ nock(testQueryBaseUrl, { reqheaders: headers })
38
+ .post('/foo')
39
+ .query(testQueryHeader)
40
+ .reply(200, body);
41
+
42
+ const response = await requester.send(requestStub);
43
+
44
+ expect(response.status).toBe(200);
45
+ expect(response.content).toBe(body);
46
+ expect(response.isTimedOut).toBe(false);
47
+ });
48
+
49
+ it('resolves status 300', async () => {
50
+ const reason = 'Multiple Choices';
51
+
52
+ nock(testQueryBaseUrl, { reqheaders: headers })
53
+ .post('/foo')
54
+ .query(testQueryHeader)
55
+ .reply(300, reason);
56
+
57
+ const response = await requester.send(requestStub);
58
+
59
+ expect(response.status).toBe(300);
60
+ expect(response.content).toBe(reason);
61
+ expect(response.isTimedOut).toBe(false);
62
+ });
63
+
64
+ it('resolves status 400', async () => {
65
+ const body = getStringifiedBody({
66
+ message: 'Invalid Application-Id or API-Key',
67
+ });
68
+
69
+ nock(testQueryBaseUrl, { reqheaders: headers })
70
+ .post('/foo')
71
+ .query(testQueryHeader)
72
+ .reply(400, body);
73
+
74
+ const response = await requester.send(requestStub);
75
+
76
+ expect(response.status).toBe(400);
77
+ expect(response.content).toBe(body);
78
+ expect(response.isTimedOut).toBe(false);
79
+ });
80
+
81
+ it('handles chunked responses inside unicode character boundaries', async () => {
82
+ const data = Buffer.from('äöü');
83
+
84
+ // create a test response stream that is chunked inside a unicode character
85
+ // eslint-disable-next-line @typescript-eslint/explicit-function-return-type
86
+ function* generate() {
87
+ yield data.slice(0, 3);
88
+ yield data.slice(3);
89
+ }
90
+
91
+ const testStream = Readable.from(generate());
92
+
93
+ nock(testQueryBaseUrl, { reqheaders: headers })
94
+ .post('/foo')
95
+ .query(testQueryHeader)
96
+ .reply(200, testStream);
97
+
98
+ const response = await requester.send(requestStub);
99
+
100
+ expect(response.content).toEqual(data.toString());
101
+ });
102
+ });
103
+
104
+ describe('timeout handling', () => {
105
+ let server: http.Server;
106
+ // setup http server to test timeout
107
+ beforeAll(() => {
108
+ server = createTestServer();
109
+
110
+ server.listen('1111');
111
+ });
112
+
113
+ afterAll((done) => {
114
+ server.close(() => done());
115
+ });
116
+
117
+ it('timeouts with the given 1 seconds connection timeout', async () => {
118
+ const before = Date.now();
119
+ const response = await requester.send({
120
+ ...timeoutRequest,
121
+ connectTimeout: 1000,
122
+ url: 'http://www.google.com:81',
123
+ });
124
+
125
+ const now = Date.now();
126
+
127
+ expect(response.content).toBe('Connection timeout');
128
+ expect(now - before).toBeGreaterThan(999);
129
+ expect(now - before).toBeLessThan(1200);
130
+ });
131
+
132
+ it('connection timeouts with the given 2 seconds connection timeout', async () => {
133
+ const before = Date.now();
134
+ const response = await requester.send({
135
+ ...timeoutRequest,
136
+ connectTimeout: 2000,
137
+ url: 'http://www.google.com:81',
138
+ });
139
+
140
+ const now = Date.now();
141
+
142
+ expect(response.content).toBe('Connection timeout');
143
+ expect(now - before).toBeGreaterThan(1999);
144
+ expect(now - before).toBeLessThan(2200);
145
+ });
146
+
147
+ it("socket timeouts if response don't appears before the timeout with 2 seconds timeout", async () => {
148
+ const before = Date.now();
149
+
150
+ const response = await requester.send({
151
+ ...timeoutRequest,
152
+ responseTimeout: 2000,
153
+ url: 'http://localhost:1111',
154
+ });
155
+
156
+ const now = Date.now();
157
+
158
+ expect(response.content).toBe('Socket timeout');
159
+ expect(now - before).toBeGreaterThan(1999);
160
+ expect(now - before).toBeLessThan(2200);
161
+ });
162
+
163
+ it("socket timeouts if response don't appears before the timeout with 3 seconds timeout", async () => {
164
+ const before = Date.now();
165
+ const response = await requester.send({
166
+ ...timeoutRequest,
167
+ responseTimeout: 3000,
168
+ url: 'http://localhost:1111',
169
+ });
170
+
171
+ const now = Date.now();
172
+
173
+ expect(response.content).toBe('Socket timeout');
174
+ expect(now - before).toBeGreaterThan(2999);
175
+ expect(now - before).toBeLessThan(3200);
176
+ });
177
+
178
+ it('do not timeouts if response appears before the timeout', async () => {
179
+ const before = Date.now();
180
+ const response = await requester.send({
181
+ ...requestStub,
182
+ url: 'http://localhost:1111',
183
+ responseTimeout: 6000,
184
+ });
185
+
186
+ const now = Date.now();
187
+
188
+ expect(response.isTimedOut).toBe(false);
189
+ expect(response.status).toBe(200);
190
+ expect(response.content).toBe('{"foo": "bar"}');
191
+ expect(now - before).toBeGreaterThan(4999);
192
+ expect(now - before).toBeLessThan(5200);
193
+ }, 10000); // This is a long-running test, default server timeout is set to 5000ms
194
+ });
195
+
196
+ describe('error handling', (): void => {
197
+ it('resolves dns not found', async () => {
198
+ const request: EndRequest = {
199
+ url: 'https://this-dont-exist.algolia.com',
200
+ method: 'POST',
201
+ headers,
202
+ data: getStringifiedBody(),
203
+ responseTimeout: 2000,
204
+ connectTimeout: 1000,
205
+ };
206
+
207
+ const response = await requester.send(request);
208
+
209
+ expect(response.status).toBe(0);
210
+ expect(response.content).toContain('');
211
+ expect(response.isTimedOut).toBe(false);
212
+ });
213
+
214
+ it('resolves general network errors', async () => {
215
+ nock(testQueryBaseUrl, { reqheaders: headers })
216
+ .post('/foo')
217
+ .query(testQueryHeader)
218
+ .replyWithError('This is a general error');
219
+
220
+ const response = await requester.send(requestStub);
221
+
222
+ expect(response.status).toBe(0);
223
+ expect(response.content).toBe('This is a general error');
224
+ expect(response.isTimedOut).toBe(false);
225
+ });
226
+ });
@@ -0,0 +1,95 @@
1
+ import http from 'http';
2
+ import https from 'https';
3
+ import { URL } from 'url';
4
+
5
+ import type { EndRequest, Requester, Response } from '@algolia/client-common';
6
+
7
+ // Global agents allow us to reuse the TCP protocol with multiple clients
8
+ const agentOptions = { keepAlive: true };
9
+ const httpAgent = new http.Agent(agentOptions);
10
+ const httpsAgent = new https.Agent(agentOptions);
11
+
12
+ export function createHttpRequester(): Requester {
13
+ function send(request: EndRequest): Promise<Response> {
14
+ return new Promise((resolve) => {
15
+ let responseTimeout: NodeJS.Timeout | undefined;
16
+ // eslint-disable-next-line prefer-const -- linter thinks this is not reassigned
17
+ let connectTimeout: NodeJS.Timeout | undefined;
18
+ const url = new URL(request.url);
19
+ const path =
20
+ url.search === null ? url.pathname : `${url.pathname}${url.search}`;
21
+ const options: https.RequestOptions = {
22
+ agent: url.protocol === 'https:' ? httpsAgent : httpAgent,
23
+ hostname: url.hostname,
24
+ path,
25
+ method: request.method,
26
+ headers: request.headers,
27
+ ...(url.port !== undefined ? { port: url.port || '' } : {}),
28
+ };
29
+
30
+ const req = (url.protocol === 'https:' ? https : http).request(
31
+ options,
32
+ (response) => {
33
+ let contentBuffers: Buffer[] = [];
34
+
35
+ response.on('data', (chunk) => {
36
+ contentBuffers = contentBuffers.concat(chunk);
37
+ });
38
+
39
+ response.on('end', () => {
40
+ clearTimeout(connectTimeout as NodeJS.Timeout);
41
+ clearTimeout(responseTimeout as NodeJS.Timeout);
42
+
43
+ resolve({
44
+ status: response.statusCode || 0,
45
+ content: Buffer.concat(contentBuffers).toString(),
46
+ isTimedOut: false,
47
+ });
48
+ });
49
+ }
50
+ );
51
+
52
+ const createTimeout = (
53
+ timeout: number,
54
+ content: string
55
+ ): NodeJS.Timeout => {
56
+ return setTimeout(() => {
57
+ req.destroy();
58
+
59
+ resolve({
60
+ status: 0,
61
+ content,
62
+ isTimedOut: true,
63
+ });
64
+ }, timeout);
65
+ };
66
+
67
+ connectTimeout = createTimeout(
68
+ request.connectTimeout,
69
+ 'Connection timeout'
70
+ );
71
+
72
+ req.on('error', (error) => {
73
+ clearTimeout(connectTimeout as NodeJS.Timeout);
74
+ clearTimeout(responseTimeout!);
75
+ resolve({ status: 0, content: error.message, isTimedOut: false });
76
+ });
77
+
78
+ req.once('response', () => {
79
+ clearTimeout(connectTimeout as NodeJS.Timeout);
80
+ responseTimeout = createTimeout(
81
+ request.responseTimeout,
82
+ 'Socket timeout'
83
+ );
84
+ });
85
+
86
+ if (request.data !== undefined) {
87
+ req.write(request.data);
88
+ }
89
+
90
+ req.end();
91
+ });
92
+ }
93
+
94
+ return { send };
95
+ }
@@ -0,0 +1,8 @@
1
+ import { URL } from 'url';
2
+
3
+ import { createEchoRequester } from '@algolia/client-common';
4
+ import type { Requester } from '@algolia/client-common';
5
+
6
+ export function echoRequester(status: number = 200): Requester {
7
+ return createEchoRequester({ getURL: (url: string) => new URL(url), status });
8
+ }
@@ -1,16 +0,0 @@
1
- /// <reference types="node" />
2
- import { Destroyable } from '@algolia/requester-common';
3
- import * as http from 'http';
4
- import * as https from 'https';
5
- import { Requester } from '@algolia/requester-common';
6
-
7
- export declare function createNodeHttpRequester({ agent: userGlobalAgent, httpAgent: userHttpAgent, httpsAgent: userHttpsAgent, requesterOptions, }?: NodeHttpRequesterOptions): Requester & Destroyable;
8
-
9
- export declare type NodeHttpRequesterOptions = {
10
- agent?: https.Agent | http.Agent;
11
- httpAgent?: http.Agent;
12
- httpsAgent?: https.Agent;
13
- requesterOptions?: https.RequestOptions;
14
- };
15
-
16
- export { }
@@ -1,85 +0,0 @@
1
- import * as http from 'http';
2
- import { Agent } from 'http';
3
- import * as https from 'https';
4
- import { Agent as Agent$1 } from 'https';
5
- import { parse } from 'url';
6
-
7
- /* eslint functional/prefer-readonly-type: 0 */
8
- const agentOptions = { keepAlive: true };
9
- const defaultHttpAgent = new Agent(agentOptions);
10
- const defaultHttpsAgent = new Agent$1(agentOptions);
11
- function createNodeHttpRequester({ agent: userGlobalAgent, httpAgent: userHttpAgent, httpsAgent: userHttpsAgent, requesterOptions = {}, } = {}) {
12
- const httpAgent = userHttpAgent || userGlobalAgent || defaultHttpAgent;
13
- const httpsAgent = userHttpsAgent || userGlobalAgent || defaultHttpsAgent;
14
- return {
15
- send(request) {
16
- return new Promise(resolve => {
17
- const url = parse(request.url);
18
- const path = url.query === null ? url.pathname : `${url.pathname}?${url.query}`;
19
- const options = {
20
- ...requesterOptions,
21
- agent: url.protocol === 'https:' ? httpsAgent : httpAgent,
22
- hostname: url.hostname,
23
- path,
24
- method: request.method,
25
- headers: {
26
- ...(requesterOptions && requesterOptions.headers ? requesterOptions.headers : {}),
27
- ...request.headers,
28
- },
29
- ...(url.port !== undefined ? { port: url.port || '' } : {}),
30
- };
31
- const req = (url.protocol === 'https:' ? https : http).request(options, response => {
32
- // eslint-disable-next-line functional/no-let
33
- let contentBuffers = [];
34
- response.on('data', chunk => {
35
- contentBuffers = contentBuffers.concat(chunk);
36
- });
37
- response.on('end', () => {
38
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
39
- clearTimeout(connectTimeout);
40
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
41
- clearTimeout(responseTimeout);
42
- resolve({
43
- status: response.statusCode || 0,
44
- content: Buffer.concat(contentBuffers).toString(),
45
- isTimedOut: false,
46
- });
47
- });
48
- });
49
- const createTimeout = (timeout, content) => {
50
- return setTimeout(() => {
51
- req.abort();
52
- resolve({
53
- status: 0,
54
- content,
55
- isTimedOut: true,
56
- });
57
- }, timeout * 1000);
58
- };
59
- const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
60
- // eslint-disable-next-line functional/no-let
61
- let responseTimeout;
62
- req.on('error', error => {
63
- clearTimeout(connectTimeout);
64
- clearTimeout(responseTimeout);
65
- resolve({ status: 0, content: error.message, isTimedOut: false });
66
- });
67
- req.once('response', () => {
68
- clearTimeout(connectTimeout);
69
- responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
70
- });
71
- if (request.data !== undefined) {
72
- req.write(request.data);
73
- }
74
- req.end();
75
- });
76
- },
77
- destroy() {
78
- httpAgent.destroy();
79
- httpsAgent.destroy();
80
- return Promise.resolve();
81
- },
82
- };
83
- }
84
-
85
- export { createNodeHttpRequester };
package/index.js DELETED
@@ -1,2 +0,0 @@
1
- // eslint-disable-next-line functional/immutable-data, import/no-commonjs
2
- module.exports = require('./dist/requester-node-http.cjs.js');