summaryrefslogtreecommitdiff
path: root/test/parallel/test-http-client-spurious-aborted.js
blob: 0cb2f471c2b7920811c8e095584f526ec67d1961 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
'use strict';

const common = require('../common');
const http = require('http');
const assert = require('assert');
const { Writable } = require('stream');
const Countdown = require('../common/countdown');

const N = 2;
let abortRequest = true;

const server = http.Server(common.mustCall((req, res) => {
  const headers = { 'Content-Type': 'text/plain' };
  headers['Content-Length'] = 50;
  const socket = res.socket;
  res.writeHead(200, headers);
  res.write('aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd');
  if (abortRequest) {
    process.nextTick(() => socket.destroy());
  } else {
    process.nextTick(() => res.end('eeeeeeeeee'));
  }
}, N));

server.listen(0, common.mustCall(() => {
  download();
}));

const finishCountdown = new Countdown(N, common.mustCall(() => {
  server.close();
}));
const reqCountdown = new Countdown(N, common.mustCall());

function download() {
  const opts = {
    port: server.address().port,
    path: '/',
  };
  const req = http.get(opts);
  req.on('error', common.mustNotCall());
  req.on('response', (res) => {
    assert.strictEqual(res.statusCode, 200);
    assert.strictEqual(res.headers.connection, 'close');
    let aborted = false;
    const writable = new Writable({
      write(chunk, encoding, callback) {
        callback();
      }
    });
    res.pipe(writable);
    const _handle = res.socket._handle;
    _handle._close = res.socket._handle.close;
    _handle.close = function(callback) {
      _handle._close();
      // Set readable to true even though request is complete
      if (res.complete) res.readable = true;
      callback();
    };
    if (!abortRequest) {
      res.on('end', common.mustCall(() => {
        reqCountdown.dec();
      }));
    } else {
      res.on('aborted', common.mustCall(() => {
        aborted = true;
        reqCountdown.dec();
        writable.end();
      }));
    }

    res.on('error', common.mustNotCall());
    writable.on('finish', () => {
      assert.strictEqual(aborted, abortRequest);
      finishCountdown.dec();
      if (finishCountdown.remaining === 0) return;
      abortRequest = false; // Next one should be a good response
      download();
    });
  });
  req.end();
}