11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci// Run this program with valgrind or efence with --expose_gc to expose the
31cb0ef41Sopenharmony_ci// problem.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci// Flags: --expose_gc
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cirequire('../common');
81cb0ef41Sopenharmony_ciconst assert = require('assert');
91cb0ef41Sopenharmony_ciconst { HTTPParser } = require('_http_common');
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ciconst kOnHeaders = HTTPParser.kOnHeaders | 0;
121cb0ef41Sopenharmony_ciconst kOnHeadersComplete = HTTPParser.kOnHeadersComplete | 0;
131cb0ef41Sopenharmony_ciconst kOnBody = HTTPParser.kOnBody | 0;
141cb0ef41Sopenharmony_ciconst kOnMessageComplete = HTTPParser.kOnMessageComplete | 0;
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_cilet headersComplete = 0;
171cb0ef41Sopenharmony_cilet messagesComplete = 0;
181cb0ef41Sopenharmony_ci
191cb0ef41Sopenharmony_cifunction flushPool() {
201cb0ef41Sopenharmony_ci  Buffer.allocUnsafe(Buffer.poolSize - 1);
211cb0ef41Sopenharmony_ci  global.gc();
221cb0ef41Sopenharmony_ci}
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_cifunction demoBug(part1, part2) {
251cb0ef41Sopenharmony_ci  flushPool();
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci  const parser = new HTTPParser();
281cb0ef41Sopenharmony_ci  parser.initialize(HTTPParser.REQUEST, {});
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  parser.headers = [];
311cb0ef41Sopenharmony_ci  parser.url = '';
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci  parser[kOnHeaders] = function(headers, url) {
341cb0ef41Sopenharmony_ci    parser.headers = parser.headers.concat(headers);
351cb0ef41Sopenharmony_ci    parser.url += url;
361cb0ef41Sopenharmony_ci  };
371cb0ef41Sopenharmony_ci
381cb0ef41Sopenharmony_ci  parser[kOnHeadersComplete] = function(info) {
391cb0ef41Sopenharmony_ci    headersComplete++;
401cb0ef41Sopenharmony_ci    console.log('url', info.url);
411cb0ef41Sopenharmony_ci  };
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  parser[kOnBody] = () => {};
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci  parser[kOnMessageComplete] = function() {
461cb0ef41Sopenharmony_ci    messagesComplete++;
471cb0ef41Sopenharmony_ci  };
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  // We use a function to eliminate references to the Buffer b
511cb0ef41Sopenharmony_ci  // We want b to be GCed. The parser will hold a bad reference to it.
521cb0ef41Sopenharmony_ci  (function() {
531cb0ef41Sopenharmony_ci    const b = Buffer.from(part1);
541cb0ef41Sopenharmony_ci    flushPool();
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_ci    console.log('parse the first part of the message');
571cb0ef41Sopenharmony_ci    parser.execute(b, 0, b.length);
581cb0ef41Sopenharmony_ci  })();
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci  flushPool();
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  (function() {
631cb0ef41Sopenharmony_ci    const b = Buffer.from(part2);
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_ci    console.log('parse the second part of the message');
661cb0ef41Sopenharmony_ci    parser.execute(b, 0, b.length);
671cb0ef41Sopenharmony_ci    parser.finish();
681cb0ef41Sopenharmony_ci  })();
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  flushPool();
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_cidemoBug('POST /1', '/22 HTTP/1.1\r\n' +
751cb0ef41Sopenharmony_ci        'Content-Type: text/plain\r\n' +
761cb0ef41Sopenharmony_ci        'Content-Length: 4\r\n\r\n' +
771cb0ef41Sopenharmony_ci        'pong');
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cidemoBug('POST /1/22 HTTP/1.1\r\n' +
801cb0ef41Sopenharmony_ci        'Content-Type: tex', 't/plain\r\n' +
811cb0ef41Sopenharmony_ci        'Content-Length: 4\r\n\r\n' +
821cb0ef41Sopenharmony_ci        'pong');
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciprocess.on('exit', function() {
851cb0ef41Sopenharmony_ci  assert.strictEqual(headersComplete, 2);
861cb0ef41Sopenharmony_ci  assert.strictEqual(messagesComplete, 2);
871cb0ef41Sopenharmony_ci  console.log('done!');
881cb0ef41Sopenharmony_ci});
89