summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2013-05-24 17:16:08 -0700
committerisaacs <i@izs.me>2013-05-27 14:46:52 -0700
commitba048e72b02e17f0c73e0dcb7d37e76a03327c5a (patch)
treebe9aa3f1f745db25ce2fa12116acf07ac48683cd /lib
parent9c7078cea2b719defbb6519d10a14ab15e733822 (diff)
parentf904d614bf62d4bbf9c3adffb485f84d5c77c2d8 (diff)
downloadandroid-node-v8-ba048e72b02e17f0c73e0dcb7d37e76a03327c5a.tar.gz
android-node-v8-ba048e72b02e17f0c73e0dcb7d37e76a03327c5a.tar.bz2
android-node-v8-ba048e72b02e17f0c73e0dcb7d37e76a03327c5a.zip
Merge remote-tracking branch 'ry/v0.10'
Conflicts: AUTHORS ChangeLog configure deps/uv/ChangeLog deps/uv/src/unix/darwin.c deps/uv/src/unix/stream.c deps/uv/src/version.c deps/v8/src/isolate.cc deps/v8/src/version.cc lib/http.js src/node_version.h
Diffstat (limited to 'lib')
-rw-r--r--lib/_http_client.js7
-rw-r--r--lib/_http_outgoing.js5
-rw-r--r--lib/_http_server.js7
-rw-r--r--lib/buffer.js3
-rw-r--r--lib/net.js14
-rw-r--r--lib/timers.js108
-rw-r--r--lib/tls.js9
7 files changed, 142 insertions, 11 deletions
diff --git a/lib/_http_client.js b/lib/_http_client.js
index 339a5c785d..e02cb4f40c 100644
--- a/lib/_http_client.js
+++ b/lib/_http_client.js
@@ -25,6 +25,9 @@ var EventEmitter = require('events').EventEmitter;
var HTTPParser = process.binding('http_parser').HTTPParser;
var assert = require('assert').ok;
+// an empty buffer for UPGRADE/CONNECT bodyHead compatibility
+var emptyBuffer = new Buffer(0);
+
var common = require('_http_common');
var httpSocketSetup = common.httpSocketSetup;
@@ -273,7 +276,9 @@ function socketOnData(d, start, end) {
socket.removeListener('close', socketCloseListener);
socket.removeListener('error', socketErrorListener);
- req.emit(eventName, res, socket, bodyHead);
+ socket.unshift(bodyHead);
+
+ req.emit(eventName, res, socket, emptyBuffer);
req.emit('close');
} else {
// Got Upgrade header or CONNECT method, but have no handler.
diff --git a/lib/_http_outgoing.js b/lib/_http_outgoing.js
index 7248e5a135..8455b91603 100644
--- a/lib/_http_outgoing.js
+++ b/lib/_http_outgoing.js
@@ -402,7 +402,10 @@ OutgoingMessage.prototype.write = function(chunk, encoding) {
throw new TypeError('first argument must be a string or Buffer');
}
- if (chunk.length === 0) return false;
+
+ // If we get an empty string or buffer, then just do nothing, and
+ // signal the user to keep writing.
+ if (chunk.length === 0) return true;
var len, ret;
if (this.chunkedEncoding) {
diff --git a/lib/_http_server.js b/lib/_http_server.js
index bbbcb371d4..9d1adc6320 100644
--- a/lib/_http_server.js
+++ b/lib/_http_server.js
@@ -25,6 +25,9 @@ var EventEmitter = require('events').EventEmitter;
var HTTPParser = process.binding('http_parser').HTTPParser;
var assert = require('assert').ok;
+// an empty buffer for UPGRADE/CONNECT bodyHead compatibility
+var emptyBuffer = new Buffer(0);
+
var common = require('_http_common');
var parsers = common.parsers;
var freeParser = common.freeParser;
@@ -356,7 +359,9 @@ function connectionListener(socket) {
if (EventEmitter.listenerCount(self, eventName) > 0) {
// This is start + byteParsed
var bodyHead = d.slice(start + bytesParsed, end);
- self.emit(eventName, req, req.socket, bodyHead);
+
+ socket.unshift(bodyHead);
+ self.emit(eventName, req, req.socket, emptyBuffer);
} else {
// Got upgrade header or CONNECT method, but have no handler.
socket.destroy();
diff --git a/lib/buffer.js b/lib/buffer.js
index e5fa44d928..48c69f3f2b 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -339,6 +339,9 @@ Buffer.prototype.write = function(string, offset, length, encoding) {
}
encoding = String(encoding || 'utf8').toLowerCase();
+ if (string.length > 0 && (length < 0 || offset < 0))
+ throw new RangeError('attempt to write beyond buffer bounds');
+
var ret;
switch (encoding) {
case 'hex':
diff --git a/lib/net.js b/lib/net.js
index e248bdfb3c..4ada1dc787 100644
--- a/lib/net.js
+++ b/lib/net.js
@@ -298,7 +298,7 @@ Socket.prototype.listen = function() {
Socket.prototype.setTimeout = function(msecs, callback) {
if (msecs > 0 && !isNaN(msecs) && isFinite(msecs)) {
timers.enroll(this, msecs);
- timers.active(this);
+ timers._unrefActive(this);
if (callback) {
this.once('timeout', callback);
}
@@ -472,7 +472,7 @@ function onread(buffer, offset, length) {
var self = handle.owner;
assert(handle === self._handle, 'handle != self._handle');
- timers.active(self);
+ timers._unrefActive(self);
var end = offset + length;
debug('onread', process._errno, offset, length, end);
@@ -603,7 +603,7 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) {
this._pendingData = null;
this._pendingEncoding = '';
- timers.active(this);
+ timers._unrefActive(this);
if (!this._handle) {
this._destroy(new Error('This socket is closed.'), cb);
@@ -744,7 +744,7 @@ function afterWrite(status, handle, req) {
return;
}
- timers.active(self);
+ timers._unrefActive(self);
if (self !== process.stderr && self !== process.stdout)
debug('afterWrite call cb');
@@ -825,7 +825,7 @@ Socket.prototype.connect = function(options, cb) {
self.once('connect', cb);
}
- timers.active(this);
+ timers._unrefActive(this);
self._connecting = true;
self.writable = true;
@@ -858,7 +858,7 @@ Socket.prototype.connect = function(options, cb) {
self._destroy();
});
} else {
- timers.active(self);
+ timers._unrefActive(self);
addressType = addressType || 4;
@@ -905,7 +905,7 @@ function afterConnect(status, handle, req, readable, writable) {
if (status == 0) {
self.readable = readable;
self.writable = writable;
- timers.active(self);
+ timers._unrefActive(self);
self.emit('connect');
diff --git a/lib/timers.js b/lib/timers.js
index 1412928c51..8911e2ebf7 100644
--- a/lib/timers.js
+++ b/lib/timers.js
@@ -368,3 +368,111 @@ exports.clearImmediate = function(immediate) {
process._needImmediateCallback = false;
}
};
+
+
+// Internal APIs that need timeouts should use timers._unrefActive isntead of
+// timers.active as internal timeouts shouldn't hold the loop open
+
+var unrefList, unrefTimer;
+
+
+function unrefTimeout() {
+ var now = Date.now();
+
+ debug('unrefTimer fired');
+
+ var first;
+ while (first = L.peek(unrefList)) {
+ var diff = now - first._idleStart;
+
+ if (diff < first._idleTimeout) {
+ diff = first._idleTimeout - diff;
+ unrefTimer.start(diff, 0);
+ unrefTimer.when = now + diff;
+ debug('unrefTimer rescheudling for later');
+ return;
+ }
+
+ L.remove(first);
+
+ var domain = first.domain;
+
+ if (!first._onTimeout) continue;
+ if (domain && domain._disposed) continue;
+
+ try {
+ if (domain) domain.enter();
+ var threw = true;
+ debug('unreftimer firing timeout');
+ first._onTimeout();
+ threw = false;
+ if (domain) domain.exit();
+ } finally {
+ if (threw) process.nextTick(unrefTimeout);
+ }
+ }
+
+ debug('unrefList is empty');
+ unrefTimer.when = -1;
+}
+
+
+exports._unrefActive = function(item) {
+ var msecs = item._idleTimeout;
+ if (!msecs || msecs < 0) return;
+ assert(msecs >= 0);
+
+ L.remove(item);
+
+ if (!unrefList) {
+ debug('unrefList initialized');
+ unrefList = {};
+ L.init(unrefList);
+
+ debug('unrefTimer initialized');
+ unrefTimer = new Timer();
+ unrefTimer.unref();
+ unrefTimer.when = -1;
+ unrefTimer.ontimeout = unrefTimeout;
+ }
+
+ var now = Date.now();
+ item._idleStart = now;
+
+ if (L.isEmpty(unrefList)) {
+ debug('unrefList empty');
+ L.append(unrefList, item);
+
+ unrefTimer.start(msecs, 0);
+ unrefTimer.when = now + msecs;
+ debug('unrefTimer scheduled');
+ return;
+ }
+
+ var when = now + msecs;
+
+ debug('unrefList find where we can insert');
+
+ var cur, them;
+
+ for (cur = unrefList._idlePrev; cur != unrefList; cur = cur._idlePrev) {
+ them = cur._idleStart + cur._idleTimeout;
+
+ if (when < them) {
+ debug('unrefList inserting into middle of list');
+
+ L.append(cur, item);
+
+ if (unrefTimer.when > when) {
+ debug('unrefTimer is scheduled to fire too late, reschedule');
+ unrefTimer.start(msecs, 0);
+ unrefTimer.when = when;
+ }
+
+ return;
+ }
+ }
+
+ debug('unrefList append to end');
+ L.append(unrefList, item);
+};
diff --git a/lib/tls.js b/lib/tls.js
index cc71bd9761..4f170324b9 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -249,6 +249,7 @@ function CryptoStream(pair, options) {
this._pendingEncoding = '';
this._pendingCallback = null;
this._doneFlag = false;
+ this._retryAfterPartial = false;
this._resumingSession = false;
this._reading = true;
this._destroyed = false;
@@ -357,7 +358,13 @@ CryptoStream.prototype._write = function write(data, encoding, cb) {
return cb(null);
}
- assert(written === 0 || written === -1);
+ if (written !== 0 && written !== -1) {
+ assert(!this._retryAfterPartial);
+ this._retryAfterPartial = true;
+ this._write(data.slice(written), encoding, cb);
+ this._retryAfterPartial = false;
+ return;
+ }
} else {
debug('cleartext.write queue is full');