mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
6ac8bdc0ab
Many of the util.is*() methods used to check data types simply compare against a single value or the result of typeof. This commit replaces calls to these methods with equivalent checks. This commit does not touch calls to the more complex methods (isRegExp(), isDate(), etc.). Fixes: https://github.com/iojs/io.js/issues/607 PR-URL: https://github.com/iojs/io.js/pull/647 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
178 lines
4.4 KiB
JavaScript
178 lines
4.4 KiB
JavaScript
'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) {
|
|
if (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._pendings = [];
|
|
this._pendingIndex = 0;
|
|
this.upgrade = null;
|
|
|
|
// request (server) only
|
|
this.url = '';
|
|
this.method = null;
|
|
|
|
// response (client) only
|
|
this.statusCode = null;
|
|
this.statusMessage = null;
|
|
this.client = this.socket;
|
|
|
|
// 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;
|
|
|
|
|
|
IncomingMessage.prototype.setTimeout = function(msecs, callback) {
|
|
if (callback)
|
|
this.on('timeout', callback);
|
|
this.socket.setTimeout(msecs);
|
|
};
|
|
|
|
|
|
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) {
|
|
if (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;
|
|
|
|
// list is taken from:
|
|
// https://mxr.mozilla.org/mozilla/source/netwerk/protocol/http/src/nsHttpHeaderArray.cpp
|
|
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() {
|
|
if (!this._dumped) {
|
|
this._dumped = true;
|
|
this.resume();
|
|
}
|
|
};
|