Browse Source

Merge branch 'v0.4'

Conflicts:
	lib/tls.js
	lib/url.js
	src/node_version.h
	test/simple/test-buffer.js
	test/simple/test-url.js
v0.7.4-release
isaacs 14 years ago
parent
commit
205b9beb6b
  1. 2
      AUTHORS
  2. 18
      ChangeLog
  3. 8
      deps/v8/src/arm/code-stubs-arm.cc
  4. 4
      deps/v8/src/builtins.cc
  5. 2
      deps/v8/src/runtime.cc
  6. 2
      deps/v8/src/version.cc
  7. 6
      doc/api/http.markdown
  8. 10
      doc/api/https.markdown
  9. 4
      doc/api/vm.markdown
  10. 22
      doc/index.html
  11. 62
      lib/_debugger.js
  12. 2
      lib/buffer.js
  13. 9
      lib/http.js
  14. 8
      lib/repl.js
  15. 88
      lib/stream.js
  16. 185
      lib/tls.js
  17. 85
      lib/url.js
  18. 19
      src/node.cc
  19. 2
      src/node.h
  20. 9
      src/platform_sunos.cc
  21. 33
      test/message/stack_overflow.js
  22. 6
      test/message/stack_overflow.out
  23. 30
      test/message/throw_custom_error.js
  24. 6
      test/message/throw_custom_error.out
  25. 30
      test/message/throw_non_error.js
  26. 6
      test/message/throw_non_error.out
  27. 5
      test/simple/test-buffer.js
  28. 2
      test/simple/test-https-eof-for-eom.js
  29. 14
      test/simple/test-regress-GH-897.js
  30. 4
      test/simple/test-stream-pipe-cleanup.js
  31. 100
      test/simple/test-stream-pipe-multi.js
  32. 89
      test/simple/test-url.js
  33. 26
      wscript

2
AUTHORS

@ -170,4 +170,6 @@ Arnout Kazemier <info@3rd-Eden.com>
George Stagas <gstagas@gmail.com>
Scott McWhirter <scott.mcwhirter@joyent.com>
Jakub Lekstan <jakub.lekstan@dreamlab.pl>
Tim Baumann <tim@timbaumann.info>
Robert Mustacchi <rm@joyent.com>

18
ChangeLog

@ -1,3 +1,21 @@
2011.04.22, Version 0.4.7 (stable)
* Don't emit error on ECONNRESET from read() #670
* Fix: Multiple pipes to the same stream were broken #929
(Felix Geisendörfer)
* URL parsing/formatting corrections #954 (isaacs)
* make it possible to do repl.start('', stream) (Wade Simmons)
* Add os.loadavg for SunOS (Robert Mustacchi)
* Fix timeouts with floating point numbers #897 (Jorge Chamorro Bieling)
* Improve docs.
2011.04.13, Version 0.4.6 (stable)
* Don't error on ENOTCONN from shutdown() #670

8
deps/v8/src/arm/code-stubs-arm.cc

@ -3425,6 +3425,8 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// Save the left value on the stack.
__ Push(r5, r4);
Label pop_and_call_runtime;
// Allocate a heap number to store the result.
heap_number_result = r5;
GenerateHeapResultAllocation(masm,
@ -3432,7 +3434,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
heap_number_map,
scratch1,
scratch2,
&call_runtime);
&pop_and_call_runtime);
// Load the left value from the value saved on the stack.
__ Pop(r1, r0);
@ -3440,6 +3442,10 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
// Call the C function to handle the double operation.
FloatingPointHelper::CallCCodeForDoubleOperation(
masm, op_, heap_number_result, scratch1);
__ bind(&pop_and_call_runtime);
__ Drop(2);
__ b(&call_runtime);
}
break;

4
deps/v8/src/builtins.cc

@ -818,8 +818,8 @@ BUILTIN(ArraySplice) {
const int delta = actual_delete_count - item_count;
if (actual_start > 0) {
Object** start = elms->data_start();
memmove(start + delta, start, actual_start * kPointerSize);
AssertNoAllocation no_gc;
MoveElements(&no_gc, elms, delta, elms, 0, actual_start);
}
elms = LeftTrimFixedArray(elms, delta);

2
deps/v8/src/runtime.cc

@ -2625,7 +2625,7 @@ MUST_USE_RESULT static MaybeObject* StringReplaceRegExpWithEmptyString(
end = RegExpImpl::GetCapture(match_info_array, 1);
}
int length = subject->length();
int length = subject_handle->length();
int new_length = length - (end - start);
if (new_length == 0) {
return Heap::empty_string();

2
deps/v8/src/version.cc

@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 1
#define BUILD_NUMBER 8
#define PATCH_LEVEL 10
#define PATCH_LEVEL 14
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the

6
doc/api/http.markdown

@ -88,7 +88,7 @@ sent to the server on that socket.
If a client connection emits an 'error' event - it will forwarded here.
### http.createServer(requestListener)
### http.createServer([requestListener])
Returns a new web server object.
@ -397,6 +397,10 @@ Example:
});
});
req.on('error', function(e) {
console.log('problem with request: ' + e.message);
});
// write data to request body
req.write('data\n');
req.write('data\n');

10
doc/api/https.markdown

@ -4,7 +4,15 @@ HTTPS is the HTTP protocol over TLS/SSL. In Node this is implemented as a
separate module.
## https.Server
## https.createServer
This class is a subclass of `tls.Server` and emits events same as
`http.Server`. See `http.Server` for more information.
## https.createServer(options, [requestListener])
Returns a new HTTPS web server object. The `options` is similer to
`tls.createServer()`. The `requestListener` is a function which is
automatically added to the `'request'` event.
Example:

4
doc/api/vm.markdown

@ -33,7 +33,7 @@ Example of using `vm.runInThisContext` and `eval` to run the same code:
`eval` does have access to the local scope, so `localVar` is changed.
In case of syntax error in `code`, `vm.runInThisContext` emits the syntax error to stderr
and throws.an exception.
and throws an exception.
### vm.runInNewContext(code, [sandbox], [filename])
@ -62,7 +62,7 @@ Note that running untrusted code is a tricky business requiring great care. To
global variable leakage, `vm.runInNewContext` is quite useful, but safely running untrusted code
requires a separate process.
In case of syntax error in `code`, `vm.runInThisContext` emits the syntax error to stderr
In case of syntax error in `code`, `vm.runInNewContext` emits the syntax error to stderr
and throws an exception.

22
doc/index.html

@ -24,9 +24,9 @@
<div id="toc">
<ol>
<li><a href="#download">Download</a></li>
<li><a href="https://github.com/joyent/node/raw/master/ChangeLog">ChangeLog</a></li>
<li><a href="https://github.com/joyent/node/raw/v0.4/ChangeLog">ChangeLog</a></li>
<li><a href="#about">About</a></li>
<li><a href="http://nodejs.org/docs/v0.4.6/api">v0.4.6 docs</a></li>
<li><a href="http://nodejs.org/docs/v0.4.7/api">v0.4.7 docs</a></li>
<br/>
<li><a href="https://github.com/joyent/node/wiki">Wiki</a></li>
<li><a href="http://blog.nodejs.org/">Blog</a></li>
@ -55,8 +55,8 @@ var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(8124, "127.0.0.1");
console.log('Server running at http://127.0.0.1:8124/');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');
</pre>
<p>
@ -66,10 +66,10 @@ console.log('Server running at http://127.0.0.1:8124/');
</p>
<pre class="sh_none">
% node example.js
Server running at http://127.0.0.1:8124/</pre>
Server running at http://127.0.0.1:1337/</pre>
<p>
Here is an example of a simple TCP server which listens on port 8124
Here is an example of a simple TCP server which listens on port 1337
and echoes whatever you send it:
</p>
@ -79,9 +79,9 @@ var net = require('net');
var server = net.createServer(function (socket) {
socket.write("Echo server\r\n");
socket.pipe(socket);
})
});
server.listen(8124, "127.0.0.1");
server.listen(1337, "127.0.0.1");
</pre>
<p>
@ -107,9 +107,9 @@ server.listen(8124, "127.0.0.1");
</p>
<p>
2011.04.13
<a href="http://nodejs.org/dist/node-v0.4.6.tar.gz">node-v0.4.6.tar.gz</a>
(<a href="http://nodejs.org/docs/v0.4.6/api/index.html">Documentation</a>)
2011.04.22
<a href="http://nodejs.org/dist/node-v0.4.7.tar.gz">node-v0.4.7.tar.gz</a>
(<a href="http://nodejs.org/docs/v0.4.7/api/index.html">Documentation</a>)
</p>
<p>Historical: <a href="http://nodejs.org/dist">versions</a>, <a href="http://nodejs.org/docs">docs</a></p>

62
lib/_debugger.js

@ -291,7 +291,10 @@ Client.prototype.reqEval = function(expression, cb) {
var frame = bt.frames[self.currentFrame];
var evalFrames = frame.scopes.map(function(s) {
return bt.frames[s.index].index;
if (!s) return;
var x = bt.frames[s.index];
if (!x) return;
return x.index;
});
self._reqFramesEval(expression, evalFrames, cb);
@ -1043,19 +1046,16 @@ Interface.prototype.trySpawn = function(cb) {
this.pause();
setTimeout(function() {
process.stdout.write('connecting...');
var client = self.client = new Client();
client.connect(exports.port);
var client = self.client = new Client();
var connectionAttempts = 0;
client.once('ready', function() {
process.stdout.write('ok\r\n');
client.once('ready', function() {
process.stdout.write(' ok\r\n');
// since we did debug-brk, we're hitting a break point immediately
// continue before anything else.
client.reqContinue(function() {
if (cb) cb();
});
// since we did debug-brk, we're hitting a break point immediately
// continue before anything else.
client.reqContinue(function() {
if (cb) cb();
});
client.on('close', function() {
@ -1064,17 +1064,37 @@ Interface.prototype.trySpawn = function(cb) {
self.killChild();
if (!self.quitting) self.term.prompt();
});
});
client.on('unhandledResponse', function(res) {
console.log('\r\nunhandled res:');
console.log(res);
self.term.prompt();
});
client.on('unhandledResponse', function(res) {
console.log('\r\nunhandled res:');
console.log(res);
self.term.prompt();
});
client.on('break', function(res) {
self.handleBreak(res.body);
});
}, 100);
client.on('break', function(res) {
self.handleBreak(res.body);
});
client.on('error', connectError);
function connectError() {
// If it's failed to connect 4 times then don't catch the next error
if (connectionAttempts >= 4) {
client.removeListener('error', connectError);
}
setTimeout(attemptConnect, 50);
}
function attemptConnect() {
++connectionAttempts;
process.stdout.write('.');
client.connect(exports.port);
}
setTimeout(function() {
process.stdout.write('connecting..');
attemptConnect();
}, 50);
};

2
lib/buffer.js

@ -139,7 +139,7 @@ SlowBuffer.prototype.write = function(string, offset, encoding) {
case 'ucs2':
case 'ucs-2':
return this.ucs2Write(start, end);
return this.ucs2Write(string, offset);
default:
throw new Error('Unknown encoding');

9
lib/http.js

@ -1196,13 +1196,12 @@ Agent.prototype._establishNewConnection = function() {
req = self.queue.shift();
assert(req._queue === self.queue);
req._queue = null;
} else {
// No requests on queue? Where is the request
assert(0);
}
req.emit('error', err);
req._hadError = true; // hacky
if (req) {
req.emit('error', err);
req._hadError = true; // hacky
}
// clean up so that agent can handle new requests
parser.finish();

8
lib/repl.js

@ -80,7 +80,7 @@ function REPLServer(prompt, stream) {
process.stdin.resume();
}
self.prompt = prompt || '> ';
self.prompt = (prompt != undefined ? prompt : '> ');
function complete(text) {
return self.complete(text);
@ -92,7 +92,7 @@ function REPLServer(prompt, stream) {
this.commands = {};
defineDefaultCommands(this);
if (rli.enabled && !disableColors) {
if (rli.enabled && !disableColors && exports.writer === util.inspect) {
// Turn on ANSI coloring.
exports.writer = function(obj, showHidden, depth) {
return util.inspect(obj, showHidden, depth, true);
@ -181,8 +181,8 @@ function REPLServer(prompt, stream) {
// It could also be an error from JSON.parse
} else if (e &&
e.stack &&
e.stack.match('Unexpected token ILLEGAL') &&
e.stack.match(/Object.parse \(native\)/)) {
e.stack.match(/^SyntaxError: Unexpected token .*\n/) &&
e.stack.match(/\n at Object.parse \(native\)\n/)) {
throw e;
}
}

88
lib/stream.js

@ -28,13 +28,9 @@ function Stream() {
util.inherits(Stream, events.EventEmitter);
exports.Stream = Stream;
var pipes = [];
Stream.prototype.pipe = function(dest, options) {
var source = this;
pipes.push(dest);
function ondata(chunk) {
if (dest.writable) {
if (false === dest.write(chunk)) source.pause();
@ -49,31 +45,66 @@ Stream.prototype.pipe = function(dest, options) {
dest.on('drain', ondrain);
/*
* If the 'end' option is not supplied, dest.end() will be called when
* source gets the 'end' event.
*/
// If the 'end' option is not supplied, dest.end() will be called when
// source gets the 'end' or 'close' events. Only dest.end() once, and
// only when all sources have ended.
if (!options || options.end !== false) {
function onend() {
var index = pipes.indexOf(dest);
pipes.splice(index, 1);
dest._pipeCount = dest._pipeCount || 0;
dest._pipeCount++;
source.on('end', onend);
source.on('close', onclose);
}
if (pipes.indexOf(dest) > -1) {
return;
}
var didOnEnd = false;
function onend() {
if (didOnEnd) return;
didOnEnd = true;
dest.end();
dest._pipeCount--;
// remove the listeners
cleanup();
if (dest._pipeCount > 0) {
// waiting for other incoming streams to end.
return;
}
source.on('end', onend);
source.on('close', onend);
dest.end();
}
/*
* Questionable:
*/
function onclose() {
if (didOnEnd) return;
didOnEnd = true;
dest._pipeCount--;
// remove the listeners
cleanup();
if (dest._pipeCount > 0) {
// waiting for other incoming streams to end.
return;
}
dest.destroy();
}
// don't leave dangling pipes when there are errors.
function onerror(er) {
cleanup();
if (this.listeners('error').length === 1) {
throw er; // Unhandled stream error in pipe.
}
}
source.on('error', onerror);
dest.on('error', onerror);
// guarantee that source streams can be paused and resumed, even
// if the only effect is to proxy the event back up the pipe chain.
if (!source.pause) {
source.pause = function() {
source.emit('pause');
@ -86,27 +117,32 @@ Stream.prototype.pipe = function(dest, options) {
};
}
var onpause = function() {
function onpause() {
source.pause();
}
dest.on('pause', onpause);
var onresume = function() {
function onresume() {
if (source.readable) source.resume();
};
}
dest.on('resume', onresume);
var cleanup = function () {
// remove all the event listeners that were added.
function cleanup() {
source.removeListener('data', ondata);
dest.removeListener('drain', ondrain);
source.removeListener('end', onend);
source.removeListener('close', onend);
source.removeListener('close', onclose);
dest.removeListener('pause', onpause);
dest.removeListener('resume', onresume);
source.removeListener('error', onerror);
dest.removeListener('error', onerror);
source.removeListener('end', cleanup);
source.removeListener('close', cleanup);

185
lib/tls.js

@ -79,7 +79,7 @@ function CryptoStream(pair) {
this.readable = this.writable = true;
this._writeState = true;
this._paused = false;
this._pending = [];
this._pendingCallbacks = [];
this._pendingBytes = 0;
@ -118,11 +118,10 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
this._pending.push(data);
this._pendingCallbacks.push(cb);
this._pendingBytes += data.length;
this.pair._writeCalled = true;
this.pair._cycle();
this.pair.cycle();
return this._pendingBytes < 128 * 1024;
};
@ -130,14 +129,14 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
CryptoStream.prototype.pause = function() {
debug('paused ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted'));
this._writeState = false;
this._paused = true;
};
CryptoStream.prototype.resume = function() {
debug('resume ' + (this == this.pair.cleartext ? 'cleartext' : 'encrypted'));
this._writeState = true;
this.pair._cycle();
this._paused = false;
this.pair.cycle();
};
@ -175,8 +174,8 @@ function parseCertString(s) {
CryptoStream.prototype.getPeerCertificate = function() {
if (this.pair._ssl) {
var c = this.pair._ssl.getPeerCertificate();
if (this.pair.ssl) {
var c = this.pair.ssl.getPeerCertificate();
if (c) {
if (c.issuer) c.issuer = parseCertString(c.issuer);
@ -190,8 +189,8 @@ CryptoStream.prototype.getPeerCertificate = function() {
CryptoStream.prototype.getCipher = function(err) {
if (this.pair._ssl) {
return this.pair._ssl.getCurrentCipher();
if (this.pair.ssl) {
return this.pair.ssl.getCurrentCipher();
} else {
return null;
}
@ -199,23 +198,22 @@ CryptoStream.prototype.getCipher = function(err) {
CryptoStream.prototype.end = function(d) {
if (this.writable) {
if (this.pair._done) return;
if (this.pair._doneFlag) return;
if (!this.writable) return;
if (d) {
this.write(d);
}
if (d) {
this.write(d);
}
this._pending.push(END_OF_FILE);
this._pendingCallbacks.push(null);
this._pending.push(END_OF_FILE);
this._pendingCallbacks.push(null);
// If this is an encrypted stream then we need to disable further 'data'
// events.
// If this is an encrypted stream then we need to disable further 'data'
// events.
this.writable = false;
this.writable = false;
this.pair._cycle();
}
this.pair.cycle();
};
@ -229,8 +227,8 @@ CryptoStream.prototype.destroySoon = function(err) {
CryptoStream.prototype.destroy = function(err) {
if (this.pair._done) return;
this.pair._destroy();
if (this.pair._doneFlag) return;
this.pair.destroy();
};
@ -239,9 +237,9 @@ CryptoStream.prototype._done = function() {
if (this.pair.cleartext._doneFlag &&
this.pair.encrypted._doneFlag &&
!this.pair._done) {
!this.pair._doneFlag) {
// If both streams are done:
this.pair._destroy();
this.pair.destroy();
}
};
@ -269,7 +267,7 @@ CryptoStream.prototype._push = function() {
return;
}
while (this._writeState == true) {
while (!this._paused) {
var bytesRead = 0;
var chunkBytes = 0;
var pool = new Buffer(16 * 4096); // alloc every time?
@ -277,18 +275,18 @@ CryptoStream.prototype._push = function() {
do {
chunkBytes = this._pusher(pool, bytesRead, pool.length - bytesRead);
if (this.pair._ssl && this.pair._ssl.error) {
this.pair._error();
if (this.pair.ssl && this.pair.ssl.error) {
this.pair.error();
return;
}
this.pair._maybeInitFinished();
this.pair.maybeInitFinished();
if (chunkBytes >= 0) {
bytesRead += chunkBytes;
}
} while ((chunkBytes > 0) && (bytesRead < pool.length));
} while (chunkBytes > 0 && bytesRead < pool.length);
assert(bytesRead >= 0);
@ -341,7 +339,7 @@ CryptoStream.prototype._pull = function() {
assert(havePending || this._pendingBytes == 0);
while (this._pending.length > 0) {
if (!this.pair._ssl) break;
if (!this.pair.ssl) break;
var tmp = this._pending.shift();
var cb = this._pendingCallbacks.shift();
@ -358,7 +356,7 @@ CryptoStream.prototype._pull = function() {
assert(this === this.pair.cleartext);
debug('end cleartext');
this.pair._ssl.shutdown();
this.pair.ssl.shutdown();
// TODO check if we get EAGAIN From shutdown, would have to do it
// again. should unshift END_OF_FILE back onto pending and wait for
@ -366,7 +364,7 @@ CryptoStream.prototype._pull = function() {
this.pair.encrypted._destroyAfterPush = true;
}
this.pair._cycle();
this.pair.cycle();
this._done()
return;
}
@ -375,12 +373,12 @@ CryptoStream.prototype._pull = function() {
var rv = this._puller(tmp);
if (this.pair._ssl && this.pair._ssl.error) {
this.pair._error();
if (this.pair.ssl && this.pair.ssl.error) {
this.pair.error();
return;
}
this.pair._maybeInitFinished();
this.pair.maybeInitFinished();
if (rv === 0 || rv < 0) {
this._pending.unshift(tmp);
@ -412,8 +410,8 @@ util.inherits(CleartextStream, CryptoStream);
CleartextStream.prototype._internallyPendingBytes = function() {
if (this.pair._ssl) {
return this.pair._ssl.clearPending();
if (this.pair.ssl) {
return this.pair.ssl.clearPending();
} else {
return 0;
}
@ -422,14 +420,14 @@ CleartextStream.prototype._internallyPendingBytes = function() {
CleartextStream.prototype._puller = function(b) {
debug('clearIn ' + b.length + ' bytes');
return this.pair._ssl.clearIn(b, 0, b.length);
return this.pair.ssl.clearIn(b, 0, b.length);
};
CleartextStream.prototype._pusher = function(pool, offset, length) {
debug('reading from clearOut');
if (!this.pair._ssl) return -1;
return this.pair._ssl.clearOut(pool, offset, length);
if (!this.pair.ssl) return -1;
return this.pair.ssl.clearOut(pool, offset, length);
};
@ -440,8 +438,8 @@ util.inherits(EncryptedStream, CryptoStream);
EncryptedStream.prototype._internallyPendingBytes = function() {
if (this.pair._ssl) {
return this.pair._ssl.encPending();
if (this.pair.ssl) {
return this.pair.ssl.encPending();
} else {
return 0;
}
@ -450,14 +448,14 @@ EncryptedStream.prototype._internallyPendingBytes = function() {
EncryptedStream.prototype._puller = function(b) {
debug('writing from encIn');
return this.pair._ssl.encIn(b, 0, b.length);
return this.pair.ssl.encIn(b, 0, b.length);
};
EncryptedStream.prototype._pusher = function(pool, offset, length) {
debug('reading from encOut');
if (!this.pair._ssl) return -1;
return this.pair._ssl.encOut(pool, offset, length);
if (!this.pair.ssl) return -1;
return this.pair.ssl.encOut(pool, offset, length);
};
@ -483,9 +481,7 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
this._isServer = isServer ? true : false;
this._encWriteState = true;
this._clearWriteState = true;
this._done = false;
var crypto = require('crypto');
this._doneFlag = false;
if (!credentials) {
this.credentials = crypto.createCredentials();
@ -503,13 +499,13 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
this._rejectUnauthorized = rejectUnauthorized ? true : false;
this._requestCert = requestCert ? true : false;
this._ssl = new Connection(this.credentials.context,
this.ssl = new Connection(this.credentials.context,
this._isServer ? true : false,
this._requestCert,
this._rejectUnauthorized);
if (NPN_ENABLED && NPNProtocols) {
this._ssl.setNPNProtocols(NPNProtocols);
this.ssl.setNPNProtocols(NPNProtocols);
this.npnProtocol = null;
}
@ -520,8 +516,8 @@ function SecurePair(credentials, isServer, requestCert, rejectUnauthorized,
this.encrypted = new EncryptedStream(this);
process.nextTick(function() {
self._ssl.start();
self._cycle();
self.ssl.start();
self.cycle();
});
}
@ -569,63 +565,57 @@ exports.createSecurePair = function(credentials,
* Because it is also called everywhere, we also check if the connection has
* completed negotiation and emit 'secure' from here if it has.
*/
SecurePair.prototype._cycle = function(depth) {
SecurePair.prototype.cycle = function(depth) {
if (this._doneFlag) return;
depth = depth ? depth : 0;
if (this._done) {
return;
}
if(depth == 0) this._writeCalled = false;
if (depth == 0) this._writeCalled = false;
var established = this._secureEstablished;
if (!this._cycleEncryptedPullLock) {
this._cycleEncryptedPullLock = true;
if (!this.cycleEncryptedPullLock) {
this.cycleEncryptedPullLock = true;
debug("encrypted._pull");
this.encrypted._pull();
this._cycleEncryptedPullLock = false;
this.cycleEncryptedPullLock = false;
}
if (!this._cycleCleartextPullLock) {
this._cycleCleartextPullLock = true;
if (!this.cycleCleartextPullLock) {
this.cycleCleartextPullLock = true;
debug("cleartext._pull");
this.cleartext._pull();
this._cycleCleartextPullLock = false;
this.cycleCleartextPullLock = false;
}
if (!this._cycleCleartextPushLock) {
this._cycleCleartextPushLock = true;
if (!this.cycleCleartextPushLock) {
this.cycleCleartextPushLock = true;
debug("cleartext._push");
this.cleartext._push();
this._cycleCleartextPushLock = false;
this.cycleCleartextPushLock = false;
}
if (!this._cycleEncryptedPushLock) {
this._cycleEncryptedPushLock = true;
if (!this.cycleEncryptedPushLock) {
this.cycleEncryptedPushLock = true;
debug("encrypted._push");
this.encrypted._push();
this._cycleEncryptedPushLock = false;
}
if (this._done) {
return;
this.cycleEncryptedPushLock = false;
}
if ((!established && this._secureEstablished) ||
(depth == 0 && this._writeCalled)) {
// If we were not established but now we are, let's cycle again.
// Or if there is some data to write...
this._cycle(depth + 1);
this.cycle(depth + 1);
}
};
SecurePair.prototype._maybeInitFinished = function() {
if (this._ssl && !this._secureEstablished && this._ssl.isInitFinished()) {
SecurePair.prototype.maybeInitFinished = function() {
if (this.ssl && !this._secureEstablished && this.ssl.isInitFinished()) {
if (NPN_ENABLED) {
this.npnProtocol = this._ssl.getNegotiatedProtocol();
this.npnProtocol = this.ssl.getNegotiatedProtocol();
}
this._secureEstablished = true;
debug('secure established');
this.emit('secure');
@ -633,45 +623,38 @@ SecurePair.prototype._maybeInitFinished = function() {
};
SecurePair.prototype._destroy = function() {
SecurePair.prototype.destroy = function() {
var self = this;
if (!this._done) {
this._done = true;
this._ssl.error = null;
this._ssl.close();
this._ssl = null;
if (!this._doneFlag) {
this._doneFlag = true;
this.ssl.error = null;
this.ssl.close();
this.ssl = null;
self.encrypted.writable = self.encrypted.readable = false;
self.cleartext.writable = self.cleartext.readable = false;
process.nextTick(function() {
self.encrypted.emit('end');
if (self.encrypted.onend) self.encrypted.onend();
self.encrypted.emit('close');
self.cleartext.emit('end');
if (self.cleartext.onend) self.cleartext.onend();
self.cleartext.emit('close');
});
}
this._cycle();
};
SecurePair.prototype._error = function() {
SecurePair.prototype.error = function() {
if (!this._secureEstablished) {
this._destroy();
this.destroy();
} else {
var err = this._ssl.error;
this._ssl.error = null;
var err = this.ssl.error;
this.ssl.error = null;
if (this._isServer &&
this._rejectUnauthorized &&
/peer did not return a certificate/.test(err.message)) {
// Not really an error.
this._destroy();
this.destroy();
} else {
this.cleartext.emit('error', err);
}
@ -796,13 +779,13 @@ function Server(/* [options], listener */) {
cleartext._controlReleased = true;
self.emit('secureConnection', pair.cleartext, pair.encrypted);
} else {
var verifyError = pair._ssl.verifyError();
var verifyError = pair.ssl.verifyError();
if (verifyError) {
pair.cleartext.authorizationError = verifyError;
if (self.rejectUnauthorized) {
socket.destroy();
pair._destroy();
pair.destroy();
} else {
cleartext._controlReleased = true;
self.emit('secureConnection', pair.cleartext, pair.encrypted);
@ -904,7 +887,7 @@ exports.connect = function(port /* host, options, cb */) {
socket.connect(port, host);
pair.on('secure', function() {
var verifyError = pair._ssl.verifyError();
var verifyError = pair.ssl.verifyError();
cleartext.npnProtocol = pair.npnProtocol;

85
lib/url.js

@ -24,25 +24,40 @@ exports.resolve = urlResolve;
exports.resolveObject = urlResolveObject;
exports.format = urlFormat;
// Reference: RFC 3986, RFC 1808, RFC 2396
// define these here so at least they only have to be
// compiled once on the first module load.
var protocolPattern = /^([a-z0-9]+:)/i,
portPattern = /:[0-9]+$/,
delims = ['<', '>', '"', '\'', '`', /\s/],
// RFC 2396: characters reserved for delimiting URLs.
delims = ['<', '>', '"', '`', ' ', '\r', '\n', '\t'],
// RFC 2396: characters not allowed for various reasons.
unwise = ['{', '}', '|', '\\', '^', '~', '[', ']', '`'].concat(delims),
nonHostChars = ['/', '?', ';', '#'].concat(unwise),
// Allowed by RFCs, but cause of XSS attacks. Always escape these.
autoEscape = ['\''],
// Characters that are never ever allowed in a hostname.
// Note that any invalid chars are also handled, but these
// are the ones that are *expected* to be seen, so we fast-path
// them.
nonHostChars = ['%', '/', '?', ';', '#']
.concat(unwise).concat(autoEscape),
hostnameMaxLen = 255,
hostnamePartPattern = /^[a-z0-9][a-z0-9A-Z-]{0,62}$/,
hostnamePartPattern = /^[a-zA-Z0-9][a-z0-9A-Z-]{0,62}$/,
hostnamePartStart = /^([a-zA-Z0-9][a-z0-9A-Z-]{0,62})(.*)$/,
// protocols that can allow "unsafe" and "unwise" chars.
unsafeProtocol = {
'javascript': true,
'javascript:': true
},
// protocols that never have a hostname.
hostlessProtocol = {
'javascript': true,
'javascript:': true,
'file': true,
'file:': true
},
// protocols that always have a path component.
pathedProtocol = {
'http': true,
'https': true,
@ -54,6 +69,7 @@ var protocolPattern = /^([a-z0-9]+:)/i,
'gopher:': true,
'file:': true
},
// protocols that always contain a // bit.
slashedProtocol = {
'http': true,
'https': true,
@ -71,17 +87,23 @@ var protocolPattern = /^([a-z0-9]+:)/i,
function urlParse(url, parseQueryString, slashesDenoteHost) {
if (url && typeof(url) === 'object' && url.href) return url;
var out = { href: '' },
var out = {},
rest = url;
var proto = protocolPattern.exec(rest),
lowerProto = proto;
// cut off any delimiters.
// This is to support parse stuff like "<http://foo.com>"
for (var i = 0, l = rest.length; i < l; i++) {
if (delims.indexOf(rest.charAt(i)) === -1) break;
}
if (i !== 0) rest = rest.substr(i);
var proto = protocolPattern.exec(rest);
if (proto) {
proto = proto[0];
lowerProto = proto.toLowerCase();
var lowerProto = proto.toLowerCase();
out.protocol = lowerProto;
rest = rest.substr(proto.length);
out.href += lowerProto;
}
// figure out if it's got a host
@ -90,15 +112,14 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
// how the browser resolves relative URLs.
if (slashesDenoteHost || proto || rest.match(/^\/\/[^@\/]+@[^@\/]+/)) {
var slashes = rest.substr(0, 2) === '//';
if (slashes && !(lowerProto && hostlessProtocol[lowerProto])) {
if (slashes && !(proto && hostlessProtocol[proto])) {
rest = rest.substr(2);
out.slashes = true;
out.href += '//';
}
}
if (!hostlessProtocol[lowerProto] &&
(slashes || (lowerProto && !slashedProtocol[lowerProto]))) {
if (!hostlessProtocol[proto] &&
(slashes || (proto && !slashedProtocol[proto]))) {
// there's a hostname.
// the first instance of /, ?, ;, or # ends the host.
// don't enforce full RFC correctness, just be unstupid about it.
@ -123,9 +144,10 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
var key = keys[i];
out[key] = p[key];
}
// we've indicated that there is a hostname,
// so even if it's empty, it has to be present.
out.hostname = (out.hostname) ? out.hostname.toLowerCase() : '';
out.hostname = out.hostname || '';
// validate a little.
if (out.hostname.length > hostnameMaxLen) {
@ -134,19 +156,49 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
var hostparts = out.hostname.split(/\./);
for (var i = 0, l = hostparts.length; i < l; i++) {
var part = hostparts[i];
if (!part) continue;
if (!part.match(hostnamePartPattern)) {
out.hostname = '';
var validParts = hostparts.slice(0, i);
var notHost = hostparts.slice(i + 1);
var bit = part.match(hostnamePartStart);
if (bit) {
validParts.push(bit[1]);
notHost.unshift(bit[2]);
}
if (notHost.length) {
rest = '/' + notHost.join('.') + rest
}
out.hostname = validParts.join('.');
break;
}
}
}
out.host = ((out.auth)?out.auth +'@':'') + (out.hostname||'') + ((out.port)?':'+out.port:'');
// hostnames are always lower case.
out.hostname = out.hostname.toLowerCase();
out.host = ((out.auth) ? out.auth + '@' : '') +
(out.hostname || '') +
((out.port) ? ':' + out.port : '');
out.href += out.host;
}
// now rest is set to the post-host stuff.
// chop off any delim chars.
if (!unsafeProtocol[lowerProto]) {
// First, make 100% sure that any "autoEscape" chars get
// escaped, even if encodeURIComponent doesn't think they
// need to be.
for (var i = 0, l = autoEscape.length; i < l; i++) {
var ae = autoEscape[i];
var esc = encodeURIComponent(ae);
if (esc === ae) {
esc = escape(ae);
}
rest = rest.split(ae).join(esc);
}
// Now make sure that delims never appear in a url.
var chop = rest.length;
for (var i = 0, l = delims.length; i < l; i++) {
var c = rest.indexOf(delims[i]);
@ -155,7 +207,6 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
}
}
rest = rest.substr(0, chop);
out.href += rest;
}
@ -180,7 +231,7 @@ function urlParse(url, parseQueryString, slashesDenoteHost) {
out.query = {};
}
if (rest) out.pathname = rest;
if (slashedProtocol[lowerProto] &&
if (slashedProtocol[proto] &&
out.hostname && !out.pathname) {
out.pathname = '/';
}

19
src/node.cc

@ -1278,13 +1278,24 @@ static void ReportException(TryCatch &try_catch, bool show_line) {
String::Utf8Value trace(try_catch.StackTrace());
if (trace.length() > 0) {
// range errors have a trace member set to undefined
if (trace.length() > 0 && !try_catch.StackTrace()->IsUndefined()) {
fprintf(stderr, "%s\n", *trace);
} else {
// this really only happens for RangeErrors, since they're the only
// kind that won't have all this info in the trace.
// kind that won't have all this info in the trace, or when non-Error
// objects are thrown manually.
Local<Value> er = try_catch.Exception();
String::Utf8Value msg(!er->IsObject() ? er->ToString()
bool isErrorObject = er->IsObject() &&
!(er->ToObject()->Get(String::New("message"))->IsUndefined()) &&
!(er->ToObject()->Get(String::New("name"))->IsUndefined());
if (isErrorObject) {
String::Utf8Value name(er->ToObject()->Get(String::New("name")));
fprintf(stderr, "%s: ", *name);
}
String::Utf8Value msg(!isErrorObject ? er->ToString()
: er->ToObject()->Get(String::New("message"))->ToString());
fprintf(stderr, "%s\n", *msg);
}
@ -2251,7 +2262,7 @@ static void EnableDebug(bool wait_connect) {
assert(r);
// Print out some information.
fprintf(stderr, "debugger listening on port %d\r\n", debug_port);
fprintf(stderr, "debugger listening on port %d", debug_port);
}

2
src/node.h

@ -48,7 +48,7 @@ void EmitExit(v8::Handle<v8::Object> process);
/* Converts a unixtime to V8 Date */
#define NODE_UNIXTIME_V8(t) v8::Date::New(1000*static_cast<double>(t))
#define NODE_V8_UNIXTIME(v) (static_cast<double>((v)->IntegerValue())/1000.0);
#define NODE_V8_UNIXTIME(v) (static_cast<double>((v)->NumberValue())/1000.0);
#define NODE_DEFINE_CONSTANT(target, constant) \
(target)->Set(v8::String::NewSymbol(#constant), \

9
src/platform_sunos.cc

@ -31,6 +31,7 @@
#include <errno.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/loadavg.h>
#if (!defined(_LP64)) && (_FILE_OFFSET_BITS - 0 == 64)
#define PROCFS_FILE_OFFSET_BITS_HACK 1
@ -250,6 +251,14 @@ double Platform::GetUptimeImpl() {
}
int Platform::GetLoadAvg(Local<Array> *loads) {
HandleScope scope;
double loadavg[3];
(void) getloadavg(loadavg, 3);
(*loads)->Set(0, Number::New(loadavg[LOADAVG_1MIN]));
(*loads)->Set(1, Number::New(loadavg[LOADAVG_5MIN]));
(*loads)->Set(2, Number::New(loadavg[LOADAVG_15MIN]));
return 0;
}

33
test/message/stack_overflow.js

@ -0,0 +1,33 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
var assert = require('assert');
common.error('before');
// stack overflow
function stackOverflow() {
stackOverflow();
}
stackOverflow();
common.error('after');

6
test/message/stack_overflow.out

@ -0,0 +1,6 @@
before
node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
RangeError: Maximum call stack size exceeded

30
test/message/throw_custom_error.js

@ -0,0 +1,30 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
var assert = require('assert');
common.error('before');
// custom error throwing
throw { name: 'MyCustomError', message: 'This is a custom message' };
common.error('after');

6
test/message/throw_custom_error.out

@ -0,0 +1,6 @@
before
node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
MyCustomError: This is a custom message

30
test/message/throw_non_error.js

@ -0,0 +1,30 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
var common = require('../common');
var assert = require('assert');
common.error('before');
// custom error throwing
throw { foo : 'bar' };
common.error('after');

6
test/message/throw_non_error.out

@ -0,0 +1,6 @@
before
node.js:*
throw e; // process.nextTick error, or 'error' event on first tick
^
[object Object]

5
test/simple/test-buffer.js

@ -540,6 +540,7 @@ console.log(z.length)
assert.equal(2, z.length);
assert.equal(0x66, z[0]);
assert.equal(0x6f, z[1]);
assert.equal(0, Buffer('hello').slice(0, 0).length)
b = new Buffer(50);
@ -557,3 +558,7 @@ b.fill(1, 16, 32);
for (var i = 0; i < 16; i++) assert.equal(0, b[i]);
for (; i < 32; i++) assert.equal(1, b[i]);
for (; i < b.length; i++) assert.equal(0, b[i]);
var b = new SlowBuffer(10);
b.write('あいうえお', 'ucs2');
assert.equal(b.toString('ucs2'), 'あいうえお');

2
test/simple/test-https-eof-for-eom.js

@ -83,7 +83,7 @@ server.listen(common.PORT, function() {
bodyBuffer += s;
});
res.on('end', function() {
res.on('close', function() {
console.log('5) Client got "end" event.');
gotEnd = true;
});

14
test/simple/test-regress-GH-897.js

@ -0,0 +1,14 @@
var common = require('../common');
var assert = require('assert');
var t = Date.now();
var diff;
setTimeout(function () {
diff = Date.now() - t;
console.error(diff);
}, 0.1);
process.on('exit', function() {
assert.ok(diff < 100);
});

4
test/simple/test-stream-pipe-cleanup.js

@ -36,6 +36,10 @@ Writable.prototype.end = function () {
this.endCalls++;
}
Writable.prototype.destroy = function () {
this.endCalls++;
}
function Readable () {
this.readable = true;
stream.Stream.call(this);

100
test/simple/test-stream-pipe-multi.js

@ -0,0 +1,100 @@
// Test that having a bunch of streams piping in parallel
// doesn't break anything.
var common = require("../common");
var assert = require("assert");
var Stream = require("stream").Stream;
var rr = [];
var ww = [];
var cnt = 100;
var chunks = 1000;
var chunkSize = 250;
var data = new Buffer(chunkSize);
var wclosed = 0;
var rclosed = 0;
function FakeStream() {
Stream.apply(this);
this.wait = false;
this.writable = true;
this.readable = true;
}
FakeStream.prototype = Object.create(Stream.prototype);
FakeStream.prototype.write = function(chunk) {
console.error(this.ID, "write", this.wait)
if (this.wait) {
process.nextTick(this.emit.bind(this, "drain"));
}
this.wait = !this.wait;
return this.wait;
};
FakeStream.prototype.end = function() {
this.emit("end");
process.nextTick(this.close.bind(this));
};
// noop - closes happen automatically on end.
FakeStream.prototype.close = function() {
this.emit("close");
};
// expect all streams to close properly.
process.on("exit", function() {
assert.equal(cnt, wclosed, "writable streams closed");
assert.equal(cnt, rclosed, "readable streams closed");
});
for (var i = 0; i < chunkSize; i ++) {
chunkSize[i] = i % 256;
}
for (var i = 0; i < cnt; i++) {
var r = new FakeStream();
r.on("close", function() {
console.error(this.ID, "read close");
rclosed++;
});
rr.push(r);
var w = new FakeStream();
w.on("close", function() {
console.error(this.ID, "write close");
wclosed++;
});
ww.push(w);
r.ID = w.ID = i;
r.pipe(w);
}
// now start passing through data
// simulate a relatively fast async stream.
rr.forEach(function (r) {
var cnt = chunks;
var paused = false;
r.on("pause", function() {
paused = true;
});
r.on("resume", function() {
paused = false;
step();
});
function step() {
r.emit("data", data);
if (--cnt === 0) {
r.end();
return;
}
if (paused) return;
process.nextTick(step);
}
process.nextTick(step);
});

89
test/simple/test-url.js

@ -63,7 +63,67 @@ var parseTests = {
'host': 'USER:PW@www.example.com',
'hostname': 'www.example.com',
'pathname': '/'
},
'http://x.com/path?that\'s#all, folks' : {
'href': 'http://x.com/path?that%27s#all,',
'protocol': 'http:',
'host': 'x.com',
'hostname': 'x.com',
'search': '?that%27s',
'query': 'that%27s',
'pathname': '/path',
'hash': '#all,'
},
'HTTP://X.COM/Y' : {
'href': 'http://x.com/Y',
'protocol': 'http:',
'host': 'x.com',
'hostname': 'x.com',
'pathname': '/Y',
},
// an unexpected invalid char in the hostname.
'HtTp://x.y.cOm*a/b/c?d=e#f g<h>i' : {
'href': 'http://x.y.com/*a/b/c?d=e#f',
'protocol': 'http:',
'host': 'x.y.com',
'hostname': 'x.y.com',
'pathname': '/*a/b/c',
'search': '?d=e',
'query': 'd=e',
'hash': '#f'
},
// make sure that we don't accidentally lcast the path parts.
'HtTp://x.y.cOm*A/b/c?d=e#f g<h>i' : {
'href': 'http://x.y.com/*A/b/c?d=e#f',
'protocol': 'http:',
'host': 'x.y.com',
'hostname': 'x.y.com',
'pathname': '/*A/b/c',
'search': '?d=e',
'query': 'd=e',
'hash': '#f'
},
'http://x...y...#p': {
'href': 'http://x...y.../#p',
'protocol': 'http:',
'host': 'x...y...',
'hostname': 'x...y...',
'hash': '#p',
'pathname': '/'
},
'http://x/p/"quoted"': {
'href': 'http://x/p/',
'protocol':'http:',
'host': 'x',
'hostname': 'x',
'pathname': '/p/'
},
'<http://goo.corn/bread> Is a URL!': {
'href': 'http://goo.corn/bread',
'protocol': 'http:',
'host': 'goo.corn',
'hostname': 'goo.corn',
'pathname': '/bread'
},
'http://www.narwhaljs.org/blog/categories?id=news' : {
'href': 'http://www.narwhaljs.org/blog/categories?id=news',
@ -91,17 +151,18 @@ var parseTests = {
'query': '??&hl=en&src=api&x=2&y=2&z=3&s=',
'pathname': '/vt/lyrs=m@114'
},
'http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=' : {
'href': 'http://user:pass@mt0.google.com/vt/lyrs=m@114???' +
'&hl=en&src=api&x=2&y=2&z=3&s=',
'protocol': 'http:',
'host': 'user:pass@mt0.google.com',
'auth': 'user:pass',
'hostname': 'mt0.google.com',
'search': '???&hl=en&src=api&x=2&y=2&z=3&s=',
'query': '??&hl=en&src=api&x=2&y=2&z=3&s=',
'pathname': '/vt/lyrs=m@114'
},
'http://user:pass@mt0.google.com/vt/lyrs=m@114???&hl=en&src=api&x=2&y=2&z=3&s=':
{
'href': 'http://user:pass@mt0.google.com/vt/lyrs=m@114???' +
'&hl=en&src=api&x=2&y=2&z=3&s=',
'protocol': 'http:',
'host': 'user:pass@mt0.google.com',
'auth': 'user:pass',
'hostname': 'mt0.google.com',
'search': '???&hl=en&src=api&x=2&y=2&z=3&s=',
'query': '??&hl=en&src=api&x=2&y=2&z=3&s=',
'pathname': '/vt/lyrs=m@114'
},
'file:///etc/passwd' : {
'href': 'file:///etc/passwd',
'protocol': 'file:',
@ -191,7 +252,7 @@ for (var u in parseTests) {
actual = url.format(parseTests[u]);
assert.equal(expected, actual,
'format(' + u + ') == ' + expected + '\nactual:' + actual);
'format(' + u + ') == ' + u + '\nactual:' + actual);
}
var parseTestsWithQueryString = {
@ -204,7 +265,7 @@ var parseTestsWithQueryString = {
},
'pathname': '/foo/bar'
},
'http://example.com/' : {
'http://example.com' : {
'href': 'http://example.com/',
'protocol': 'http:',
'slashes': true,

26
wscript

@ -143,13 +143,6 @@ def set_options(opt):
, dest='openssl_libpath'
)
opt.add_option( '--oprofile'
, action='store_true'
, default=False
, help="add oprofile support"
, dest='use_oprofile'
)
opt.add_option( '--gdb'
, action='store_true'
, default=False
@ -252,12 +245,8 @@ def configure(conf):
conf.env["USE_SHARED_CARES"] = o.shared_cares or o.shared_cares_includes or o.shared_cares_libpath
conf.env["USE_SHARED_LIBEV"] = o.shared_libev or o.shared_libev_includes or o.shared_libev_libpath
conf.env["USE_OPROFILE"] = o.use_oprofile
conf.env["USE_GDBJIT"] = o.use_gdbjit
if o.use_oprofile:
conf.check(lib=['bfd', 'opagent'], uselib_store="OPROFILE")
conf.check(lib='dl', uselib_store='DL')
if not sys.platform.startswith("sunos") and not sys.platform.startswith("cygwin") and not sys.platform.startswith("win32"):
conf.env.append_value("CCFLAGS", "-rdynamic")
@ -552,7 +541,6 @@ def configure(conf):
# Configure default variant
conf.setenv('default')
conf.env.append_value('CPPFLAGS', '-DNDEBUG')
default_compile_flags = ['-g', '-O3']
conf.env.append_value('CCFLAGS', default_compile_flags)
conf.env.append_value('CXXFLAGS', default_compile_flags)
@ -587,12 +575,7 @@ def v8_cmd(bld, variant):
else:
snapshot = ""
if bld.env["USE_OPROFILE"]:
profile = "prof=oprofile"
else:
profile = ""
cmd_R = sys.executable + ' "%s" -j %d -C "%s" -Y "%s" visibility=default mode=%s %s toolchain=%s library=static %s %s'
cmd_R = sys.executable + ' "%s" -j %d -C "%s" -Y "%s" visibility=default mode=%s %s toolchain=%s library=static %s'
cmd = cmd_R % ( scons
, Options.options.jobs
@ -602,7 +585,6 @@ def v8_cmd(bld, variant):
, arch
, toolchain
, snapshot
, profile
)
if bld.env["USE_GDBJIT"]:
@ -753,8 +735,8 @@ def build(bld):
native_cc_debug = native_cc.clone("debug")
native_cc_debug.rule = javascript_in_c_debug
native_cc.rule = javascript_in_c
native_cc.rule = javascript_in_c_debug
if bld.env["USE_DTRACE"]:
dtrace = bld.new_task_gen(
name = "dtrace",
@ -892,7 +874,7 @@ def build(bld):
, 'CPPFLAGS' : " ".join(program.env["CPPFLAGS"]).replace('"', '\\"')
, 'LIBFLAGS' : " ".join(program.env["LIBFLAGS"]).replace('"', '\\"')
, 'PREFIX' : safe_path(program.env["PREFIX"])
, 'VERSION' : '0.4.6' # FIXME should not be hard-coded, see NODE_VERSION_STRING in src/node_version.
, 'VERSION' : '0.4.7' # FIXME should not be hard-coded, see NODE_VERSION_STRING in src/node_version.
}
return x

Loading…
Cancel
Save