this.output = [];
this.outputEncodings = [];
this.outputCallbacks = [];
+ this.outputSize = 0;
this.writable = true;
this._header = null;
this._headers = null;
this._headerNames = {};
+
+ this._onPendingData = null;
}
util.inherits(OutgoingMessage, Stream);
this.output.unshift(this._header);
this.outputEncodings.unshift('binary');
this.outputCallbacks.unshift(null);
+ this.outputSize += this._header.length;
+ if (this._onPendingData !== null)
+ this._onPendingData(this._header.length);
}
this._headerSent = true;
}
this.output = [];
this.outputEncodings = [];
this.outputCallbacks = [];
+ if (this._onPendingData !== null)
+ this._onPendingData(-this.outputSize);
+ this.outputSize = 0;
} else if (data.length === 0) {
if (typeof callback === 'function')
process.nextTick(callback);
this.output.push(data);
this.outputEncodings.push(encoding);
this.outputCallbacks.push(callback);
+ this.outputSize += data.length;
+ if (this._onPendingData !== null)
+ this._onPendingData(data.length);
return false;
};
});
this.timeout = 2 * 60 * 1000;
+
+ this._pendingResponseData = 0;
}
util.inherits(Server, net.Server);
var self = this;
var outgoing = [];
var incoming = [];
+ var outgoingData = 0;
+
+ function updateOutgoingData(delta) {
+ outgoingData += delta;
+ if (socket._paused && outgoingData < socket._writableState.highWaterMark)
+ return socketOnDrain();
+ }
function abortIncoming() {
while (incoming.length) {
socket._paused = false;
function socketOnDrain() {
+ var needPause = outgoingData > socket._writableState.highWaterMark;
+
// If we previously paused, then start reading again.
- if (socket._paused) {
+ if (socket._paused && !needPause) {
socket._paused = false;
socket.parser.resume();
socket.resume();
// so that we don't become overwhelmed by a flood of
// pipelined requests that may never be resolved.
if (!socket._paused) {
- var needPause = socket._writableState.needDrain;
+ var needPause = socket._writableState.needDrain ||
+ outgoingData >= socket._writableState.highWaterMark;
if (needPause) {
socket._paused = true;
// We also need to pause the parser, but don't do that until after
}
var res = new ServerResponse(req);
+ res._onPendingData = updateOutgoingData;
res.shouldKeepAlive = shouldKeepAlive;
DTRACE_HTTP_SERVER_REQUEST(req, socket);