requester-node-http.esm.js 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  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. /* eslint functional/prefer-readonly-type: 0 */
  7. const agentOptions = { keepAlive: true };
  8. const defaultHttpAgent = new Agent(agentOptions);
  9. const defaultHttpsAgent = new Agent$1(agentOptions);
  10. function createNodeHttpRequester({ agent: userGlobalAgent, httpAgent: userHttpAgent, httpsAgent: userHttpsAgent, requesterOptions = {}, } = {}) {
  11. const httpAgent = userHttpAgent || userGlobalAgent || defaultHttpAgent;
  12. const httpsAgent = userHttpsAgent || userGlobalAgent || defaultHttpsAgent;
  13. return {
  14. send(request) {
  15. return new Promise(resolve => {
  16. const url = parse(request.url);
  17. const path = url.query === null ? url.pathname : `${url.pathname}?${url.query}`;
  18. const options = {
  19. ...requesterOptions,
  20. agent: url.protocol === 'https:' ? httpsAgent : httpAgent,
  21. hostname: url.hostname,
  22. path,
  23. method: request.method,
  24. headers: {
  25. ...(requesterOptions && requesterOptions.headers ? requesterOptions.headers : {}),
  26. ...request.headers,
  27. },
  28. ...(url.port !== undefined ? { port: url.port || '' } : {}),
  29. };
  30. const req = (url.protocol === 'https:' ? https : http).request(options, response => {
  31. // eslint-disable-next-line functional/no-let
  32. let contentBuffers = [];
  33. response.on('data', chunk => {
  34. contentBuffers = contentBuffers.concat(chunk);
  35. });
  36. response.on('end', () => {
  37. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  38. clearTimeout(connectTimeout);
  39. // eslint-disable-next-line @typescript-eslint/no-use-before-define
  40. clearTimeout(responseTimeout);
  41. resolve({
  42. status: response.statusCode || 0,
  43. content: Buffer.concat(contentBuffers).toString(),
  44. isTimedOut: false,
  45. });
  46. });
  47. });
  48. const createTimeout = (timeout, content) => {
  49. return setTimeout(() => {
  50. req.abort();
  51. resolve({
  52. status: 0,
  53. content,
  54. isTimedOut: true,
  55. });
  56. }, timeout * 1000);
  57. };
  58. const connectTimeout = createTimeout(request.connectTimeout, 'Connection timeout');
  59. // eslint-disable-next-line functional/no-let
  60. let responseTimeout;
  61. req.on('error', error => {
  62. clearTimeout(connectTimeout);
  63. clearTimeout(responseTimeout);
  64. resolve({ status: 0, content: error.message, isTimedOut: false });
  65. });
  66. req.once('response', () => {
  67. clearTimeout(connectTimeout);
  68. responseTimeout = createTimeout(request.responseTimeout, 'Socket timeout');
  69. });
  70. if (request.data !== undefined) {
  71. req.write(request.data);
  72. }
  73. req.end();
  74. });
  75. },
  76. destroy() {
  77. httpAgent.destroy();
  78. httpsAgent.destroy();
  79. return Promise.resolve();
  80. },
  81. };
  82. }
  83. export { createNodeHttpRequester };