1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 | 173 173 173 6187 5015 173 173 164 164 173 173 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 3812 173 173 173 173 4 4 4 4 173 3730 3730 3730 173 2407 2403 173 2 2 173 7596 3785 3785 2 2 3783 3783 3785 16396 16396 16396 16396 16396 173 16396 16396 11 5 6 11 4722 4708 4722 11663 35 11628 173 3052 3052 3052 | (function () { 'use strict'; const util = require('util'); const Stream = require('stream'); function readStart(socket) { if (socket && !socket._paused && socket.readable) socket.resume(); } exports.readStart = readStart; function readStop(socket) { Eif (socket) socket.pause(); } exports.readStop = readStop; /* Abstract base class for ServerRequest and ClientResponse. */ function IncomingMessage(socket) { Stream.Readable.call(this); // XXX This implementation is kind of all over the place // When the parser emits body chunks, they go in this list. // _read() pulls them out, and when it finds EOF, it ends. this.socket = socket; this.connection = socket; this.httpVersionMajor = null; this.httpVersionMinor = null; this.httpVersion = null; this.complete = false; this.headers = {}; this.rawHeaders = []; this.trailers = {}; this.rawTrailers = []; this.readable = true; this.upgrade = null; // request (server) only this.url = ''; this.method = null; // response (client) only this.statusCode = null; this.statusMessage = null; this._client = socket; // deprecated // flag for backwards compatibility grossness. this._consuming = false; // flag for when we decide that this message cannot possibly be // read by the user, so there's no point continuing to handle it. this._dumped = false; } util.inherits(IncomingMessage, Stream.Readable); exports.IncomingMessage = IncomingMessage; Object.defineProperty(IncomingMessage.prototype, 'client', { configurable: true, enumerable: true, get: util.deprecate(function() { return this._client; }, 'client is deprecated, use socket or connection instead'), set: util.deprecate(function(val) { this._client = val; }, 'client is deprecated, use socket or connection instead') }); IncomingMessage.prototype.setTimeout = function(msecs, callback) { Eif (callback) this.on('timeout', callback); this.socket.setTimeout(msecs); return this; }; IncomingMessage.prototype.read = function(n) { this._consuming = true; this.read = Stream.Readable.prototype.read; return this.read(n); }; IncomingMessage.prototype._read = function(n) { // We actually do almost nothing here, because the parserOnBody // function fills up our internal buffer directly. However, we // do need to unpause the underlying socket so that it flows. if (this.socket.readable) readStart(this.socket); }; // It's possible that the socket will be destroyed, and removed from // any messages, before ever calling this. In that case, just skip // it, since something else is destroying this connection anyway. IncomingMessage.prototype.destroy = function(error) { Eif (this.socket) this.socket.destroy(error); }; IncomingMessage.prototype._addHeaderLines = function(headers, n) { if (headers && headers.length) { var raw, dest; if (this.complete) { raw = this.rawTrailers; dest = this.trailers; } else { raw = this.rawHeaders; dest = this.headers; } for (var i = 0; i < n; i += 2) { var k = headers[i]; var v = headers[i + 1]; raw.push(k); raw.push(v); this._addHeaderLine(k, v, dest); } } }; // Add the given (field, value) pair to the message // // Per RFC2616, section 4.2 it is acceptable to join multiple instances of the // same header with a ', ' if the header in question supports specification of // multiple values this way. If not, we declare the first instance the winner // and drop the second. Extended header fields (those beginning with 'x-') are // always joined. IncomingMessage.prototype._addHeaderLine = function(field, value, dest) { field = field.toLowerCase(); switch (field) { // Array headers: case 'set-cookie': if (dest[field] !== undefined) { dest[field].push(value); } else { dest[field] = [value]; } break; /* eslint-disable max-len */ // list is taken from: // https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp /* eslint-enable max-len */ case 'content-type': case 'content-length': case 'user-agent': case 'referer': case 'host': case 'authorization': case 'proxy-authorization': case 'if-modified-since': case 'if-unmodified-since': case 'from': case 'location': case 'max-forwards': // drop duplicates if (dest[field] === undefined) dest[field] = value; break; default: // make comma-separated list if (dest[field] !== undefined) { dest[field] += ', ' + value; } else { dest[field] = value; } } }; // Call this instead of resume() if we want to just // dump all the data to /dev/null IncomingMessage.prototype._dump = function() { Eif (!this._dumped) { this._dumped = true; this.resume(); } }; }()); |