11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst http = require('http');
51cb0ef41Sopenharmony_ciconst assert = require('assert');
61cb0ef41Sopenharmony_ciconst { Writable } = require('stream');
71cb0ef41Sopenharmony_ciconst Countdown = require('../common/countdown');
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_ciconst N = 2;
101cb0ef41Sopenharmony_cilet abortRequest = true;
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciconst server = http.Server(common.mustCall((req, res) => {
131cb0ef41Sopenharmony_ci  const headers = { 'Content-Type': 'text/plain' };
141cb0ef41Sopenharmony_ci  headers['Content-Length'] = 50;
151cb0ef41Sopenharmony_ci  const socket = res.socket;
161cb0ef41Sopenharmony_ci  res.writeHead(200, headers);
171cb0ef41Sopenharmony_ci  res.write('aaaaaaaaaabbbbbbbbbbccccccccccdddddddddd');
181cb0ef41Sopenharmony_ci  if (abortRequest) {
191cb0ef41Sopenharmony_ci    process.nextTick(() => socket.destroy());
201cb0ef41Sopenharmony_ci  } else {
211cb0ef41Sopenharmony_ci    process.nextTick(() => res.end('eeeeeeeeee'));
221cb0ef41Sopenharmony_ci  }
231cb0ef41Sopenharmony_ci}, N));
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => {
261cb0ef41Sopenharmony_ci  download();
271cb0ef41Sopenharmony_ci}));
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ciconst finishCountdown = new Countdown(N, common.mustCall(() => {
301cb0ef41Sopenharmony_ci  server.close();
311cb0ef41Sopenharmony_ci}));
321cb0ef41Sopenharmony_ciconst reqCountdown = new Countdown(N, common.mustCall());
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cifunction download() {
351cb0ef41Sopenharmony_ci  const opts = {
361cb0ef41Sopenharmony_ci    port: server.address().port,
371cb0ef41Sopenharmony_ci    path: '/',
381cb0ef41Sopenharmony_ci  };
391cb0ef41Sopenharmony_ci  const req = http.get(opts);
401cb0ef41Sopenharmony_ci  req.on('error', common.mustNotCall());
411cb0ef41Sopenharmony_ci  req.on('response', (res) => {
421cb0ef41Sopenharmony_ci    assert.strictEqual(res.statusCode, 200);
431cb0ef41Sopenharmony_ci    assert.strictEqual(res.headers.connection, 'close');
441cb0ef41Sopenharmony_ci    let aborted = false;
451cb0ef41Sopenharmony_ci    const writable = new Writable({
461cb0ef41Sopenharmony_ci      write(chunk, encoding, callback) {
471cb0ef41Sopenharmony_ci        callback();
481cb0ef41Sopenharmony_ci      }
491cb0ef41Sopenharmony_ci    });
501cb0ef41Sopenharmony_ci    res.pipe(writable);
511cb0ef41Sopenharmony_ci    const _handle = res.socket._handle;
521cb0ef41Sopenharmony_ci    _handle._close = res.socket._handle.close;
531cb0ef41Sopenharmony_ci    _handle.close = function(callback) {
541cb0ef41Sopenharmony_ci      _handle._close();
551cb0ef41Sopenharmony_ci      // Set readable to true even though request is complete
561cb0ef41Sopenharmony_ci      if (res.complete) res.readable = true;
571cb0ef41Sopenharmony_ci      callback();
581cb0ef41Sopenharmony_ci    };
591cb0ef41Sopenharmony_ci    if (!abortRequest) {
601cb0ef41Sopenharmony_ci      res.on('end', common.mustCall(() => {
611cb0ef41Sopenharmony_ci        reqCountdown.dec();
621cb0ef41Sopenharmony_ci      }));
631cb0ef41Sopenharmony_ci      res.on('error', common.mustNotCall());
641cb0ef41Sopenharmony_ci    } else {
651cb0ef41Sopenharmony_ci      res.on('aborted', common.mustCall(() => {
661cb0ef41Sopenharmony_ci        aborted = true;
671cb0ef41Sopenharmony_ci        reqCountdown.dec();
681cb0ef41Sopenharmony_ci        writable.end();
691cb0ef41Sopenharmony_ci      }));
701cb0ef41Sopenharmony_ci      res.on('error', common.expectsError({
711cb0ef41Sopenharmony_ci        code: 'ECONNRESET'
721cb0ef41Sopenharmony_ci      }));
731cb0ef41Sopenharmony_ci    }
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci    writable.on('finish', () => {
761cb0ef41Sopenharmony_ci      assert.strictEqual(aborted, abortRequest);
771cb0ef41Sopenharmony_ci      finishCountdown.dec();
781cb0ef41Sopenharmony_ci      if (finishCountdown.remaining === 0) return;
791cb0ef41Sopenharmony_ci      abortRequest = false; // Next one should be a good response
801cb0ef41Sopenharmony_ci      download();
811cb0ef41Sopenharmony_ci    });
821cb0ef41Sopenharmony_ci  });
831cb0ef41Sopenharmony_ci  req.end();
841cb0ef41Sopenharmony_ci}
85