summaryrefslogtreecommitdiff
path: root/test/parallel/test-http-sync-write-error-during-continue.js
blob: f77026b00b513104f9468cec2e1845499a6b6b8f (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
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
const MakeDuplexPair = require('../common/duplexpair');

// Regression test for the crash reported in
// https://github.com/nodejs/node/issues/15102 (httpParser.finish() is called
// during httpParser.execute()):

{
  const { clientSide, serverSide } = MakeDuplexPair();

  serverSide.on('data', common.mustCall((data) => {
    assert.strictEqual(data.toString('utf8'), `\
GET / HTTP/1.1
Expect: 100-continue
Host: localhost:80
Connection: close

`.replace(/\n/g, '\r\n'));

    setImmediate(() => {
      serverSide.write('HTTP/1.1 100 Continue\r\n\r\n');
    });
  }));

  const req = http.request({
    createConnection: common.mustCall(() => clientSide),
    headers: {
      'Expect': '100-continue'
    }
  });
  req.on('continue', common.mustCall((res) => {
    let sync = true;

    clientSide._writev = null;
    clientSide._write = common.mustCall((chunk, enc, cb) => {
      assert(sync);
      // On affected versions of Node.js, the error would be emitted on `req`
      // synchronously (i.e. before commit f663b31cc2aec), which would cause
      // parser.finish() to be called while we are here in the 'continue'
      // callback, which is inside a parser.execute() call.

      assert.strictEqual(chunk.length, 4);
      clientSide.destroy(new Error('sometimes the code just doesn’t work'), cb);
    });
    req.on('error', common.mustCall());
    req.end('data');

    sync = false;
  }));
}