11cb0ef41Sopenharmony_ci'use strict';
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciconst common = require('../common');
41cb0ef41Sopenharmony_ciconst assert = require('assert');
51cb0ef41Sopenharmony_ciconst { createServer } = require('http');
61cb0ef41Sopenharmony_ciconst { connect } = require('net');
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci// This test validates that request are correct checked for both requests and headers timeout in various situations.
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ciconst requestBodyPart1 = 'POST / HTTP/1.1\r\nContent-Length: 20\r\n';
111cb0ef41Sopenharmony_ciconst requestBodyPart2 = 'Connection: close\r\n\r\n1234567890';
121cb0ef41Sopenharmony_ciconst requestBodyPart3 = '1234567890';
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ciconst responseOk = 'HTTP/1.1 200 OK\r\n';
151cb0ef41Sopenharmony_ciconst responseTimeout = 'HTTP/1.1 408 Request Timeout\r\n';
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ciconst headersTimeout = common.platformTimeout(2000);
181cb0ef41Sopenharmony_ciconst connectionsCheckingInterval = headersTimeout / 8;
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ciconst server = createServer({
211cb0ef41Sopenharmony_ci  headersTimeout,
221cb0ef41Sopenharmony_ci  requestTimeout: headersTimeout * 2,
231cb0ef41Sopenharmony_ci  keepAliveTimeout: 0,
241cb0ef41Sopenharmony_ci  connectionsCheckingInterval
251cb0ef41Sopenharmony_ci}, common.mustCall((req, res) => {
261cb0ef41Sopenharmony_ci  req.resume();
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  req.on('end', () => {
291cb0ef41Sopenharmony_ci    res.writeHead(200, { 'Content-Type': 'text/plain' });
301cb0ef41Sopenharmony_ci    res.end();
311cb0ef41Sopenharmony_ci  });
321cb0ef41Sopenharmony_ci}, 4));
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ciassert.strictEqual(server.headersTimeout, headersTimeout);
351cb0ef41Sopenharmony_ciassert.strictEqual(server.requestTimeout, headersTimeout * 2);
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_cilet i = 0;
381cb0ef41Sopenharmony_cifunction createClient(server) {
391cb0ef41Sopenharmony_ci  const request = {
401cb0ef41Sopenharmony_ci    index: i++,
411cb0ef41Sopenharmony_ci    client: connect(server.address().port),
421cb0ef41Sopenharmony_ci    response: '',
431cb0ef41Sopenharmony_ci    completed: false
441cb0ef41Sopenharmony_ci  };
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  request.client.setEncoding('utf8');
471cb0ef41Sopenharmony_ci  request.client.on('data', common.mustCallAtLeast((chunk) => {
481cb0ef41Sopenharmony_ci    request.response += chunk;
491cb0ef41Sopenharmony_ci  }));
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  request.client.on('end', common.mustCall(() => {
521cb0ef41Sopenharmony_ci    request.completed = true;
531cb0ef41Sopenharmony_ci  }));
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  request.client.on('error', common.mustNotCall());
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  request.client.resume();
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ci  return request;
601cb0ef41Sopenharmony_ci}
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ciserver.listen(0, common.mustCall(() => {
631cb0ef41Sopenharmony_ci  const request1 = createClient(server);
641cb0ef41Sopenharmony_ci  let request2;
651cb0ef41Sopenharmony_ci  let request3;
661cb0ef41Sopenharmony_ci  let request4;
671cb0ef41Sopenharmony_ci  let request5;
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci  // Send the first request and stop before the body
701cb0ef41Sopenharmony_ci  request1.client.write(requestBodyPart1);
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci  // After a little while send two new requests
731cb0ef41Sopenharmony_ci  setTimeout(() => {
741cb0ef41Sopenharmony_ci    request2 = createClient(server);
751cb0ef41Sopenharmony_ci    request3 = createClient(server);
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci    // Send the second request, stop in the middle of the headers
781cb0ef41Sopenharmony_ci    request2.client.write(requestBodyPart1);
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci    // Send the third request and stop in the middle of the headers
811cb0ef41Sopenharmony_ci    request3.client.write(requestBodyPart1);
821cb0ef41Sopenharmony_ci  }, headersTimeout * 0.2);
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  // After another little while send the last two new requests
851cb0ef41Sopenharmony_ci  setTimeout(() => {
861cb0ef41Sopenharmony_ci    request4 = createClient(server);
871cb0ef41Sopenharmony_ci    request5 = createClient(server);
881cb0ef41Sopenharmony_ci
891cb0ef41Sopenharmony_ci    // Send the fourth request, stop in the middle of the headers
901cb0ef41Sopenharmony_ci    request4.client.write(requestBodyPart1);
911cb0ef41Sopenharmony_ci    // Send the fifth request, stop in the middle of the headers
921cb0ef41Sopenharmony_ci    request5.client.write(requestBodyPart1);
931cb0ef41Sopenharmony_ci  }, headersTimeout * 0.6);
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  setTimeout(() => {
961cb0ef41Sopenharmony_ci    // Finish the first request
971cb0ef41Sopenharmony_ci    request1.client.write(requestBodyPart2 + requestBodyPart3);
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci    // Complete headers for all requests but second
1001cb0ef41Sopenharmony_ci    request3.client.write(requestBodyPart2);
1011cb0ef41Sopenharmony_ci    request4.client.write(requestBodyPart2);
1021cb0ef41Sopenharmony_ci    request5.client.write(requestBodyPart2);
1031cb0ef41Sopenharmony_ci  }, headersTimeout * 0.8);
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  setTimeout(() => {
1061cb0ef41Sopenharmony_ci    // After the first timeout, the first request should have been completed and second timedout
1071cb0ef41Sopenharmony_ci    assert(request1.completed);
1081cb0ef41Sopenharmony_ci    assert(request2.completed);
1091cb0ef41Sopenharmony_ci    assert(!request3.completed);
1101cb0ef41Sopenharmony_ci    assert(!request4.completed);
1111cb0ef41Sopenharmony_ci    assert(!request5.completed);
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci    assert(request1.response.startsWith(responseOk));
1141cb0ef41Sopenharmony_ci    assert(request2.response.startsWith(responseTimeout)); // It is expired due to headersTimeout
1151cb0ef41Sopenharmony_ci  }, headersTimeout * 1.4);
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci  setTimeout(() => {
1181cb0ef41Sopenharmony_ci    // Complete the body for the fourth request
1191cb0ef41Sopenharmony_ci    request4.client.write(requestBodyPart3);
1201cb0ef41Sopenharmony_ci  }, headersTimeout * 1.5);
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ci  setTimeout(() => {
1231cb0ef41Sopenharmony_ci    // All request should be completed now, either with 200 or 408
1241cb0ef41Sopenharmony_ci    assert(request3.completed);
1251cb0ef41Sopenharmony_ci    assert(request4.completed);
1261cb0ef41Sopenharmony_ci    assert(request5.completed);
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ci    assert(request3.response.startsWith(responseTimeout)); // It is expired due to requestTimeout
1291cb0ef41Sopenharmony_ci    assert(request4.response.startsWith(responseOk));
1301cb0ef41Sopenharmony_ci    assert(request5.response.startsWith(responseTimeout)); // It is expired due to requestTimeout
1311cb0ef41Sopenharmony_ci    server.close();
1321cb0ef41Sopenharmony_ci  }, headersTimeout * 3 + connectionsCheckingInterval);
1331cb0ef41Sopenharmony_ci}));
134