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