1'use strict';
2const common = require('../common');
3const http = require('http');
4const assert = require('assert');
5const { getEventListeners } = require('events');
6
7{
8  // abort
9
10  const server = http.createServer(common.mustCall((req, res) => {
11    res.end('Hello');
12  }));
13
14  server.listen(0, common.mustCall(() => {
15    const options = { port: server.address().port };
16    const req = http.get(options, common.mustCall((res) => {
17      res.on('data', (data) => {
18        req.abort();
19        assert.strictEqual(req.aborted, true);
20        assert.strictEqual(req.destroyed, true);
21        server.close();
22      });
23    }));
24    req.on('error', common.mustNotCall());
25    assert.strictEqual(req.aborted, false);
26    assert.strictEqual(req.destroyed, false);
27  }));
28}
29
30{
31  // destroy + res
32
33  const server = http.createServer(common.mustCall((req, res) => {
34    res.end('Hello');
35  }));
36
37  server.listen(0, common.mustCall(() => {
38    const options = { port: server.address().port };
39    const req = http.get(options, common.mustCall((res) => {
40      res.on('data', (data) => {
41        req.destroy();
42        assert.strictEqual(req.aborted, false);
43        assert.strictEqual(req.destroyed, true);
44        server.close();
45      });
46    }));
47    req.on('error', common.mustNotCall());
48    assert.strictEqual(req.aborted, false);
49    assert.strictEqual(req.destroyed, false);
50  }));
51}
52
53{
54  // destroy
55
56  const server = http.createServer(common.mustNotCall());
57
58  server.listen(0, common.mustCall(() => {
59    const options = { port: server.address().port };
60    const req = http.get(options, common.mustNotCall());
61    req.on('error', common.mustCall((err) => {
62      assert.strictEqual(err.code, 'ECONNRESET');
63      server.close();
64    }));
65    assert.strictEqual(req.aborted, false);
66    assert.strictEqual(req.destroyed, false);
67    req.destroy();
68    assert.strictEqual(req.aborted, false);
69    assert.strictEqual(req.destroyed, true);
70  }));
71}
72
73
74{
75  // Destroy post-abort sync with AbortSignal
76
77  const server = http.createServer(common.mustNotCall());
78  const controller = new AbortController();
79  const { signal } = controller;
80  server.listen(0, common.mustCall(() => {
81    const options = { port: server.address().port, signal };
82    const req = http.get(options, common.mustNotCall());
83    req.on('error', common.mustCall((err) => {
84      assert.strictEqual(err.code, 'ABORT_ERR');
85      assert.strictEqual(err.name, 'AbortError');
86      server.close();
87    }));
88    assert.strictEqual(getEventListeners(signal, 'abort').length, 1);
89    assert.strictEqual(req.aborted, false);
90    assert.strictEqual(req.destroyed, false);
91    controller.abort();
92    assert.strictEqual(req.aborted, false);
93    assert.strictEqual(req.destroyed, true);
94  }));
95}
96
97{
98  // Use post-abort async AbortSignal
99  const server = http.createServer(common.mustNotCall());
100  const controller = new AbortController();
101  const { signal } = controller;
102  server.listen(0, common.mustCall(() => {
103    const options = { port: server.address().port, signal };
104    const req = http.get(options, common.mustNotCall());
105    req.on('error', common.mustCall((err) => {
106      assert.strictEqual(err.code, 'ABORT_ERR');
107      assert.strictEqual(err.name, 'AbortError');
108    }));
109
110    req.on('close', common.mustCall(() => {
111      assert.strictEqual(req.aborted, false);
112      assert.strictEqual(req.destroyed, true);
113      server.close();
114    }));
115
116    assert.strictEqual(getEventListeners(signal, 'abort').length, 1);
117    process.nextTick(() => controller.abort());
118  }));
119}
120
121{
122  // Use pre-aborted AbortSignal
123  const server = http.createServer(common.mustNotCall());
124  const controller = new AbortController();
125  const { signal } = controller;
126  server.listen(0, common.mustCall(() => {
127    controller.abort();
128    const options = { port: server.address().port, signal };
129    const req = http.get(options, common.mustNotCall());
130    assert.strictEqual(getEventListeners(signal, 'abort').length, 0);
131    req.on('error', common.mustCall((err) => {
132      assert.strictEqual(err.code, 'ABORT_ERR');
133      assert.strictEqual(err.name, 'AbortError');
134      server.close();
135    }));
136    assert.strictEqual(req.aborted, false);
137    assert.strictEqual(req.destroyed, true);
138  }));
139}
140