1// Copyright Joyent, Inc. and other Node contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the
5// "Software"), to deal in the Software without restriction, including
6// without limitation the rights to use, copy, modify, merge, publish,
7// distribute, sublicense, and/or sell copies of the Software, and to permit
8// persons to whom the Software is furnished to do so, subject to the
9// following conditions:
10//
11// The above copyright notice and this permission notice shall be included
12// in all copies or substantial portions of the Software.
13//
14// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22'use strict';
23
24const {
25  ArrayIsArray,
26  Error,
27  MathMin,
28  ObjectKeys,
29  ObjectSetPrototypeOf,
30  RegExpPrototypeExec,
31  ReflectApply,
32  Symbol,
33  SymbolFor,
34} = primordials;
35
36const net = require('net');
37const EE = require('events');
38const assert = require('internal/assert');
39const {
40  parsers,
41  freeParser,
42  continueExpression,
43  chunkExpression,
44  kIncomingMessage,
45  HTTPParser,
46  isLenient,
47  _checkInvalidHeaderChar: checkInvalidHeaderChar,
48  prepareError,
49} = require('_http_common');
50const { ConnectionsList } = internalBinding('http_parser');
51const {
52  kUniqueHeaders,
53  parseUniqueHeadersOption,
54  OutgoingMessage,
55} = require('_http_outgoing');
56const {
57  kOutHeaders,
58  kNeedDrain,
59  isTraceHTTPEnabled,
60  traceBegin,
61  traceEnd,
62  getNextTraceEventId,
63} = require('internal/http');
64const {
65  defaultTriggerAsyncIdScope,
66  getOrSetAsyncId,
67} = require('internal/async_hooks');
68const { IncomingMessage } = require('_http_incoming');
69const {
70  connResetException,
71  codes,
72} = require('internal/errors');
73const {
74  ERR_HTTP_REQUEST_TIMEOUT,
75  ERR_HTTP_HEADERS_SENT,
76  ERR_HTTP_INVALID_STATUS_CODE,
77  ERR_HTTP_SOCKET_ENCODING,
78  ERR_INVALID_ARG_TYPE,
79  ERR_HTTP_SOCKET_ASSIGNED,
80  ERR_INVALID_ARG_VALUE,
81  ERR_INVALID_CHAR,
82} = codes;
83const {
84  validateInteger,
85  validateBoolean,
86  validateLinkHeaderValue,
87  validateObject,
88} = require('internal/validators');
89const Buffer = require('buffer').Buffer;
90const {
91  DTRACE_HTTP_SERVER_REQUEST,
92  DTRACE_HTTP_SERVER_RESPONSE,
93} = require('internal/dtrace');
94const { setInterval, clearInterval } = require('timers');
95let debug = require('internal/util/debuglog').debuglog('http', (fn) => {
96  debug = fn;
97});
98
99const dc = require('diagnostics_channel');
100const onRequestStartChannel = dc.channel('http.server.request.start');
101const onResponseFinishChannel = dc.channel('http.server.response.finish');
102
103const kServerResponse = Symbol('ServerResponse');
104const kServerResponseStatistics = Symbol('ServerResponseStatistics');
105
106const {
107  hasObserver,
108  startPerf,
109  stopPerf,
110} = require('internal/perf/observe');
111
112const STATUS_CODES = {
113  100: 'Continue',                   // RFC 7231 6.2.1
114  101: 'Switching Protocols',        // RFC 7231 6.2.2
115  102: 'Processing',                 // RFC 2518 10.1 (obsoleted by RFC 4918)
116  103: 'Early Hints',                // RFC 8297 2
117  200: 'OK',                         // RFC 7231 6.3.1
118  201: 'Created',                    // RFC 7231 6.3.2
119  202: 'Accepted',                   // RFC 7231 6.3.3
120  203: 'Non-Authoritative Information', // RFC 7231 6.3.4
121  204: 'No Content',                 // RFC 7231 6.3.5
122  205: 'Reset Content',              // RFC 7231 6.3.6
123  206: 'Partial Content',            // RFC 7233 4.1
124  207: 'Multi-Status',               // RFC 4918 11.1
125  208: 'Already Reported',           // RFC 5842 7.1
126  226: 'IM Used',                    // RFC 3229 10.4.1
127  300: 'Multiple Choices',           // RFC 7231 6.4.1
128  301: 'Moved Permanently',          // RFC 7231 6.4.2
129  302: 'Found',                      // RFC 7231 6.4.3
130  303: 'See Other',                  // RFC 7231 6.4.4
131  304: 'Not Modified',               // RFC 7232 4.1
132  305: 'Use Proxy',                  // RFC 7231 6.4.5
133  307: 'Temporary Redirect',         // RFC 7231 6.4.7
134  308: 'Permanent Redirect',         // RFC 7238 3
135  400: 'Bad Request',                // RFC 7231 6.5.1
136  401: 'Unauthorized',               // RFC 7235 3.1
137  402: 'Payment Required',           // RFC 7231 6.5.2
138  403: 'Forbidden',                  // RFC 7231 6.5.3
139  404: 'Not Found',                  // RFC 7231 6.5.4
140  405: 'Method Not Allowed',         // RFC 7231 6.5.5
141  406: 'Not Acceptable',             // RFC 7231 6.5.6
142  407: 'Proxy Authentication Required', // RFC 7235 3.2
143  408: 'Request Timeout',            // RFC 7231 6.5.7
144  409: 'Conflict',                   // RFC 7231 6.5.8
145  410: 'Gone',                       // RFC 7231 6.5.9
146  411: 'Length Required',            // RFC 7231 6.5.10
147  412: 'Precondition Failed',        // RFC 7232 4.2
148  413: 'Payload Too Large',          // RFC 7231 6.5.11
149  414: 'URI Too Long',               // RFC 7231 6.5.12
150  415: 'Unsupported Media Type',     // RFC 7231 6.5.13
151  416: 'Range Not Satisfiable',      // RFC 7233 4.4
152  417: 'Expectation Failed',         // RFC 7231 6.5.14
153  418: 'I\'m a Teapot',              // RFC 7168 2.3.3
154  421: 'Misdirected Request',        // RFC 7540 9.1.2
155  422: 'Unprocessable Entity',       // RFC 4918 11.2
156  423: 'Locked',                     // RFC 4918 11.3
157  424: 'Failed Dependency',          // RFC 4918 11.4
158  425: 'Too Early',                  // RFC 8470 5.2
159  426: 'Upgrade Required',           // RFC 2817 and RFC 7231 6.5.15
160  428: 'Precondition Required',      // RFC 6585 3
161  429: 'Too Many Requests',          // RFC 6585 4
162  431: 'Request Header Fields Too Large', // RFC 6585 5
163  451: 'Unavailable For Legal Reasons', // RFC 7725 3
164  500: 'Internal Server Error',      // RFC 7231 6.6.1
165  501: 'Not Implemented',            // RFC 7231 6.6.2
166  502: 'Bad Gateway',                // RFC 7231 6.6.3
167  503: 'Service Unavailable',        // RFC 7231 6.6.4
168  504: 'Gateway Timeout',            // RFC 7231 6.6.5
169  505: 'HTTP Version Not Supported', // RFC 7231 6.6.6
170  506: 'Variant Also Negotiates',    // RFC 2295 8.1
171  507: 'Insufficient Storage',       // RFC 4918 11.5
172  508: 'Loop Detected',              // RFC 5842 7.2
173  509: 'Bandwidth Limit Exceeded',
174  510: 'Not Extended',               // RFC 2774 7
175  511: 'Network Authentication Required', // RFC 6585 6
176};
177
178const kOnExecute = HTTPParser.kOnExecute | 0;
179const kOnTimeout = HTTPParser.kOnTimeout | 0;
180const kLenientAll = HTTPParser.kLenientAll | 0;
181const kLenientNone = HTTPParser.kLenientNone | 0;
182const kConnections = Symbol('http.server.connections');
183const kConnectionsCheckingInterval = Symbol('http.server.connectionsCheckingInterval');
184
185const HTTP_SERVER_TRACE_EVENT_NAME = 'http.server.request';
186
187class HTTPServerAsyncResource {
188  constructor(type, socket) {
189    this.type = type;
190    this.socket = socket;
191  }
192}
193
194function ServerResponse(req, options) {
195  OutgoingMessage.call(this, options);
196
197  if (req.method === 'HEAD') this._hasBody = false;
198
199  this.req = req;
200  this.sendDate = true;
201  this._sent100 = false;
202  this._expect_continue = false;
203
204  if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
205    this.useChunkedEncodingByDefault = RegExpPrototypeExec(chunkExpression,
206                                                           req.headers.te) !== null;
207    this.shouldKeepAlive = false;
208  }
209
210  if (hasObserver('http')) {
211    startPerf(this, kServerResponseStatistics, {
212      type: 'http',
213      name: 'HttpRequest',
214      detail: {
215        req: {
216          method: req.method,
217          url: req.url,
218          headers: req.headers,
219        },
220      },
221    });
222  }
223  if (isTraceHTTPEnabled()) {
224    this._traceEventId = getNextTraceEventId();
225    traceBegin(HTTP_SERVER_TRACE_EVENT_NAME, this._traceEventId);
226  }
227}
228ObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype);
229ObjectSetPrototypeOf(ServerResponse, OutgoingMessage);
230
231ServerResponse.prototype._finish = function _finish() {
232  DTRACE_HTTP_SERVER_RESPONSE(this.socket);
233  if (this[kServerResponseStatistics] && hasObserver('http')) {
234    stopPerf(this, kServerResponseStatistics, {
235      detail: {
236        res: {
237          statusCode: this.statusCode,
238          statusMessage: this.statusMessage,
239          headers: typeof this.getHeaders === 'function' ? this.getHeaders() : {},
240        },
241      },
242    });
243  }
244  OutgoingMessage.prototype._finish.call(this);
245  if (isTraceHTTPEnabled() && typeof this._traceEventId === 'number') {
246    const data = {
247      url: this.req?.url,
248      statusCode: this.statusCode,
249    };
250    traceEnd(HTTP_SERVER_TRACE_EVENT_NAME, this._traceEventId, data);
251  }
252};
253
254
255ServerResponse.prototype.statusCode = 200;
256ServerResponse.prototype.statusMessage = undefined;
257
258function onServerResponseClose() {
259  // EventEmitter.emit makes a copy of the 'close' listeners array before
260  // calling the listeners. detachSocket() unregisters onServerResponseClose
261  // but if detachSocket() is called, directly or indirectly, by a 'close'
262  // listener, onServerResponseClose is still in that copy of the listeners
263  // array. That is, in the example below, b still gets called even though
264  // it's been removed by a:
265  //
266  //   const EventEmitter = require('events');
267  //   const obj = new EventEmitter();
268  //   obj.on('event', a);
269  //   obj.on('event', b);
270  //   function a() { obj.removeListener('event', b) }
271  //   function b() { throw "BAM!" }
272  //   obj.emit('event');  // throws
273  //
274  // Ergo, we need to deal with stale 'close' events and handle the case
275  // where the ServerResponse object has already been deconstructed.
276  // Fortunately, that requires only a single if check. :-)
277  if (this._httpMessage) {
278    emitCloseNT(this._httpMessage);
279  }
280}
281
282ServerResponse.prototype.assignSocket = function assignSocket(socket) {
283  if (socket._httpMessage) {
284    throw new ERR_HTTP_SOCKET_ASSIGNED();
285  }
286  socket._httpMessage = this;
287  socket.on('close', onServerResponseClose);
288  this.socket = socket;
289  this.emit('socket', socket);
290  this._flush();
291};
292
293ServerResponse.prototype.detachSocket = function detachSocket(socket) {
294  assert(socket._httpMessage === this);
295  socket.removeListener('close', onServerResponseClose);
296  socket._httpMessage = null;
297  this.socket = null;
298};
299
300ServerResponse.prototype.writeContinue = function writeContinue(cb) {
301  this._writeRaw('HTTP/1.1 100 Continue\r\n\r\n', 'ascii', cb);
302  this._sent100 = true;
303};
304
305ServerResponse.prototype.writeProcessing = function writeProcessing(cb) {
306  this._writeRaw('HTTP/1.1 102 Processing\r\n\r\n', 'ascii', cb);
307};
308
309ServerResponse.prototype.writeEarlyHints = function writeEarlyHints(hints, cb) {
310  let head = 'HTTP/1.1 103 Early Hints\r\n';
311
312  validateObject(hints, 'hints');
313
314  if (hints.link === null || hints.link === undefined) {
315    return;
316  }
317
318  const link = validateLinkHeaderValue(hints.link);
319
320  if (link.length === 0) {
321    return;
322  }
323
324  head += 'Link: ' + link + '\r\n';
325
326  for (const key of ObjectKeys(hints)) {
327    if (key !== 'link') {
328      head += key + ': ' + hints[key] + '\r\n';
329    }
330  }
331
332  head += '\r\n';
333
334  this._writeRaw(head, 'ascii', cb);
335};
336
337ServerResponse.prototype._implicitHeader = function _implicitHeader() {
338  this.writeHead(this.statusCode);
339};
340
341ServerResponse.prototype.writeHead = writeHead;
342function writeHead(statusCode, reason, obj) {
343  const originalStatusCode = statusCode;
344
345  statusCode |= 0;
346  if (statusCode < 100 || statusCode > 999) {
347    throw new ERR_HTTP_INVALID_STATUS_CODE(originalStatusCode);
348  }
349
350
351  if (typeof reason === 'string') {
352    // writeHead(statusCode, reasonPhrase[, headers])
353    this.statusMessage = reason;
354  } else {
355    // writeHead(statusCode[, headers])
356    if (!this.statusMessage)
357      this.statusMessage = STATUS_CODES[statusCode] || 'unknown';
358    obj ??= reason;
359  }
360  this.statusCode = statusCode;
361
362  let headers;
363  if (this[kOutHeaders]) {
364    // Slow-case: when progressive API and header fields are passed.
365    let k;
366    if (ArrayIsArray(obj)) {
367      if (obj.length % 2 !== 0) {
368        throw new ERR_INVALID_ARG_VALUE('headers', obj);
369      }
370
371      for (let n = 0; n < obj.length; n += 2) {
372        k = obj[n + 0];
373        if (k) this.setHeader(k, obj[n + 1]);
374      }
375    } else if (obj) {
376      const keys = ObjectKeys(obj);
377      // Retain for(;;) loop for performance reasons
378      // Refs: https://github.com/nodejs/node/pull/30958
379      for (let i = 0; i < keys.length; i++) {
380        k = keys[i];
381        if (k) this.setHeader(k, obj[k]);
382      }
383    }
384    if (k === undefined && this._header) {
385      throw new ERR_HTTP_HEADERS_SENT('render');
386    }
387    // Only progressive api is used
388    headers = this[kOutHeaders];
389  } else {
390    // Only writeHead() called
391    headers = obj;
392  }
393
394  if (checkInvalidHeaderChar(this.statusMessage))
395    throw new ERR_INVALID_CHAR('statusMessage');
396
397  const statusLine = `HTTP/1.1 ${statusCode} ${this.statusMessage}\r\n`;
398
399  if (statusCode === 204 || statusCode === 304 ||
400      (statusCode >= 100 && statusCode <= 199)) {
401    // RFC 2616, 10.2.5:
402    // The 204 response MUST NOT include a message-body, and thus is always
403    // terminated by the first empty line after the header fields.
404    // RFC 2616, 10.3.5:
405    // The 304 response MUST NOT contain a message-body, and thus is always
406    // terminated by the first empty line after the header fields.
407    // RFC 2616, 10.1 Informational 1xx:
408    // This class of status code indicates a provisional response,
409    // consisting only of the Status-Line and optional headers, and is
410    // terminated by an empty line.
411    this._hasBody = false;
412  }
413
414  // Don't keep alive connections where the client expects 100 Continue
415  // but we sent a final status; they may put extra bytes on the wire.
416  if (this._expect_continue && !this._sent100) {
417    this.shouldKeepAlive = false;
418  }
419
420  this._storeHeader(statusLine, headers);
421
422  return this;
423}
424
425// Docs-only deprecated: DEP0063
426ServerResponse.prototype.writeHeader = ServerResponse.prototype.writeHead;
427
428function storeHTTPOptions(options) {
429  this[kIncomingMessage] = options.IncomingMessage || IncomingMessage;
430  this[kServerResponse] = options.ServerResponse || ServerResponse;
431
432  const maxHeaderSize = options.maxHeaderSize;
433  if (maxHeaderSize !== undefined)
434    validateInteger(maxHeaderSize, 'maxHeaderSize', 0);
435  this.maxHeaderSize = maxHeaderSize;
436
437  const insecureHTTPParser = options.insecureHTTPParser;
438  if (insecureHTTPParser !== undefined)
439    validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');
440  this.insecureHTTPParser = insecureHTTPParser;
441
442  if (options.noDelay === undefined)
443    options.noDelay = true;
444
445  const requestTimeout = options.requestTimeout;
446  if (requestTimeout !== undefined) {
447    validateInteger(requestTimeout, 'requestTimeout', 0);
448    this.requestTimeout = requestTimeout;
449  } else {
450    this.requestTimeout = 300_000; // 5 minutes
451  }
452
453  const headersTimeout = options.headersTimeout;
454  if (headersTimeout !== undefined) {
455    validateInteger(headersTimeout, 'headersTimeout', 0);
456    this.headersTimeout = headersTimeout;
457  } else {
458    this.headersTimeout = MathMin(60_000, this.requestTimeout); // Minimum between 60 seconds or requestTimeout
459  }
460
461  if (this.requestTimeout > 0 && this.headersTimeout > 0 && this.headersTimeout > this.requestTimeout) {
462    throw new codes.ERR_OUT_OF_RANGE('headersTimeout', '<= requestTimeout', headersTimeout);
463  }
464
465  const keepAliveTimeout = options.keepAliveTimeout;
466  if (keepAliveTimeout !== undefined) {
467    validateInteger(keepAliveTimeout, 'keepAliveTimeout', 0);
468    this.keepAliveTimeout = keepAliveTimeout;
469  } else {
470    this.keepAliveTimeout = 5_000; // 5 seconds;
471  }
472
473  const connectionsCheckingInterval = options.connectionsCheckingInterval;
474  if (connectionsCheckingInterval !== undefined) {
475    validateInteger(connectionsCheckingInterval, 'connectionsCheckingInterval', 0);
476    this.connectionsCheckingInterval = connectionsCheckingInterval;
477  } else {
478    this.connectionsCheckingInterval = 30_000; // 30 seconds
479  }
480
481  const joinDuplicateHeaders = options.joinDuplicateHeaders;
482  if (joinDuplicateHeaders !== undefined) {
483    validateBoolean(joinDuplicateHeaders, 'options.joinDuplicateHeaders');
484  }
485  this.joinDuplicateHeaders = joinDuplicateHeaders;
486
487  const rejectNonStandardBodyWrites = options.rejectNonStandardBodyWrites;
488  if (rejectNonStandardBodyWrites !== undefined) {
489    validateBoolean(rejectNonStandardBodyWrites, 'options.rejectNonStandardBodyWrites');
490    this.rejectNonStandardBodyWrites = rejectNonStandardBodyWrites;
491  } else {
492    this.rejectNonStandardBodyWrites = false;
493  }
494}
495
496function setupConnectionsTracking() {
497  // Start connection handling
498  if (!this[kConnections]) {
499    this[kConnections] = new ConnectionsList();
500  }
501
502  // This checker is started without checking whether any headersTimeout or requestTimeout is non zero
503  // otherwise it would not be started if such timeouts are modified after createServer.
504  this[kConnectionsCheckingInterval] =
505    setInterval(checkConnections.bind(this), this.connectionsCheckingInterval).unref();
506}
507
508function httpServerPreClose(server) {
509  server.closeIdleConnections();
510  clearInterval(server[kConnectionsCheckingInterval]);
511}
512
513function Server(options, requestListener) {
514  if (!(this instanceof Server)) return new Server(options, requestListener);
515
516  if (typeof options === 'function') {
517    requestListener = options;
518    options = {};
519  } else if (options == null || typeof options === 'object') {
520    options = { ...options };
521  } else {
522    throw new ERR_INVALID_ARG_TYPE('options', 'object', options);
523  }
524
525  storeHTTPOptions.call(this, options);
526  net.Server.call(
527    this,
528    { allowHalfOpen: true, noDelay: options.noDelay,
529      keepAlive: options.keepAlive,
530      keepAliveInitialDelay: options.keepAliveInitialDelay,
531      highWaterMark: options.highWaterMark });
532
533  if (requestListener) {
534    this.on('request', requestListener);
535  }
536
537  // Similar option to this. Too lazy to write my own docs.
538  // http://www.squid-cache.org/Doc/config/half_closed_clients/
539  // https://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
540  this.httpAllowHalfOpen = false;
541
542  this.on('connection', connectionListener);
543  this.on('listening', setupConnectionsTracking);
544
545  this.timeout = 0;
546  this.maxHeadersCount = null;
547  this.maxRequestsPerSocket = 0;
548
549  this[kUniqueHeaders] = parseUniqueHeadersOption(options.uniqueHeaders);
550}
551ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
552ObjectSetPrototypeOf(Server, net.Server);
553
554Server.prototype.close = function() {
555  httpServerPreClose(this);
556  ReflectApply(net.Server.prototype.close, this, arguments);
557};
558
559Server.prototype.closeAllConnections = function() {
560  if (!this[kConnections]) {
561    return;
562  }
563
564  const connections = this[kConnections].all();
565
566  for (let i = 0, l = connections.length; i < l; i++) {
567    connections[i].socket.destroy();
568  }
569};
570
571Server.prototype.closeIdleConnections = function() {
572  if (!this[kConnections]) {
573    return;
574  }
575
576  const connections = this[kConnections].idle();
577
578  for (let i = 0, l = connections.length; i < l; i++) {
579    if (connections[i].socket._httpMessage && !connections[i].socket._httpMessage.finished) {
580      continue;
581    }
582
583    connections[i].socket.destroy();
584  }
585};
586
587Server.prototype.setTimeout = function setTimeout(msecs, callback) {
588  this.timeout = msecs;
589  if (callback)
590    this.on('timeout', callback);
591  return this;
592};
593
594Server.prototype[EE.captureRejectionSymbol] = function(err, event, ...args) {
595  switch (event) {
596    case 'request': {
597      const { 1: res } = args;
598      if (!res.headersSent && !res.writableEnded) {
599        // Don't leak headers.
600        const names = res.getHeaderNames();
601        for (let i = 0; i < names.length; i++) {
602          res.removeHeader(names[i]);
603        }
604        res.statusCode = 500;
605        res.end(STATUS_CODES[500]);
606      } else {
607        res.destroy();
608      }
609      break;
610    }
611    default:
612      net.Server.prototype[SymbolFor('nodejs.rejection')]
613        .apply(this, arguments);
614  }
615};
616
617function checkConnections() {
618  if (this.headersTimeout === 0 && this.requestTimeout === 0) {
619    return;
620  }
621
622  const expired = this[kConnections].expired(this.headersTimeout, this.requestTimeout);
623
624  for (let i = 0; i < expired.length; i++) {
625    const socket = expired[i].socket;
626
627    if (socket) {
628      onRequestTimeout(socket);
629    }
630  }
631}
632
633function connectionListener(socket) {
634  defaultTriggerAsyncIdScope(
635    getOrSetAsyncId(socket), connectionListenerInternal, this, socket,
636  );
637}
638
639function connectionListenerInternal(server, socket) {
640  debug('SERVER new http connection');
641
642  // Ensure that the server property of the socket is correctly set.
643  // See https://github.com/nodejs/node/issues/13435
644  socket.server = server;
645
646  // If the user has added a listener to the server,
647  // request, or response, then it's their responsibility.
648  // otherwise, destroy on timeout by default
649  if (server.timeout && typeof socket.setTimeout === 'function')
650    socket.setTimeout(server.timeout);
651  socket.on('timeout', socketOnTimeout);
652
653  const parser = parsers.alloc();
654
655  const lenient = server.insecureHTTPParser === undefined ?
656    isLenient() : server.insecureHTTPParser;
657
658  // TODO(addaleax): This doesn't play well with the
659  // `async_hooks.currentResource()` proposal, see
660  // https://github.com/nodejs/node/pull/21313
661  parser.initialize(
662    HTTPParser.REQUEST,
663    new HTTPServerAsyncResource('HTTPINCOMINGMESSAGE', socket),
664    server.maxHeaderSize || 0,
665    lenient ? kLenientAll : kLenientNone,
666    server[kConnections],
667  );
668  parser.socket = socket;
669  socket.parser = parser;
670
671  // Propagate headers limit from server instance to parser
672  if (typeof server.maxHeadersCount === 'number') {
673    parser.maxHeaderPairs = server.maxHeadersCount << 1;
674  }
675
676  const state = {
677    onData: null,
678    onEnd: null,
679    onClose: null,
680    onDrain: null,
681    outgoing: [],
682    incoming: [],
683    // `outgoingData` is an approximate amount of bytes queued through all
684    // inactive responses. If more data than the high watermark is queued - we
685    // need to pause TCP socket/HTTP parser, and wait until the data will be
686    // sent to the client.
687    outgoingData: 0,
688    requestsCount: 0,
689    keepAliveTimeoutSet: false,
690  };
691  state.onData = socketOnData.bind(undefined,
692                                   server, socket, parser, state);
693  state.onEnd = socketOnEnd.bind(undefined,
694                                 server, socket, parser, state);
695  state.onClose = socketOnClose.bind(undefined,
696                                     socket, state);
697  state.onDrain = socketOnDrain.bind(undefined,
698                                     socket, state);
699  socket.on('data', state.onData);
700  socket.on('error', socketOnError);
701  socket.on('end', state.onEnd);
702  socket.on('close', state.onClose);
703  socket.on('drain', state.onDrain);
704  parser.onIncoming = parserOnIncoming.bind(undefined,
705                                            server, socket, state);
706
707  // We are consuming socket, so it won't get any actual data
708  socket.on('resume', onSocketResume);
709  socket.on('pause', onSocketPause);
710
711  // Overrides to unconsume on `data`, `readable` listeners
712  socket.on = generateSocketListenerWrapper('on');
713  socket.addListener = generateSocketListenerWrapper('addListener');
714  socket.prependListener = generateSocketListenerWrapper('prependListener');
715  socket.setEncoding = socketSetEncoding;
716
717  // We only consume the socket if it has never been consumed before.
718  if (socket._handle && socket._handle.isStreamBase &&
719      !socket._handle._consumed) {
720    parser._consumed = true;
721    socket._handle._consumed = true;
722    parser.consume(socket._handle);
723  }
724  parser[kOnExecute] =
725    onParserExecute.bind(undefined,
726                         server, socket, parser, state);
727
728  parser[kOnTimeout] =
729    onParserTimeout.bind(undefined,
730                         server, socket);
731
732  socket._paused = false;
733}
734
735function socketSetEncoding() {
736  throw new ERR_HTTP_SOCKET_ENCODING();
737}
738
739function updateOutgoingData(socket, state, delta) {
740  state.outgoingData += delta;
741  socketOnDrain(socket, state);
742}
743
744function socketOnDrain(socket, state) {
745  const needPause = state.outgoingData > socket.writableHighWaterMark;
746
747  // If we previously paused, then start reading again.
748  if (socket._paused && !needPause) {
749    socket._paused = false;
750    if (socket.parser)
751      socket.parser.resume();
752    socket.resume();
753  }
754
755  const msg = socket._httpMessage;
756  if (msg && !msg.finished && msg[kNeedDrain]) {
757    msg[kNeedDrain] = false;
758    msg.emit('drain');
759  }
760}
761
762function socketOnTimeout() {
763  const req = this.parser && this.parser.incoming;
764  const reqTimeout = req && !req.complete && req.emit('timeout', this);
765  const res = this._httpMessage;
766  const resTimeout = res && res.emit('timeout', this);
767  const serverTimeout = this.server.emit('timeout', this);
768
769  if (!reqTimeout && !resTimeout && !serverTimeout)
770    this.destroy();
771}
772
773function socketOnClose(socket, state) {
774  debug('server socket close');
775  freeParser(socket.parser, null, socket);
776  abortIncoming(state.incoming);
777}
778
779function abortIncoming(incoming) {
780  while (incoming.length) {
781    const req = incoming.shift();
782    req.destroy(connResetException('aborted'));
783  }
784  // Abort socket._httpMessage ?
785}
786
787function socketOnEnd(server, socket, parser, state) {
788  const ret = parser.finish();
789
790  if (ret instanceof Error) {
791    debug('parse error');
792    // socketOnError has additional logic and will call socket.destroy(err).
793    socketOnError.call(socket, ret);
794  } else if (!server.httpAllowHalfOpen) {
795    socket.end();
796  } else if (state.outgoing.length) {
797    state.outgoing[state.outgoing.length - 1]._last = true;
798  } else if (socket._httpMessage) {
799    socket._httpMessage._last = true;
800  } else {
801    socket.end();
802  }
803}
804
805function socketOnData(server, socket, parser, state, d) {
806  assert(!socket._paused);
807  debug('SERVER socketOnData %d', d.length);
808
809  const ret = parser.execute(d);
810  onParserExecuteCommon(server, socket, parser, state, ret, d);
811}
812
813function onRequestTimeout(socket) {
814  // socketOnError has additional logic and will call socket.destroy(err).
815  socketOnError.call(socket, new ERR_HTTP_REQUEST_TIMEOUT());
816}
817
818function onParserExecute(server, socket, parser, state, ret) {
819  // When underlying `net.Socket` instance is consumed - no
820  // `data` events are emitted, and thus `socket.setTimeout` fires the
821  // callback even if the data is constantly flowing into the socket.
822  // See, https://github.com/nodejs/node/commit/ec2822adaad76b126b5cccdeaa1addf2376c9aa6
823  socket._unrefTimer();
824  debug('SERVER socketOnParserExecute %d', ret);
825  onParserExecuteCommon(server, socket, parser, state, ret, undefined);
826}
827
828function onParserTimeout(server, socket) {
829  const serverTimeout = server.emit('timeout', socket);
830
831  if (!serverTimeout)
832    socket.destroy();
833}
834
835const noop = () => {};
836const badRequestResponse = Buffer.from(
837  `HTTP/1.1 400 ${STATUS_CODES[400]}\r\n` +
838  'Connection: close\r\n\r\n', 'ascii',
839);
840const requestTimeoutResponse = Buffer.from(
841  `HTTP/1.1 408 ${STATUS_CODES[408]}\r\n` +
842  'Connection: close\r\n\r\n', 'ascii',
843);
844const requestHeaderFieldsTooLargeResponse = Buffer.from(
845  `HTTP/1.1 431 ${STATUS_CODES[431]}\r\n` +
846  'Connection: close\r\n\r\n', 'ascii',
847);
848
849const requestChunkExtensionsTooLargeResponse = Buffer.from(
850  `HTTP/1.1 413 ${STATUS_CODES[413]}\r\n` +
851  'Connection: close\r\n\r\n', 'ascii',
852);
853
854function warnUnclosedSocket() {
855  if (warnUnclosedSocket.emitted) {
856    return;
857  }
858
859  warnUnclosedSocket.emitted = true;
860  process.emitWarning(
861    'An error event has already been emitted on the socket. ' +
862    'Please use the destroy method on the socket while handling ' +
863    "a 'clientError' event.",
864  );
865}
866
867function socketOnError(e) {
868  // Ignore further errors
869  this.removeListener('error', socketOnError);
870
871  if (this.listenerCount('error', noop) === 0) {
872    this.on('error', noop);
873  } else {
874    warnUnclosedSocket();
875  }
876
877  if (!this.server.emit('clientError', e, this)) {
878    // Caution must be taken to avoid corrupting the remote peer.
879    // Reply an error segment if there is no in-flight `ServerResponse`,
880    // or no data of the in-flight one has been written yet to this socket.
881    if (this.writable &&
882        (!this._httpMessage || !this._httpMessage._headerSent)) {
883      let response;
884
885      switch (e.code) {
886        case 'HPE_HEADER_OVERFLOW':
887          response = requestHeaderFieldsTooLargeResponse;
888          break;
889        case 'HPE_CHUNK_EXTENSIONS_OVERFLOW':
890          response = requestChunkExtensionsTooLargeResponse;
891          break;
892        case 'ERR_HTTP_REQUEST_TIMEOUT':
893          response = requestTimeoutResponse;
894          break;
895        default:
896          response = badRequestResponse;
897          break;
898      }
899
900      this.write(response);
901    }
902    this.destroy(e);
903  }
904}
905
906function onParserExecuteCommon(server, socket, parser, state, ret, d) {
907  resetSocketTimeout(server, socket, state);
908
909  if (ret instanceof Error) {
910    prepareError(ret, parser, d);
911    debug('parse error', ret);
912    socketOnError.call(socket, ret);
913  } else if (parser.incoming && parser.incoming.upgrade) {
914    // Upgrade or CONNECT
915    const req = parser.incoming;
916    debug('SERVER upgrade or connect', req.method);
917
918    if (!d)
919      d = parser.getCurrentBuffer();
920
921    socket.removeListener('data', state.onData);
922    socket.removeListener('end', state.onEnd);
923    socket.removeListener('close', state.onClose);
924    socket.removeListener('drain', state.onDrain);
925    socket.removeListener('error', socketOnError);
926    socket.removeListener('timeout', socketOnTimeout);
927    unconsume(parser, socket);
928    parser.finish();
929    freeParser(parser, req, socket);
930    parser = null;
931
932    const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
933    if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) {
934      debug('SERVER have listener for %s', eventName);
935      const bodyHead = d.slice(ret, d.length);
936
937      socket.readableFlowing = null;
938
939      server.emit(eventName, req, socket, bodyHead);
940    } else {
941      // Got CONNECT method, but have no handler.
942      socket.destroy();
943    }
944  } else if (parser.incoming && parser.incoming.method === 'PRI') {
945    debug('SERVER got PRI request');
946    socket.destroy();
947  }
948
949  if (socket._paused && socket.parser) {
950    // onIncoming paused the socket, we should pause the parser as well
951    debug('pause parser');
952    socket.parser.pause();
953  }
954}
955
956function clearIncoming(req) {
957  req = req || this;
958  const parser = req.socket && req.socket.parser;
959  // Reset the .incoming property so that the request object can be gc'ed.
960  if (parser && parser.incoming === req) {
961    if (req.readableEnded) {
962      parser.incoming = null;
963    } else {
964      req.on('end', clearIncoming);
965    }
966  }
967}
968
969function resOnFinish(req, res, socket, state, server) {
970  if (onResponseFinishChannel.hasSubscribers) {
971    onResponseFinishChannel.publish({
972      request: req,
973      response: res,
974      socket,
975      server,
976    });
977  }
978
979  // Usually the first incoming element should be our request.  it may
980  // be that in the case abortIncoming() was called that the incoming
981  // array will be empty.
982  assert(state.incoming.length === 0 || state.incoming[0] === req);
983
984  state.incoming.shift();
985
986  // If the user never called req.read(), and didn't pipe() or
987  // .resume() or .on('data'), then we call req._dump() so that the
988  // bytes will be pulled off the wire.
989  if (!req._consuming && !req._readableState.resumeScheduled)
990    req._dump();
991
992  res.detachSocket(socket);
993  clearIncoming(req);
994  process.nextTick(emitCloseNT, res);
995
996  if (res._last) {
997    if (typeof socket.destroySoon === 'function') {
998      socket.destroySoon();
999    } else {
1000      socket.end();
1001    }
1002  } else if (state.outgoing.length === 0) {
1003    if (server.keepAliveTimeout && typeof socket.setTimeout === 'function') {
1004      socket.setTimeout(server.keepAliveTimeout);
1005      state.keepAliveTimeoutSet = true;
1006    }
1007  } else {
1008    // Start sending the next message
1009    const m = state.outgoing.shift();
1010    if (m) {
1011      m.assignSocket(socket);
1012    }
1013  }
1014}
1015
1016function emitCloseNT(self) {
1017  if (!self._closed) {
1018    self.destroyed = true;
1019    self._closed = true;
1020    self.emit('close');
1021  }
1022}
1023
1024// The following callback is issued after the headers have been read on a
1025// new message. In this callback we setup the response object and pass it
1026// to the user.
1027function parserOnIncoming(server, socket, state, req, keepAlive) {
1028  resetSocketTimeout(server, socket, state);
1029
1030  if (req.upgrade) {
1031    req.upgrade = req.method === 'CONNECT' ||
1032                  server.listenerCount('upgrade') > 0;
1033    if (req.upgrade)
1034      return 2;
1035  }
1036
1037  state.incoming.push(req);
1038
1039  // If the writable end isn't consuming, then stop reading
1040  // so that we don't become overwhelmed by a flood of
1041  // pipelined requests that may never be resolved.
1042  if (!socket._paused) {
1043    const ws = socket._writableState;
1044    if (ws.needDrain || state.outgoingData >= socket.writableHighWaterMark) {
1045      socket._paused = true;
1046      // We also need to pause the parser, but don't do that until after
1047      // the call to execute, because we may still be processing the last
1048      // chunk.
1049      socket.pause();
1050    }
1051  }
1052
1053  const res = new server[kServerResponse](req,
1054                                          {
1055                                            highWaterMark: socket.writableHighWaterMark,
1056                                            rejectNonStandardBodyWrites: server.rejectNonStandardBodyWrites,
1057                                          });
1058  res._keepAliveTimeout = server.keepAliveTimeout;
1059  res._maxRequestsPerSocket = server.maxRequestsPerSocket;
1060  res._onPendingData = updateOutgoingData.bind(undefined,
1061                                               socket, state);
1062
1063  res.shouldKeepAlive = keepAlive;
1064  res[kUniqueHeaders] = server[kUniqueHeaders];
1065  DTRACE_HTTP_SERVER_REQUEST(req, socket);
1066
1067  if (onRequestStartChannel.hasSubscribers) {
1068    onRequestStartChannel.publish({
1069      request: req,
1070      response: res,
1071      socket,
1072      server,
1073    });
1074  }
1075
1076  if (socket._httpMessage) {
1077    // There are already pending outgoing res, append.
1078    state.outgoing.push(res);
1079  } else {
1080    res.assignSocket(socket);
1081  }
1082
1083  // When we're finished writing the response, check if this is the last
1084  // response, if so destroy the socket.
1085  res.on('finish',
1086         resOnFinish.bind(undefined,
1087                          req, res, socket, state, server));
1088
1089  let handled = false;
1090
1091  if (req.httpVersionMajor === 1 && req.httpVersionMinor === 1) {
1092    const isRequestsLimitSet = (
1093      typeof server.maxRequestsPerSocket === 'number' &&
1094      server.maxRequestsPerSocket > 0
1095    );
1096
1097    if (isRequestsLimitSet) {
1098      state.requestsCount++;
1099      res.maxRequestsOnConnectionReached = (
1100        server.maxRequestsPerSocket <= state.requestsCount);
1101    }
1102
1103    if (isRequestsLimitSet &&
1104      (server.maxRequestsPerSocket < state.requestsCount)) {
1105      handled = true;
1106      server.emit('dropRequest', req, socket);
1107      res.writeHead(503);
1108      res.end();
1109    } else if (req.headers.expect !== undefined) {
1110      handled = true;
1111
1112      if (RegExpPrototypeExec(continueExpression, req.headers.expect) !== null) {
1113        res._expect_continue = true;
1114
1115        if (server.listenerCount('checkContinue') > 0) {
1116          server.emit('checkContinue', req, res);
1117        } else {
1118          res.writeContinue();
1119          server.emit('request', req, res);
1120        }
1121      } else if (server.listenerCount('checkExpectation') > 0) {
1122        server.emit('checkExpectation', req, res);
1123      } else {
1124        res.writeHead(417);
1125        res.end();
1126      }
1127    }
1128  }
1129
1130  if (!handled) {
1131    server.emit('request', req, res);
1132  }
1133
1134  return 0;  // No special treatment.
1135}
1136
1137function resetSocketTimeout(server, socket, state) {
1138  if (!state.keepAliveTimeoutSet)
1139    return;
1140
1141  socket.setTimeout(server.timeout || 0);
1142  state.keepAliveTimeoutSet = false;
1143}
1144
1145function onSocketResume() {
1146  // It may seem that the socket is resumed, but this is an enemy's trick to
1147  // deceive us! `resume` is emitted asynchronously, and may be called from
1148  // `incoming.readStart()`. Stop the socket again here, just to preserve the
1149  // state.
1150  //
1151  // We don't care about stream semantics for the consumed socket anyway.
1152  if (this._paused) {
1153    this.pause();
1154    return;
1155  }
1156
1157  if (this._handle && !this._handle.reading) {
1158    this._handle.reading = true;
1159    this._handle.readStart();
1160  }
1161}
1162
1163function onSocketPause() {
1164  if (this._handle && this._handle.reading) {
1165    this._handle.reading = false;
1166    this._handle.readStop();
1167  }
1168}
1169
1170function unconsume(parser, socket) {
1171  if (socket._handle) {
1172    if (parser._consumed)
1173      parser.unconsume();
1174    parser._consumed = false;
1175    socket.removeListener('pause', onSocketPause);
1176    socket.removeListener('resume', onSocketResume);
1177  }
1178}
1179
1180function generateSocketListenerWrapper(originalFnName) {
1181  return function socketListenerWrap(ev, fn) {
1182    const res = net.Socket.prototype[originalFnName].call(this,
1183                                                          ev, fn);
1184    if (!this.parser) {
1185      this.on = net.Socket.prototype.on;
1186      this.addListener = net.Socket.prototype.addListener;
1187      this.prependListener = net.Socket.prototype.prependListener;
1188      return res;
1189    }
1190
1191    if (ev === 'data' || ev === 'readable')
1192      unconsume(this.parser, this);
1193
1194    return res;
1195  };
1196}
1197
1198module.exports = {
1199  STATUS_CODES,
1200  Server,
1201  ServerResponse,
1202  setupConnectionsTracking,
1203  storeHTTPOptions,
1204  _connectionListener: connectionListener,
1205  kServerResponse,
1206  httpServerPreClose,
1207  kConnectionsCheckingInterval,
1208};
1209