• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  Error,
26  ObjectKeys,
27  ObjectSetPrototypeOf,
28  Symbol,
29} = primordials;
30
31const net = require('net');
32const EE = require('events');
33const assert = require('internal/assert');
34const {
35  parsers,
36  freeParser,
37  debug,
38  CRLF,
39  continueExpression,
40  chunkExpression,
41  kIncomingMessage,
42  HTTPParser,
43  isLenient,
44  _checkInvalidHeaderChar: checkInvalidHeaderChar,
45  prepareError,
46} = require('_http_common');
47const { OutgoingMessage } = require('_http_outgoing');
48const {
49  kOutHeaders,
50  kNeedDrain,
51  emitStatistics
52} = require('internal/http');
53const {
54  defaultTriggerAsyncIdScope,
55  getOrSetAsyncId
56} = require('internal/async_hooks');
57const { IncomingMessage } = require('_http_incoming');
58const {
59  ERR_HTTP_HEADERS_SENT,
60  ERR_HTTP_INVALID_STATUS_CODE,
61  ERR_INVALID_ARG_TYPE,
62  ERR_INVALID_CHAR
63} = require('internal/errors').codes;
64const Buffer = require('buffer').Buffer;
65const {
66  DTRACE_HTTP_SERVER_REQUEST,
67  DTRACE_HTTP_SERVER_RESPONSE
68} = require('internal/dtrace');
69const { getOptionValue } = require('internal/options');
70const { observerCounts, constants } = internalBinding('performance');
71const { NODE_PERFORMANCE_ENTRY_TYPE_HTTP } = constants;
72
73const kServerResponse = Symbol('ServerResponse');
74const kServerResponseStatistics = Symbol('ServerResponseStatistics');
75const kDefaultHttpServerTimeout =
76  getOptionValue('--http-server-default-timeout');
77
78const STATUS_CODES = {
79  100: 'Continue',
80  101: 'Switching Protocols',
81  102: 'Processing',                 // RFC 2518, obsoleted by RFC 4918
82  103: 'Early Hints',
83  200: 'OK',
84  201: 'Created',
85  202: 'Accepted',
86  203: 'Non-Authoritative Information',
87  204: 'No Content',
88  205: 'Reset Content',
89  206: 'Partial Content',
90  207: 'Multi-Status',               // RFC 4918
91  208: 'Already Reported',
92  226: 'IM Used',
93  300: 'Multiple Choices',           // RFC 7231
94  301: 'Moved Permanently',
95  302: 'Found',
96  303: 'See Other',
97  304: 'Not Modified',
98  305: 'Use Proxy',
99  307: 'Temporary Redirect',
100  308: 'Permanent Redirect',         // RFC 7238
101  400: 'Bad Request',
102  401: 'Unauthorized',
103  402: 'Payment Required',
104  403: 'Forbidden',
105  404: 'Not Found',
106  405: 'Method Not Allowed',
107  406: 'Not Acceptable',
108  407: 'Proxy Authentication Required',
109  408: 'Request Timeout',
110  409: 'Conflict',
111  410: 'Gone',
112  411: 'Length Required',
113  412: 'Precondition Failed',
114  413: 'Payload Too Large',
115  414: 'URI Too Long',
116  415: 'Unsupported Media Type',
117  416: 'Range Not Satisfiable',
118  417: 'Expectation Failed',
119  418: 'I\'m a Teapot',              // RFC 7168
120  421: 'Misdirected Request',
121  422: 'Unprocessable Entity',       // RFC 4918
122  423: 'Locked',                     // RFC 4918
123  424: 'Failed Dependency',          // RFC 4918
124  425: 'Unordered Collection',       // RFC 4918
125  426: 'Upgrade Required',           // RFC 2817
126  428: 'Precondition Required',      // RFC 6585
127  429: 'Too Many Requests',          // RFC 6585
128  431: 'Request Header Fields Too Large', // RFC 6585
129  451: 'Unavailable For Legal Reasons',
130  500: 'Internal Server Error',
131  501: 'Not Implemented',
132  502: 'Bad Gateway',
133  503: 'Service Unavailable',
134  504: 'Gateway Timeout',
135  505: 'HTTP Version Not Supported',
136  506: 'Variant Also Negotiates',    // RFC 2295
137  507: 'Insufficient Storage',       // RFC 4918
138  508: 'Loop Detected',
139  509: 'Bandwidth Limit Exceeded',
140  510: 'Not Extended',               // RFC 2774
141  511: 'Network Authentication Required' // RFC 6585
142};
143
144const kOnExecute = HTTPParser.kOnExecute | 0;
145const kOnTimeout = HTTPParser.kOnTimeout | 0;
146
147class HTTPServerAsyncResource {
148  constructor(type, socket) {
149    this.type = type;
150    this.socket = socket;
151  }
152}
153
154function ServerResponse(req) {
155  OutgoingMessage.call(this);
156
157  if (req.method === 'HEAD') this._hasBody = false;
158
159  this.sendDate = true;
160  this._sent100 = false;
161  this._expect_continue = false;
162
163  if (req.httpVersionMajor < 1 || req.httpVersionMinor < 1) {
164    this.useChunkedEncodingByDefault = chunkExpression.test(req.headers.te);
165    this.shouldKeepAlive = false;
166  }
167
168  const httpObserverCount = observerCounts[NODE_PERFORMANCE_ENTRY_TYPE_HTTP];
169  if (httpObserverCount > 0) {
170    this[kServerResponseStatistics] = {
171      startTime: process.hrtime()
172    };
173  }
174}
175ObjectSetPrototypeOf(ServerResponse.prototype, OutgoingMessage.prototype);
176ObjectSetPrototypeOf(ServerResponse, OutgoingMessage);
177
178ServerResponse.prototype._finish = function _finish() {
179  DTRACE_HTTP_SERVER_RESPONSE(this.connection);
180  if (this[kServerResponseStatistics] !== undefined) {
181    emitStatistics(this[kServerResponseStatistics]);
182  }
183  OutgoingMessage.prototype._finish.call(this);
184};
185
186
187ServerResponse.prototype.statusCode = 200;
188ServerResponse.prototype.statusMessage = undefined;
189
190function onServerResponseClose() {
191  // EventEmitter.emit makes a copy of the 'close' listeners array before
192  // calling the listeners. detachSocket() unregisters onServerResponseClose
193  // but if detachSocket() is called, directly or indirectly, by a 'close'
194  // listener, onServerResponseClose is still in that copy of the listeners
195  // array. That is, in the example below, b still gets called even though
196  // it's been removed by a:
197  //
198  //   var EventEmitter = require('events');
199  //   var obj = new EventEmitter();
200  //   obj.on('event', a);
201  //   obj.on('event', b);
202  //   function a() { obj.removeListener('event', b) }
203  //   function b() { throw "BAM!" }
204  //   obj.emit('event');  // throws
205  //
206  // Ergo, we need to deal with stale 'close' events and handle the case
207  // where the ServerResponse object has already been deconstructed.
208  // Fortunately, that requires only a single if check. :-)
209  if (this._httpMessage) this._httpMessage.emit('close');
210}
211
212ServerResponse.prototype.assignSocket = function assignSocket(socket) {
213  assert(!socket._httpMessage);
214  socket._httpMessage = this;
215  socket.on('close', onServerResponseClose);
216  this.socket = socket;
217  this.connection = socket;
218  this.emit('socket', socket);
219  this._flush();
220};
221
222ServerResponse.prototype.detachSocket = function detachSocket(socket) {
223  assert(socket._httpMessage === this);
224  socket.removeListener('close', onServerResponseClose);
225  socket._httpMessage = null;
226  this.socket = this.connection = null;
227};
228
229ServerResponse.prototype.writeContinue = function writeContinue(cb) {
230  this._writeRaw(`HTTP/1.1 100 Continue${CRLF}${CRLF}`, 'ascii', cb);
231  this._sent100 = true;
232};
233
234ServerResponse.prototype.writeProcessing = function writeProcessing(cb) {
235  this._writeRaw(`HTTP/1.1 102 Processing${CRLF}${CRLF}`, 'ascii', cb);
236};
237
238ServerResponse.prototype._implicitHeader = function _implicitHeader() {
239  this.writeHead(this.statusCode);
240};
241
242ServerResponse.prototype.writeHead = writeHead;
243function writeHead(statusCode, reason, obj) {
244  const originalStatusCode = statusCode;
245
246  statusCode |= 0;
247  if (statusCode < 100 || statusCode > 999) {
248    throw new ERR_HTTP_INVALID_STATUS_CODE(originalStatusCode);
249  }
250
251
252  if (typeof reason === 'string') {
253    // writeHead(statusCode, reasonPhrase[, headers])
254    this.statusMessage = reason;
255  } else {
256    // writeHead(statusCode[, headers])
257    if (!this.statusMessage)
258      this.statusMessage = STATUS_CODES[statusCode] || 'unknown';
259    obj = reason;
260  }
261  this.statusCode = statusCode;
262
263  let headers;
264  if (this[kOutHeaders]) {
265    // Slow-case: when progressive API and header fields are passed.
266    let k;
267    if (obj) {
268      const keys = ObjectKeys(obj);
269      // Retain for(;;) loop for performance reasons
270      // Refs: https://github.com/nodejs/node/pull/30958
271      for (let i = 0; i < keys.length; i++) {
272        k = keys[i];
273        if (k) this.setHeader(k, obj[k]);
274      }
275    }
276    if (k === undefined && this._header) {
277      throw new ERR_HTTP_HEADERS_SENT('render');
278    }
279    // Only progressive api is used
280    headers = this[kOutHeaders];
281  } else {
282    // Only writeHead() called
283    headers = obj;
284  }
285
286  if (checkInvalidHeaderChar(this.statusMessage))
287    throw new ERR_INVALID_CHAR('statusMessage');
288
289  const statusLine = `HTTP/1.1 ${statusCode} ${this.statusMessage}${CRLF}`;
290
291  if (statusCode === 204 || statusCode === 304 ||
292      (statusCode >= 100 && statusCode <= 199)) {
293    // RFC 2616, 10.2.5:
294    // The 204 response MUST NOT include a message-body, and thus is always
295    // terminated by the first empty line after the header fields.
296    // RFC 2616, 10.3.5:
297    // The 304 response MUST NOT contain a message-body, and thus is always
298    // terminated by the first empty line after the header fields.
299    // RFC 2616, 10.1 Informational 1xx:
300    // This class of status code indicates a provisional response,
301    // consisting only of the Status-Line and optional headers, and is
302    // terminated by an empty line.
303    this._hasBody = false;
304  }
305
306  // Don't keep alive connections where the client expects 100 Continue
307  // but we sent a final status; they may put extra bytes on the wire.
308  if (this._expect_continue && !this._sent100) {
309    this.shouldKeepAlive = false;
310  }
311
312  this._storeHeader(statusLine, headers);
313
314  return this;
315}
316
317// Docs-only deprecated: DEP0063
318ServerResponse.prototype.writeHeader = ServerResponse.prototype.writeHead;
319
320function Server(options, requestListener) {
321  if (!(this instanceof Server)) return new Server(options, requestListener);
322
323  if (typeof options === 'function') {
324    requestListener = options;
325    options = {};
326  } else if (options == null || typeof options === 'object') {
327    options = { ...options };
328  } else {
329    throw new ERR_INVALID_ARG_TYPE('options', 'object', options);
330  }
331
332  this[kIncomingMessage] = options.IncomingMessage || IncomingMessage;
333  this[kServerResponse] = options.ServerResponse || ServerResponse;
334
335  const insecureHTTPParser = options.insecureHTTPParser;
336  if (insecureHTTPParser !== undefined &&
337      typeof insecureHTTPParser !== 'boolean') {
338    throw new ERR_INVALID_ARG_TYPE(
339      'options.insecureHTTPParser', 'boolean', insecureHTTPParser);
340  }
341  this.insecureHTTPParser = insecureHTTPParser;
342
343  net.Server.call(this, { allowHalfOpen: true });
344
345  if (requestListener) {
346    this.on('request', requestListener);
347  }
348
349  // Similar option to this. Too lazy to write my own docs.
350  // http://www.squid-cache.org/Doc/config/half_closed_clients/
351  // https://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
352  this.httpAllowHalfOpen = false;
353
354  this.on('connection', connectionListener);
355
356  this.timeout = kDefaultHttpServerTimeout;
357  this.keepAliveTimeout = 5000;
358  this.maxHeadersCount = null;
359  this.headersTimeout = 60 * 1000; // 60 seconds
360}
361ObjectSetPrototypeOf(Server.prototype, net.Server.prototype);
362ObjectSetPrototypeOf(Server, net.Server);
363
364
365Server.prototype.setTimeout = function setTimeout(msecs, callback) {
366  this.timeout = msecs;
367  if (callback)
368    this.on('timeout', callback);
369  return this;
370};
371
372Server.prototype[EE.captureRejectionSymbol] = function(
373  err, event, ...args) {
374
375  switch (event) {
376    case 'request':
377      const [ , res] = args;
378      if (!res.headersSent && !res.writableEnded) {
379        // Don't leak headers.
380        for (const name of res.getHeaderNames()) {
381          res.removeHeader(name);
382        }
383        res.statusCode = 500;
384        res.end(STATUS_CODES[500]);
385      } else {
386        res.destroy();
387      }
388      break;
389    default:
390      net.Server.prototype[Symbol.for('nodejs.rejection')]
391        .call(this, err, event, ...args);
392  }
393};
394
395function connectionListener(socket) {
396  defaultTriggerAsyncIdScope(
397    getOrSetAsyncId(socket), connectionListenerInternal, this, socket
398  );
399}
400
401function connectionListenerInternal(server, socket) {
402  debug('SERVER new http connection');
403
404  // Ensure that the server property of the socket is correctly set.
405  // See https://github.com/nodejs/node/issues/13435
406  socket.server = server;
407
408  // If the user has added a listener to the server,
409  // request, or response, then it's their responsibility.
410  // otherwise, destroy on timeout by default
411  if (server.timeout && typeof socket.setTimeout === 'function')
412    socket.setTimeout(server.timeout);
413  socket.on('timeout', socketOnTimeout);
414
415  const parser = parsers.alloc();
416
417  // TODO(addaleax): This doesn't play well with the
418  // `async_hooks.currentResource()` proposal, see
419  // https://github.com/nodejs/node/pull/21313
420  parser.initialize(
421    HTTPParser.REQUEST,
422    new HTTPServerAsyncResource('HTTPINCOMINGMESSAGE', socket),
423    server.insecureHTTPParser === undefined ?
424      isLenient() : server.insecureHTTPParser,
425    server.headersTimeout || 0,
426  );
427  parser.socket = socket;
428  socket.parser = parser;
429
430  // Propagate headers limit from server instance to parser
431  if (typeof server.maxHeadersCount === 'number') {
432    parser.maxHeaderPairs = server.maxHeadersCount << 1;
433  }
434
435  const state = {
436    onData: null,
437    onEnd: null,
438    onClose: null,
439    onDrain: null,
440    outgoing: [],
441    incoming: [],
442    // `outgoingData` is an approximate amount of bytes queued through all
443    // inactive responses. If more data than the high watermark is queued - we
444    // need to pause TCP socket/HTTP parser, and wait until the data will be
445    // sent to the client.
446    outgoingData: 0,
447    keepAliveTimeoutSet: false
448  };
449  state.onData = socketOnData.bind(undefined, server, socket, parser, state);
450  state.onEnd = socketOnEnd.bind(undefined, server, socket, parser, state);
451  state.onClose = socketOnClose.bind(undefined, socket, state);
452  state.onDrain = socketOnDrain.bind(undefined, socket, state);
453  socket.on('data', state.onData);
454  socket.on('error', socketOnError);
455  socket.on('end', state.onEnd);
456  socket.on('close', state.onClose);
457  socket.on('drain', state.onDrain);
458  parser.onIncoming = parserOnIncoming.bind(undefined, server, socket, state);
459
460  // We are consuming socket, so it won't get any actual data
461  socket.on('resume', onSocketResume);
462  socket.on('pause', onSocketPause);
463
464  // Overrides to unconsume on `data`, `readable` listeners
465  socket.on = generateSocketListenerWrapper('on');
466  socket.addListener = generateSocketListenerWrapper('addListener');
467  socket.prependListener = generateSocketListenerWrapper('prependListener');
468
469  // We only consume the socket if it has never been consumed before.
470  if (socket._handle && socket._handle.isStreamBase &&
471      !socket._handle._consumed) {
472    parser._consumed = true;
473    socket._handle._consumed = true;
474    parser.consume(socket._handle);
475  }
476  parser[kOnExecute] =
477    onParserExecute.bind(undefined, server, socket, parser, state);
478
479  parser[kOnTimeout] =
480    onParserTimeout.bind(undefined, server, socket);
481
482  socket._paused = false;
483}
484
485function updateOutgoingData(socket, state, delta) {
486  state.outgoingData += delta;
487  socketOnDrain(socket, state);
488}
489
490function socketOnDrain(socket, state) {
491  const needPause = state.outgoingData > socket.writableHighWaterMark;
492
493  // If we previously paused, then start reading again.
494  if (socket._paused && !needPause) {
495    socket._paused = false;
496    if (socket.parser)
497      socket.parser.resume();
498    socket.resume();
499  }
500
501  const msg = socket._httpMessage;
502  if (msg && !msg.finished && msg[kNeedDrain]) {
503    msg[kNeedDrain] = false;
504    msg.emit('drain');
505  }
506}
507
508function socketOnTimeout() {
509  const req = this.parser && this.parser.incoming;
510  const reqTimeout = req && !req.complete && req.emit('timeout', this);
511  const res = this._httpMessage;
512  const resTimeout = res && res.emit('timeout', this);
513  const serverTimeout = this.server.emit('timeout', this);
514
515  if (!reqTimeout && !resTimeout && !serverTimeout)
516    this.destroy();
517}
518
519function socketOnClose(socket, state) {
520  debug('server socket close');
521  // Mark this parser as reusable
522  if (socket.parser) {
523    freeParser(socket.parser, null, socket);
524  }
525
526  abortIncoming(state.incoming);
527}
528
529function abortIncoming(incoming) {
530  while (incoming.length) {
531    const req = incoming.shift();
532    req.aborted = true;
533    req.emit('aborted');
534    req.emit('close');
535  }
536  // Abort socket._httpMessage ?
537}
538
539function socketOnEnd(server, socket, parser, state) {
540  const ret = parser.finish();
541
542  if (ret instanceof Error) {
543    debug('parse error');
544    socketOnError.call(socket, ret);
545    return;
546  }
547
548  if (!server.httpAllowHalfOpen) {
549    abortIncoming(state.incoming);
550    if (socket.writable) socket.end();
551  } else if (state.outgoing.length) {
552    state.outgoing[state.outgoing.length - 1]._last = true;
553  } else if (socket._httpMessage) {
554    socket._httpMessage._last = true;
555  } else if (socket.writable) {
556    socket.end();
557  }
558}
559
560function socketOnData(server, socket, parser, state, d) {
561  assert(!socket._paused);
562  debug('SERVER socketOnData %d', d.length);
563
564  const ret = parser.execute(d);
565  onParserExecuteCommon(server, socket, parser, state, ret, d);
566}
567
568function onParserExecute(server, socket, parser, state, ret) {
569  // When underlying `net.Socket` instance is consumed - no
570  // `data` events are emitted, and thus `socket.setTimeout` fires the
571  // callback even if the data is constantly flowing into the socket.
572  // See, https://github.com/nodejs/node/commit/ec2822adaad76b126b5cccdeaa1addf2376c9aa6
573  socket._unrefTimer();
574  debug('SERVER socketOnParserExecute %d', ret);
575  onParserExecuteCommon(server, socket, parser, state, ret, undefined);
576}
577
578function onParserTimeout(server, socket) {
579  const serverTimeout = server.emit('timeout', socket);
580
581  if (!serverTimeout)
582    socket.destroy();
583}
584
585const noop = () => {};
586const badRequestResponse = Buffer.from(
587  `HTTP/1.1 400 ${STATUS_CODES[400]}${CRLF}` +
588  `Connection: close${CRLF}${CRLF}`, 'ascii'
589);
590const requestHeaderFieldsTooLargeResponse = Buffer.from(
591  `HTTP/1.1 431 ${STATUS_CODES[431]}${CRLF}` +
592  `Connection: close${CRLF}${CRLF}`, 'ascii'
593);
594function socketOnError(e) {
595  // Ignore further errors
596  this.removeListener('error', socketOnError);
597  this.on('error', noop);
598
599  if (!this.server.emit('clientError', e, this)) {
600    if (this.writable && this.bytesWritten === 0) {
601      const response = e.code === 'HPE_HEADER_OVERFLOW' ?
602        requestHeaderFieldsTooLargeResponse : badRequestResponse;
603      this.write(response);
604    }
605    this.destroy(e);
606  }
607}
608
609function onParserExecuteCommon(server, socket, parser, state, ret, d) {
610  resetSocketTimeout(server, socket, state);
611
612  if (ret instanceof Error) {
613    prepareError(ret, parser, d);
614    ret.rawPacket = d || parser.getCurrentBuffer();
615    debug('parse error', ret);
616    socketOnError.call(socket, ret);
617  } else if (parser.incoming && parser.incoming.upgrade) {
618    // Upgrade or CONNECT
619    const req = parser.incoming;
620    debug('SERVER upgrade or connect', req.method);
621
622    if (!d)
623      d = parser.getCurrentBuffer();
624
625    socket.removeListener('data', state.onData);
626    socket.removeListener('end', state.onEnd);
627    socket.removeListener('close', state.onClose);
628    socket.removeListener('drain', state.onDrain);
629    socket.removeListener('error', socketOnError);
630    unconsume(parser, socket);
631    parser.finish();
632    freeParser(parser, req, socket);
633    parser = null;
634
635    const eventName = req.method === 'CONNECT' ? 'connect' : 'upgrade';
636    if (eventName === 'upgrade' || server.listenerCount(eventName) > 0) {
637      debug('SERVER have listener for %s', eventName);
638      const bodyHead = d.slice(ret, d.length);
639
640      socket.readableFlowing = null;
641      server.emit(eventName, req, socket, bodyHead);
642    } else {
643      // Got CONNECT method, but have no handler.
644      socket.destroy();
645    }
646  }
647
648  if (socket._paused && socket.parser) {
649    // onIncoming paused the socket, we should pause the parser as well
650    debug('pause parser');
651    socket.parser.pause();
652  }
653}
654
655function clearIncoming(req) {
656  req = req || this;
657  const parser = req.socket && req.socket.parser;
658  // Reset the .incoming property so that the request object can be gc'ed.
659  if (parser && parser.incoming === req) {
660    if (req.readableEnded) {
661      parser.incoming = null;
662      req.emit('close');
663    } else {
664      req.on('end', clearIncoming);
665    }
666  } else {
667    req.emit('close');
668  }
669}
670
671function resOnFinish(req, res, socket, state, server) {
672  // Usually the first incoming element should be our request.  it may
673  // be that in the case abortIncoming() was called that the incoming
674  // array will be empty.
675  assert(state.incoming.length === 0 || state.incoming[0] === req);
676
677  state.incoming.shift();
678
679  // If the user never called req.read(), and didn't pipe() or
680  // .resume() or .on('data'), then we call req._dump() so that the
681  // bytes will be pulled off the wire.
682  if (!req._consuming && !req._readableState.resumeScheduled)
683    req._dump();
684
685  res.detachSocket(socket);
686  clearIncoming(req);
687  process.nextTick(emitCloseNT, res);
688
689  if (res._last) {
690    if (typeof socket.destroySoon === 'function') {
691      socket.destroySoon();
692    } else {
693      socket.end();
694    }
695  } else if (state.outgoing.length === 0) {
696    if (server.keepAliveTimeout && typeof socket.setTimeout === 'function') {
697      socket.setTimeout(server.keepAliveTimeout);
698      state.keepAliveTimeoutSet = true;
699    }
700  } else {
701    // Start sending the next message
702    const m = state.outgoing.shift();
703    if (m) {
704      m.assignSocket(socket);
705    }
706  }
707}
708
709function emitCloseNT(self) {
710  self.emit('close');
711}
712
713// The following callback is issued after the headers have been read on a
714// new message. In this callback we setup the response object and pass it
715// to the user.
716function parserOnIncoming(server, socket, state, req, keepAlive) {
717  resetSocketTimeout(server, socket, state);
718
719  if (req.upgrade) {
720    req.upgrade = req.method === 'CONNECT' ||
721                  server.listenerCount('upgrade') > 0;
722    if (req.upgrade)
723      return 2;
724  }
725
726  state.incoming.push(req);
727
728  // If the writable end isn't consuming, then stop reading
729  // so that we don't become overwhelmed by a flood of
730  // pipelined requests that may never be resolved.
731  if (!socket._paused) {
732    const ws = socket._writableState;
733    if (ws.needDrain || state.outgoingData >= socket.writableHighWaterMark) {
734      socket._paused = true;
735      // We also need to pause the parser, but don't do that until after
736      // the call to execute, because we may still be processing the last
737      // chunk.
738      socket.pause();
739    }
740  }
741
742  const res = new server[kServerResponse](req);
743  res._keepAliveTimeout = server.keepAliveTimeout;
744  res._onPendingData = updateOutgoingData.bind(undefined, socket, state);
745
746  res.shouldKeepAlive = keepAlive;
747  DTRACE_HTTP_SERVER_REQUEST(req, socket);
748
749  if (socket._httpMessage) {
750    // There are already pending outgoing res, append.
751    state.outgoing.push(res);
752  } else {
753    res.assignSocket(socket);
754  }
755
756  // When we're finished writing the response, check if this is the last
757  // response, if so destroy the socket.
758  res.on('finish',
759         resOnFinish.bind(undefined, req, res, socket, state, server));
760
761  if (req.headers.expect !== undefined &&
762      (req.httpVersionMajor === 1 && req.httpVersionMinor === 1)) {
763    if (continueExpression.test(req.headers.expect)) {
764      res._expect_continue = true;
765
766      if (server.listenerCount('checkContinue') > 0) {
767        server.emit('checkContinue', req, res);
768      } else {
769        res.writeContinue();
770        server.emit('request', req, res);
771      }
772    } else if (server.listenerCount('checkExpectation') > 0) {
773      server.emit('checkExpectation', req, res);
774    } else {
775      res.writeHead(417);
776      res.end();
777    }
778  } else {
779    server.emit('request', req, res);
780  }
781  return 0;  // No special treatment.
782}
783
784function resetSocketTimeout(server, socket, state) {
785  if (!state.keepAliveTimeoutSet)
786    return;
787
788  socket.setTimeout(server.timeout || 0);
789  state.keepAliveTimeoutSet = false;
790}
791
792function onSocketResume() {
793  // It may seem that the socket is resumed, but this is an enemy's trick to
794  // deceive us! `resume` is emitted asynchronously, and may be called from
795  // `incoming.readStart()`. Stop the socket again here, just to preserve the
796  // state.
797  //
798  // We don't care about stream semantics for the consumed socket anyway.
799  if (this._paused) {
800    this.pause();
801    return;
802  }
803
804  if (this._handle && !this._handle.reading) {
805    this._handle.reading = true;
806    this._handle.readStart();
807  }
808}
809
810function onSocketPause() {
811  if (this._handle && this._handle.reading) {
812    this._handle.reading = false;
813    this._handle.readStop();
814  }
815}
816
817function unconsume(parser, socket) {
818  if (socket._handle) {
819    if (parser._consumed)
820      parser.unconsume();
821    parser._consumed = false;
822    socket.removeListener('pause', onSocketPause);
823    socket.removeListener('resume', onSocketResume);
824  }
825}
826
827function generateSocketListenerWrapper(originalFnName) {
828  return function socketListenerWrap(ev, fn) {
829    const res = net.Socket.prototype[originalFnName].call(this, ev, fn);
830    if (!this.parser) {
831      this.on = net.Socket.prototype.on;
832      this.addListener = net.Socket.prototype.addListener;
833      this.prependListener = net.Socket.prototype.prependListener;
834      return res;
835    }
836
837    if (ev === 'data' || ev === 'readable')
838      unconsume(this.parser, this);
839
840    return res;
841  };
842}
843
844module.exports = {
845  STATUS_CODES,
846  Server,
847  ServerResponse,
848  _connectionListener: connectionListener,
849  kServerResponse
850};
851