• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1'use strict';
2
3const common = require('../common');
4const http = require('http');
5const assert = require('assert');
6const { Writable } = require('stream');
7const Countdown = require('../common/countdown');
8
9const N = 2;
10let abortRequest = true;
11
12const server = http.Server(common.mustCall((req, res) => {
13  const headers = { 'Content-Type': 'text/plain' };
14  headers['Content-Length'] = 50;
15  const socket = res.socket;
16  res.writeHead(200, headers);
17  res.write('aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd');
18  if (abortRequest) {
19    process.nextTick(() => socket.destroy());
20  } else {
21    process.nextTick(() => res.end('eeeeeeeeee'));
22  }
23}, N));
24
25server.listen(0, common.mustCall(() => {
26  download();
27}));
28
29const finishCountdown = new Countdown(N, common.mustCall(() => {
30  server.close();
31}));
32const reqCountdown = new Countdown(N, common.mustCall());
33
34function download() {
35  const opts = {
36    port: server.address().port,
37    path: '/',
38  };
39  const req = http.get(opts);
40  req.on('error', common.mustNotCall());
41  req.on('response', (res) => {
42    assert.strictEqual(res.statusCode, 200);
43    assert.strictEqual(res.headers.connection, 'close');
44    let aborted = false;
45    const writable = new Writable({
46      write(chunk, encoding, callback) {
47        callback();
48      }
49    });
50    res.pipe(writable);
51    const _handle = res.socket._handle;
52    _handle._close = res.socket._handle.close;
53    _handle.close = function(callback) {
54      _handle._close();
55      // Set readable to true even though request is complete
56      if (res.complete) res.readable = true;
57      callback();
58    };
59    if (!abortRequest) {
60      res.on('end', common.mustCall(() => {
61        reqCountdown.dec();
62      }));
63      res.on('error', common.mustNotCall());
64    } else {
65      res.on('aborted', common.mustCall(() => {
66        aborted = true;
67        reqCountdown.dec();
68        writable.end();
69      }));
70      res.on('error', common.expectsError({
71        code: 'ECONNRESET'
72      }));
73    }
74
75    writable.on('finish', () => {
76      assert.strictEqual(aborted, abortRequest);
77      finishCountdown.dec();
78      if (finishCountdown.remaining === 0) return;
79      abortRequest = false; // Next one should be a good response
80      download();
81    });
82  });
83  req.end();
84}
85