1'use strict';
2
3const common = require('../common');
4const assert = require('assert');
5const { createServer } = require('http');
6const { connect } = require('net');
7
8// This test validates that request are correct checked for both requests and headers timeout in various situations.
9
10const requestBodyPart1 = 'POST / HTTP/1.1\r\nContent-Length: 20\r\n';
11const requestBodyPart2 = 'Connection: close\r\n\r\n1234567890';
12const requestBodyPart3 = '1234567890';
13
14const responseOk = 'HTTP/1.1 200 OK\r\n';
15const responseTimeout = 'HTTP/1.1 408 Request Timeout\r\n';
16
17const headersTimeout = common.platformTimeout(2000);
18const connectionsCheckingInterval = headersTimeout / 8;
19
20const server = createServer({
21  headersTimeout,
22  requestTimeout: headersTimeout * 2,
23  keepAliveTimeout: 0,
24  connectionsCheckingInterval
25}, common.mustCall((req, res) => {
26  req.resume();
27
28  req.on('end', () => {
29    res.writeHead(200, { 'Content-Type': 'text/plain' });
30    res.end();
31  });
32}, 4));
33
34assert.strictEqual(server.headersTimeout, headersTimeout);
35assert.strictEqual(server.requestTimeout, headersTimeout * 2);
36
37let i = 0;
38function createClient(server) {
39  const request = {
40    index: i++,
41    client: connect(server.address().port),
42    response: '',
43    completed: false
44  };
45
46  request.client.setEncoding('utf8');
47  request.client.on('data', common.mustCallAtLeast((chunk) => {
48    request.response += chunk;
49  }));
50
51  request.client.on('end', common.mustCall(() => {
52    request.completed = true;
53  }));
54
55  request.client.on('error', common.mustNotCall());
56
57  request.client.resume();
58
59  return request;
60}
61
62server.listen(0, common.mustCall(() => {
63  const request1 = createClient(server);
64  let request2;
65  let request3;
66  let request4;
67  let request5;
68
69  // Send the first request and stop before the body
70  request1.client.write(requestBodyPart1);
71
72  // After a little while send two new requests
73  setTimeout(() => {
74    request2 = createClient(server);
75    request3 = createClient(server);
76
77    // Send the second request, stop in the middle of the headers
78    request2.client.write(requestBodyPart1);
79
80    // Send the third request and stop in the middle of the headers
81    request3.client.write(requestBodyPart1);
82  }, headersTimeout * 0.2);
83
84  // After another little while send the last two new requests
85  setTimeout(() => {
86    request4 = createClient(server);
87    request5 = createClient(server);
88
89    // Send the fourth request, stop in the middle of the headers
90    request4.client.write(requestBodyPart1);
91    // Send the fifth request, stop in the middle of the headers
92    request5.client.write(requestBodyPart1);
93  }, headersTimeout * 0.6);
94
95  setTimeout(() => {
96    // Finish the first request
97    request1.client.write(requestBodyPart2 + requestBodyPart3);
98
99    // Complete headers for all requests but second
100    request3.client.write(requestBodyPart2);
101    request4.client.write(requestBodyPart2);
102    request5.client.write(requestBodyPart2);
103  }, headersTimeout * 0.8);
104
105  setTimeout(() => {
106    // After the first timeout, the first request should have been completed and second timedout
107    assert(request1.completed);
108    assert(request2.completed);
109    assert(!request3.completed);
110    assert(!request4.completed);
111    assert(!request5.completed);
112
113    assert(request1.response.startsWith(responseOk));
114    assert(request2.response.startsWith(responseTimeout)); // It is expired due to headersTimeout
115  }, headersTimeout * 1.4);
116
117  setTimeout(() => {
118    // Complete the body for the fourth request
119    request4.client.write(requestBodyPart3);
120  }, headersTimeout * 1.5);
121
122  setTimeout(() => {
123    // All request should be completed now, either with 200 or 408
124    assert(request3.completed);
125    assert(request4.completed);
126    assert(request5.completed);
127
128    assert(request3.response.startsWith(responseTimeout)); // It is expired due to requestTimeout
129    assert(request4.response.startsWith(responseOk));
130    assert(request5.response.startsWith(responseTimeout)); // It is expired due to requestTimeout
131    server.close();
132  }, headersTimeout * 3 + connectionsCheckingInterval);
133}));
134