1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const http = require('http');
6const Countdown = require('../common/countdown');
7
8assert.throws(() => new http.Agent({
9  maxTotalSockets: 'test',
10}), {
11  code: 'ERR_INVALID_ARG_TYPE',
12  name: 'TypeError',
13  message: 'The "maxTotalSockets" argument must be of type number. ' +
14    "Received type string ('test')",
15});
16
17[-1, 0, NaN].forEach((item) => {
18  assert.throws(() => new http.Agent({
19    maxTotalSockets: item,
20  }), {
21    code: 'ERR_OUT_OF_RANGE',
22    name: 'RangeError',
23  });
24});
25
26assert.ok(new http.Agent({
27  maxTotalSockets: Infinity,
28}));
29
30function start(param = {}) {
31  const { maxTotalSockets, maxSockets } = param;
32
33  const agent = new http.Agent({
34    keepAlive: true,
35    keepAliveMsecs: 1000,
36    maxTotalSockets,
37    maxSockets,
38    maxFreeSockets: 3
39  });
40
41  const server = http.createServer(common.mustCall((req, res) => {
42    res.end('hello world');
43  }, 6));
44  const server2 = http.createServer(common.mustCall((req, res) => {
45    res.end('hello world');
46  }, 6));
47
48  server.keepAliveTimeout = 0;
49  server2.keepAliveTimeout = 0;
50
51  const countdown = new Countdown(12, () => {
52    assert.strictEqual(getRequestCount(), 0);
53    agent.destroy();
54    server.close();
55    server2.close();
56  });
57
58  function handler(s) {
59    for (let i = 0; i < 6; i++) {
60      http.get({
61        host: 'localhost',
62        port: s.address().port,
63        agent,
64        path: `/${i}`,
65      }, common.mustCall((res) => {
66        assert.strictEqual(res.statusCode, 200);
67        res.resume();
68        res.on('end', common.mustCall(() => {
69          for (const key of Object.keys(agent.sockets)) {
70            assert(agent.sockets[key].length <= maxSockets);
71          }
72          assert(getTotalSocketsCount() <= maxTotalSockets);
73          countdown.dec();
74        }));
75      }));
76    }
77  }
78
79  function getTotalSocketsCount() {
80    let num = 0;
81    for (const key of Object.keys(agent.sockets)) {
82      num += agent.sockets[key].length;
83    }
84    return num;
85  }
86
87  function getRequestCount() {
88    let num = 0;
89    for (const key of Object.keys(agent.requests)) {
90      num += agent.requests[key].length;
91    }
92    return num;
93  }
94
95  server.listen(0, common.mustCall(() => handler(server)));
96  server2.listen(0, common.mustCall(() => handler(server2)));
97}
98
99// If maxTotalSockets is larger than maxSockets,
100// then the origin check will be skipped
101// when the socket is removed.
102[{
103  maxTotalSockets: 2,
104  maxSockets: 3,
105}, {
106  maxTotalSockets: 3,
107  maxSockets: 2,
108}, {
109  maxTotalSockets: 2,
110  maxSockets: 2,
111}].forEach(start);
112