3 const util = require('util');
4 const Stream = require('stream');
6 function readStart(socket) {
7 if (socket && !socket._paused && socket.readable)
10 exports.readStart = readStart;
12 function readStop(socket) {
16 exports.readStop = readStop;
19 /* Abstract base class for ServerRequest and ClientResponse. */
20 function IncomingMessage(socket) {
21 Stream.Readable.call(this);
23 // XXX This implementation is kind of all over the place
24 // When the parser emits body chunks, they go in this list.
25 // _read() pulls them out, and when it finds EOF, it ends.
28 this.connection = socket;
30 this.httpVersionMajor = null;
31 this.httpVersionMinor = null;
32 this.httpVersion = null;
33 this.complete = false;
37 this.rawTrailers = [];
43 // request (server) only
47 // response (client) only
48 this.statusCode = null;
49 this.statusMessage = null;
52 // flag for backwards compatibility grossness.
53 this._consuming = false;
55 // flag for when we decide that this message cannot possibly be
56 // read by the user, so there's no point continuing to handle it.
59 util.inherits(IncomingMessage, Stream.Readable);
62 exports.IncomingMessage = IncomingMessage;
65 IncomingMessage.prototype.setTimeout = function(msecs, callback) {
67 this.on('timeout', callback);
68 this.socket.setTimeout(msecs);
73 IncomingMessage.prototype.read = function(n) {
74 this._consuming = true;
75 this.read = Stream.Readable.prototype.read;
80 IncomingMessage.prototype._read = function(n) {
81 // We actually do almost nothing here, because the parserOnBody
82 // function fills up our internal buffer directly. However, we
83 // do need to unpause the underlying socket so that it flows.
84 if (this.socket.readable)
85 readStart(this.socket);
89 // It's possible that the socket will be destroyed, and removed from
90 // any messages, before ever calling this. In that case, just skip
91 // it, since something else is destroying this connection anyway.
92 IncomingMessage.prototype.destroy = function(error) {
94 this.socket.destroy(error);
98 IncomingMessage.prototype._addHeaderLines = function(headers, n) {
99 if (headers && headers.length) {
102 raw = this.rawTrailers;
103 dest = this.trailers;
105 raw = this.rawHeaders;
109 for (var i = 0; i < n; i += 2) {
111 var v = headers[i + 1];
114 this._addHeaderLine(k, v, dest);
120 // Add the given (field, value) pair to the message
122 // Per RFC2616, section 4.2 it is acceptable to join multiple instances of the
123 // same header with a ', ' if the header in question supports specification of
124 // multiple values this way. If not, we declare the first instance the winner
125 // and drop the second. Extended header fields (those beginning with 'x-') are
127 IncomingMessage.prototype._addHeaderLine = function(field, value, dest) {
128 field = field.toLowerCase();
132 if (dest[field] !== undefined) {
133 dest[field].push(value);
135 dest[field] = [value];
139 /* eslint-disable max-len */
140 // list is taken from:
141 // https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
142 /* eslint-enable max-len */
144 case 'content-length':
148 case 'authorization':
149 case 'proxy-authorization':
150 case 'if-modified-since':
151 case 'if-unmodified-since':
156 if (dest[field] === undefined)
161 // make comma-separated list
162 if (dest[field] !== undefined) {
163 dest[field] += ', ' + value;
171 // Call this instead of resume() if we want to just
172 // dump all the data to /dev/null
173 IncomingMessage.prototype._dump = function() {