From ed5bad754c1ff5a4544ef8ac6f2eed0261a9aec7 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 26 Dec 2011 03:23:34 +0100 Subject: [PATCH 1/9] bench: fix use of fd after close --- benchmark/io.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/benchmark/io.c b/benchmark/io.c index 53a5231f02..a4f4575179 100644 --- a/benchmark/io.c +++ b/benchmark/io.c @@ -51,7 +51,6 @@ static void writetest(int size, size_t bsize) exit(254); } } - close(fd); #ifndef NSYNC # ifdef __linux__ @@ -61,6 +60,8 @@ static void writetest(int size, size_t bsize) # endif #endif /* SYNC */ + close(fd); + end = now(); elapsed = (end - start) / 1e6; mbps = ((tsize/elapsed)) / 1048576; From 0de6ec5f08161d481c9cca73ab49cb9fba1b7699 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 26 Dec 2011 03:27:28 +0100 Subject: [PATCH 2/9] win: fix mismatched new[]/delete --- src/platform_win32.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform_win32.cc b/src/platform_win32.cc index 197b1ac31a..65add1124a 100644 --- a/src/platform_win32.cc +++ b/src/platform_win32.cc @@ -125,7 +125,7 @@ void Platform::SetProcessTitle(char *title) { length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); if (!length) { winapi_perror("MultiByteToWideChar"); - delete title_w; + delete[] title_w; return; }; @@ -141,7 +141,7 @@ void Platform::SetProcessTitle(char *title) { free(process_title); process_title = strdup(title); - delete title_w; + delete[] title_w; } From 7aa5924dc6e8d80980a9b79f3d5fc6305bf1aea7 Mon Sep 17 00:00:00 2001 From: koichik Date: Tue, 29 Nov 2011 20:55:05 +0900 Subject: [PATCH 3/9] http: fix resource leak Fixes #2069 --- lib/http.js | 12 ++++++--- test/simple/test-http-client-agent.js | 9 ++++--- test/simple/test-http-keep-alive.js | 36 +++++++++++++++++--------- test/simple/test-http-upgrade-agent.js | 5 ++-- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/lib/http.js b/lib/http.js index 912e3da170..6be71a3c6b 100644 --- a/lib/http.js +++ b/lib/http.js @@ -896,6 +896,10 @@ function Agent(options) { var name = host + ':' + port; if (self.requests[name] && self.requests[name].length) { self.requests[name].shift().onSocket(socket); + if (self.requests[name].length === 0) { + // don't leak + delete this.requests[name]; + } } else { // If there are no pending requests just destroy the // socket and it will get removed from the pool. This @@ -963,11 +967,11 @@ Agent.prototype.removeSocket = function(s, name, host, port) { var index = this.sockets[name].indexOf(s); if (index !== -1) { this.sockets[name].splice(index, 1); + if (this.sockets[name].length === 0) { + // don't leak + delete this.sockets[name]; + } } - } else if (this.sockets[name] && this.sockets[name].length === 0) { - // don't leak - delete this.sockets[name]; - delete this.requests[name]; } if (this.requests[name] && this.requests[name].length) { // If we have pending requests and a socket gets closed a new one diff --git a/test/simple/test-http-client-agent.js b/test/simple/test-http-client-agent.js index edf064a25c..f7112e3bfe 100644 --- a/test/simple/test-http-client-agent.js +++ b/test/simple/test-http-client-agent.js @@ -52,9 +52,12 @@ function request(i) { var socket = req.socket; socket.on('close', function() { ++count; - assert.equal(http.globalAgent.sockets[name].length, max - count); - assert.equal(http.globalAgent.sockets[name].indexOf(socket), -1); - if (count === max) { + if (count < max) { + assert.equal(http.globalAgent.sockets[name].length, max - count); + assert.equal(http.globalAgent.sockets[name].indexOf(socket), -1); + } else { + assert(!http.globalAgent.sockets.hasOwnProperty(name)); + assert(!http.globalAgent.requests.hasOwnProperty(name)); server.close(); } }); diff --git a/test/simple/test-http-keep-alive.js b/test/simple/test-http-keep-alive.js index 061747d369..aa03639deb 100644 --- a/test/simple/test-http-keep-alive.js +++ b/test/simple/test-http-keep-alive.js @@ -22,10 +22,8 @@ var common = require('../common'); var assert = require('assert'); var http = require('http'); -var util = require('util'); var body = 'hello world\n'; -var headers = {'connection': 'keep-alive'}; var server = http.createServer(function(req, res) { res.writeHead(200, {'Content-Length': body.length}); @@ -34,23 +32,37 @@ var server = http.createServer(function(req, res) { }); var connectCount = 0; +var name = 'localhost:' + common.PORT; +var agent = new http.Agent({maxSockets: 1}); +var headers = {'connection': 'keep-alive'}; server.listen(common.PORT, function() { - var agent = new http.Agent({maxSockets: 1}); - var request = http.request({method: 'GET', path: '/', headers: headers, port: common.PORT, agent: agent}, function() { - assert.equal(1, agent.sockets['localhost:' + common.PORT].length); + http.get({ + path: '/', headers: headers, port: common.PORT, agent: agent + }, function(response) { + assert.equal(agent.sockets[name].length, 1); + assert.equal(agent.requests[name].length, 2); }); - request.end(); - request = http.request({method: 'GET', path: '/', headers: headers, port: common.PORT, agent: agent}, function() { - assert.equal(1, agent.sockets['localhost:' + common.PORT].length); + http.get({ + path: '/', headers: headers, port: common.PORT, agent: agent + }, function(response) { + assert.equal(agent.sockets[name].length, 1); + assert.equal(agent.requests[name].length, 1); }); - request.end(); - request = http.request({method: 'GET', path: '/', headers: headers, port: common.PORT, agent: agent}, function(response) { + + http.get({ + path: '/', headers: headers, port: common.PORT, agent: agent + }, function(response) { response.on('end', function() { - assert.equal(1, agent.sockets['localhost:' + common.PORT].length); + assert.equal(agent.sockets[name].length, 1); + assert(!agent.requests.hasOwnProperty(name)); server.close(); }); }); - request.end(); +}); + +process.on('exit', function() { + assert(!agent.sockets.hasOwnProperty(name)); + assert(!agent.requests.hasOwnProperty(name)); }); diff --git a/test/simple/test-http-upgrade-agent.js b/test/simple/test-http-upgrade-agent.js index f59633318c..a87d5e864c 100644 --- a/test/simple/test-http-upgrade-agent.js +++ b/test/simple/test-http-upgrade-agent.js @@ -59,6 +59,7 @@ srv.listen(common.PORT, '127.0.0.1', function() { 'upgrade': 'websocket' } }; + var name = options.host + ':' + options.port; var req = http.request(options); req.end(); @@ -73,11 +74,11 @@ srv.listen(common.PORT, '127.0.0.1', function() { 'connection': 'upgrade', 'upgrade': 'websocket' }; assert.deepEqual(expectedHeaders, res.headers); - assert.equal(http.globalAgent.sockets[options.host + ':' + options.port].length, 1); + assert.equal(http.globalAgent.sockets[name].length, 1); process.nextTick(function() { // Make sure this request got removed from the pool. - assert.equal(http.globalAgent.sockets[options.host + ':' + options.port].length, 0); + assert(!http.globalAgent.sockets.hasOwnProperty(name)); socket.end(); srv.close(); From 70e6f3f115cfbd74462ec50e3cdc8fac89ae922a Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Mon, 26 Dec 2011 23:30:25 +0100 Subject: [PATCH 4/9] docs: document http.Server.close() semantics --- doc/api/http.markdown | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 330ea27710..27bb3986a1 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -120,6 +120,7 @@ See also [net.Server.listen()](net.html#server.listen). ### server.close() Stops the server from accepting new connections. +See [net.Server.close()](net.html#server.close). ## http.ServerRequest From a337ac75843ba4547a18d5b7c09930d5f5d954fa Mon Sep 17 00:00:00 2001 From: koichik Date: Tue, 27 Dec 2011 17:42:37 +0900 Subject: [PATCH 5/9] http: fix XMLHttpRequest piped in a writable file stream hangs next request Fixes #2263. --- lib/http.js | 5 +++ test/simple/test-http-pipe-fs.js | 68 ++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 test/simple/test-http-pipe-fs.js diff --git a/lib/http.js b/lib/http.js index 6be71a3c6b..25c308379e 100644 --- a/lib/http.js +++ b/lib/http.js @@ -136,6 +136,11 @@ var parsers = new FreeList('parsers', 1000, function() { parser.incoming.readable = false; parser.incoming.emit('end'); } + + if (parser.socket.readable) { + // force to read the next incoming message + parser.socket.resume(); + } }; return parser; diff --git a/test/simple/test-http-pipe-fs.js b/test/simple/test-http-pipe-fs.js new file mode 100644 index 0000000000..bc033fe59f --- /dev/null +++ b/test/simple/test-http-pipe-fs.js @@ -0,0 +1,68 @@ +// 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'); +var http = require('http'); +var fs = require('fs'); +var path = require('path'); + +var file = path.join(common.tmpDir, 'http-pipe-fs-test.txt'); +var requests = 0; + +var server = http.createServer(function(req, res) { + ++requests; + var stream = fs.createWriteStream(file); + req.pipe(stream); + stream.on('close', function() { + res.writeHead(200); + res.end(); + }); +}).listen(common.PORT, function() { + http.globalAgent.maxSockets = 1; + + for (var i = 0; i < 2; ++i) { + (function(i) { + var req = http.request({ + port: common.PORT, + method: 'POST', + headers: { + 'Content-Length': 5 + } + }, function(res) { + res.on('end', function() { + common.debug('res' + i + ' end'); + if (i === 2) { + server.close(); + } + }); + }); + req.on('socket', function(s) { + common.debug('req' + i + ' start'); + }); + req.end('12345'); + }(i + 1)); + } +}); + +process.on('exit', function() { + assert.equal(requests, 2); +}); From e1c043f43a42d1645c67761be4b1db913862d968 Mon Sep 17 00:00:00 2001 From: koichik Date: Tue, 27 Dec 2011 17:43:58 +0900 Subject: [PATCH 6/9] docs: fix docs to not suggest variable leaks Fixes #2106. --- doc/api/buffers.markdown | 133 ++++++++++++++++--------------- doc/api/child_processes.markdown | 4 +- doc/api/crypto.markdown | 83 +++++++++++-------- doc/api/dns.markdown | 14 ++-- doc/api/fs.markdown | 12 +-- doc/api/http.markdown | 25 +++--- doc/api/net.markdown | 17 ++-- doc/api/process.markdown | 4 +- doc/api/querystring.markdown | 10 ++- doc/api/repl.markdown | 9 ++- doc/api/streams.markdown | 2 +- doc/api/url.markdown | 5 +- doc/api/util.markdown | 5 +- 13 files changed, 177 insertions(+), 146 deletions(-) diff --git a/doc/api/buffers.markdown b/doc/api/buffers.markdown index 0ac7eb03ae..3bc9559173 100644 --- a/doc/api/buffers.markdown +++ b/doc/api/buffers.markdown @@ -43,18 +43,19 @@ Allocates a new buffer of `size` octets. Allocates a new buffer using an `array` of octets. -### new Buffer(str, encoding='utf8') +### new Buffer(str, [encoding]) Allocates a new buffer containing the given `str`. +`encoding` defaults to `'utf8'`. -### buffer.write(string, offset=0, length=buffer.length-offset, encoding='utf8') +### buffer.write(string, [offset], [length], [encoding]) -Writes `string` to the buffer at `offset` using the given encoding. `length` is +Writes `string` to the buffer at `offset` using the given encoding. +`offset` defaults to `0`, `encoding` defaults to `'utf8'`. `length` is the number of bytes to write. Returns number of octets written. If `buffer` did not contain enough space to fit the entire string, it will write a partial -amount of the string. The method will not write partial characters. - -Example: write a utf8 string into a buffer, then print it +amount of the string. `length` defaults to `buffer.length - offset`. +The method will not write partial characters. buf = new Buffer(256); len = buf.write('\u00bd + \u00bc = \u00be', 0); @@ -65,10 +66,11 @@ bytes written) is set in `Buffer._charsWritten` and will be overwritten the next time `buf.write()` is called. -### buffer.toString(encoding, start=0, end=buffer.length) +### buffer.toString(encoding, [start], [end]) Decodes and returns a string from buffer data encoded with `encoding` -beginning at `start` and ending at `end`. +(defaults to `'utf8'`) beginning at `start` (defaults to `0`) and ending at +`end` (defaults to `buffer.length`). See `buffer.write()` example, above. @@ -95,11 +97,11 @@ Example: copy an ASCII string into a buffer, one byte at a time: Tests if `obj` is a `Buffer`. -### Buffer.byteLength(string, encoding='utf8') +### Buffer.byteLength(string, [encoding]) -Gives the actual byte length of a string. This is not the same as -`String.prototype.length` since that returns the number of *characters* in a -string. +Gives the actual byte length of a string. `encoding` defaults to `'utf8'`. +This is not the same as `String.prototype.length` since that returns the +number of *characters* in a string. Example: @@ -126,9 +128,11 @@ buffer object. It does not change when the contents of the buffer are changed. // 1234 // 1234 -### buffer.copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +### buffer.copy(targetBuffer, [targetStart], [sourceStart], [sourceEnd]) Does copy between buffers. The source and target regions can be overlapped. +`targetStart` and `sourceStart` default to `0`. +`sourceEnd` defaults to `buffer.length`. Example: build two Buffers, then copy `buf1` from byte 16 through byte 19 into `buf2`, starting at the 8th byte in `buf2`. @@ -147,11 +151,11 @@ into `buf2`, starting at the 8th byte in `buf2`. // !!!!!!!!qrst!!!!!!!!!!!!! -### buffer.slice(start, end=buffer.length) +### buffer.slice([start], [end]) -Returns a new buffer which references the -same memory as the old, but offset and cropped by the `start` and `end` -indexes. +Returns a new buffer which references the same memory as the old, but offset +and cropped by the `start` (defaults to `0`) and `end` (defaults to +`buffer.length`) indexes. **Modifying the new buffer slice will modify memory in the original buffer!** @@ -172,12 +176,12 @@ byte from the original Buffer. // abc // !bc -### buffer.readUInt8(offset, noAssert=false) +### buffer.readUInt8(offset, [noAssert]) Reads an unsigned 8 bit integer from the buffer at the specified offset. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Example: @@ -197,14 +201,14 @@ Example: // 0x23 // 0x42 -### buffer.readUInt16LE(offset, noAssert=false) -### buffer.readUInt16BE(offset, noAssert=false) +### buffer.readUInt16LE(offset, [noAssert]) +### buffer.readUInt16BE(offset, [noAssert]) Reads an unsigned 16 bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Example: @@ -229,14 +233,14 @@ Example: // 0x2342 // 0x4223 -### buffer.readUInt32LE(offset, noAssert=false) -### buffer.readUInt32BE(offset, noAssert=false) +### buffer.readUInt32LE(offset, [noAssert]) +### buffer.readUInt32BE(offset, [noAssert]) Reads an unsigned 32 bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Example: @@ -253,48 +257,48 @@ Example: // 0x03042342 // 0x42230403 -### buffer.readInt8(offset, noAssert=false) +### buffer.readInt8(offset, [noAssert]) Reads a signed 8 bit integer from the buffer at the specified offset. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Works as `buffer.readUInt8`, except buffer contents are treated as two's complement signed values. -### buffer.readInt16LE(offset, noAssert=false) -### buffer.readInt16BE(offset, noAssert=false) +### buffer.readInt16LE(offset, [noAssert]) +### buffer.readInt16BE(offset, [noAssert]) Reads a signed 16 bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Works as `buffer.readUInt16*`, except buffer contents are treated as two's complement signed values. -### buffer.readInt32LE(offset, noAssert=false) -### buffer.readInt32BE(offset, noAssert=false) +### buffer.readInt32LE(offset, [noAssert]) +### buffer.readInt32BE(offset, [noAssert]) Reads a signed 32 bit integer from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Works as `buffer.readUInt32*`, except buffer contents are treated as two's complement signed values. -### buffer.readFloatLE(offset, noAssert=false) -### buffer.readFloatBE(offset, noAssert=false) +### buffer.readFloatLE(offset, [noAssert]) +### buffer.readFloatBE(offset, [noAssert]) Reads a 32 bit float from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Example: @@ -309,14 +313,14 @@ Example: // 0x01 -### buffer.readDoubleLE(offset, noAssert=false) -### buffer.readDoubleBE(offset, noAssert=false) +### buffer.readDoubleLE(offset, [noAssert]) +### buffer.readDoubleBE(offset, [noAssert]) Reads a 64 bit double from the buffer at the specified offset with specified endian format. Set `noAssert` to true to skip validation of `offset`. This means that `offset` -may be beyond the end of the buffer. +may be beyond the end of the buffer. Defaults to `false`. Example: @@ -335,7 +339,7 @@ Example: // 0.3333333333333333 -### buffer.writeUInt8(value, offset, noAssert=false) +### buffer.writeUInt8(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset. Note, `value` must be a valid unsigned 8 bit integer. @@ -343,7 +347,7 @@ valid unsigned 8 bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Example: @@ -357,8 +361,8 @@ Example: // -### buffer.writeUInt16LE(value, offset, noAssert=false) -### buffer.writeUInt16BE(value, offset, noAssert=false) +### buffer.writeUInt16LE(value, offset, [noAssert]) +### buffer.writeUInt16BE(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset with specified endian format. Note, `value` must be a valid unsigned 16 bit integer. @@ -366,7 +370,7 @@ format. Note, `value` must be a valid unsigned 16 bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Example: @@ -384,8 +388,8 @@ Example: // // -### buffer.writeUInt32LE(value, offset, noAssert=false) -### buffer.writeUInt32BE(value, offset, noAssert=false) +### buffer.writeUInt32LE(value, offset, [noAssert]) +### buffer.writeUInt32BE(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset with specified endian format. Note, `value` must be a valid unsigned 32 bit integer. @@ -393,7 +397,7 @@ format. Note, `value` must be a valid unsigned 32 bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Example: @@ -409,7 +413,7 @@ Example: // // -### buffer.writeInt8(value, offset, noAssert=false) +### buffer.writeInt8(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset. Note, `value` must be a valid signed 8 bit integer. @@ -417,13 +421,13 @@ valid signed 8 bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Works as `buffer.writeUInt8`, except value is written out as a two's complement signed integer into `buffer`. -### buffer.writeInt16LE(value, offset, noAssert=false) -### buffer.writeInt16BE(value, offset, noAssert=false) +### buffer.writeInt16LE(value, offset, [noAssert]) +### buffer.writeInt16BE(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset with specified endian format. Note, `value` must be a valid signed 16 bit integer. @@ -431,13 +435,13 @@ format. Note, `value` must be a valid signed 16 bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Works as `buffer.writeUInt16*`, except value is written out as a two's complement signed integer into `buffer`. -### buffer.writeInt32LE(value, offset, noAssert=false) -### buffer.writeInt32BE(value, offset, noAssert=false) +### buffer.writeInt32LE(value, offset, [noAssert]) +### buffer.writeInt32BE(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset with specified endian format. Note, `value` must be a valid signed 32 bit integer. @@ -445,13 +449,13 @@ format. Note, `value` must be a valid signed 32 bit integer. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Works as `buffer.writeUInt32*`, except value is written out as a two's complement signed integer into `buffer`. -### buffer.writeFloatLE(value, offset, noAssert=false) -### buffer.writeFloatBE(value, offset, noAssert=false) +### buffer.writeFloatLE(value, offset, [noAssert]) +### buffer.writeFloatBE(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset with specified endian format. Note, `value` must be a valid 32 bit float. @@ -459,7 +463,7 @@ format. Note, `value` must be a valid 32 bit float. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Example: @@ -475,8 +479,8 @@ Example: // // -### buffer.writeDoubleLE(value, offset, noAssert=false) -### buffer.writeDoubleBE(value, offset, noAssert=false) +### buffer.writeDoubleLE(value, offset, [noAssert]) +### buffer.writeDoubleBE(value, offset, [noAssert]) Writes `value` to the buffer at the specified offset with specified endian format. Note, `value` must be a valid 64 bit double. @@ -484,7 +488,7 @@ format. Note, `value` must be a valid 64 bit double. Set `noAssert` to true to skip validation of `value` and `offset`. This means that `value` may be too large for the specific function and `offset` may be beyond the end of the buffer leading to the values being silently dropped. This -should not be used unless you are certain of correctness. +should not be used unless you are certain of correctness. Defaults to `false`. Example: @@ -500,10 +504,11 @@ Example: // // -### buffer.fill(value, offset=0, end=buffer.length) +### buffer.fill(value, [offset], [end]) -Fills the buffer with the specified value. If the offset and end are not -given it will fill the entire buffer. +Fills the buffer with the specified value. If the `offset` (defaults to `0`) +and `end` (defaults to `buffer.length`) are not given it will fill the entire +buffer. var b = new Buffer(50); b.fill("h"); diff --git a/doc/api/child_processes.markdown b/doc/api/child_processes.markdown index 8efcede70a..d4c990e65e 100644 --- a/doc/api/child_processes.markdown +++ b/doc/api/child_processes.markdown @@ -50,7 +50,7 @@ Example: grep.stdin.end(); -### child_process.spawn(command, args=[], [options]) +### child_process.spawn(command, [args], [options]) Launches a new process with the given `command`, with command line arguments in `args`. If omitted, `args` defaults to an empty Array. @@ -259,7 +259,7 @@ processes: -### child.kill(signal='SIGTERM') +### child.kill([signal]) Send a signal to the child process. If no argument is given, the process will be sent `'SIGTERM'`. See `signal(7)` for a list of available signals. diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown index 6ca68d5c38..930956f0c7 100644 --- a/doc/api/crypto.markdown +++ b/doc/api/crypto.markdown @@ -47,16 +47,18 @@ Example: this program that takes the sha1 sum of a file console.log(d + ' ' + filename); }); -### hash.update(data, input_encoding='binary') +### hash.update(data, [input_encoding]) Updates the hash content with the given `data`, the encoding of which is given in `input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`. +Defaults to `'binary'`. This can be called many times with new data as it is streamed. -### hash.digest(encoding='binary') +### hash.digest([encoding]) Calculates the digest of all of the passed data to be hashed. The `encoding` can be `'hex'`, `'binary'` or `'base64'`. +Defaults to `'binary'`. Note: `hash` object can not be used after `digest()` method been called. @@ -73,10 +75,11 @@ Creates and returns a hmac object, a cryptographic hmac with the given algorithm Update the hmac content with the given `data`. This can be called many times with new data as it is streamed. -### hmac.digest(encoding='binary') +### hmac.digest([encoding]) Calculates the digest of all of the passed data to the hmac. The `encoding` can be `'hex'`, `'binary'` or `'base64'`. +Defaults to `'binary'`. Note: `hmac` object can not be used after `digest()` method been called. @@ -99,17 +102,21 @@ Creates and returns a cipher object, with the given algorithm, key and iv. algorithm. `iv` is an Initialization vector. `key` and `iv` must be `'binary'` encoded string (See the [Buffers](buffers.html) for more information). -### cipher.update(data, input_encoding='binary', output_encoding='binary') +### cipher.update(data, [input_encoding], [output_encoding]) -Updates the cipher with `data`, the encoding of which is given in `input_encoding` -and can be `'utf8'`, `'ascii'` or `'binary'`. The `output_encoding` specifies -the output format of the enciphered data, and can be `'binary'`, `'base64'` or `'hex'`. +Updates the cipher with `data`, the encoding of which is given in +`input_encoding` and can be `'utf8'`, `'ascii'` or `'binary'`. +Defaults to `'binary'`. + +The `output_encoding` specifies the output format of the enciphered data, +and can be `'binary'`, `'base64'` or `'hex'`. Defaults to `'binary'`. Returns the enciphered contents, and can be called many times with new data as it is streamed. -### cipher.final(output_encoding='binary') +### cipher.final([output_encoding]) -Returns any remaining enciphered contents, with `output_encoding` being one of: `'binary'`, `'base64'` or `'hex'`. +Returns any remaining enciphered contents, with `output_encoding` being one of: +`'binary'`, `'base64'` or `'hex'`. Defaults to `'binary'`. Note: `cipher` object can not be used after `final()` method been called. @@ -124,15 +131,19 @@ This is the mirror of the [createCipher()](#crypto.createCipher) above. Creates and returns a decipher object, with the given algorithm, key and iv. This is the mirror of the [createCipheriv()](#crypto.createCipheriv) above. -### decipher.update(data, input_encoding='binary', output_encoding='binary') +### decipher.update(data, [input_encoding], [output_encoding]) + +Updates the decipher with `data`, which is encoded in `'binary'`, `'base64'` +or `'hex'`. Defaults to `'binary'`. -Updates the decipher with `data`, which is encoded in `'binary'`, `'base64'` or `'hex'`. -The `output_decoding` specifies in what format to return the deciphered plaintext: `'binary'`, `'ascii'` or `'utf8'`. +The `output_decoding` specifies in what format to return the deciphered +plaintext: `'binary'`, `'ascii'` or `'utf8'`. Defaults to `'binary'`. -### decipher.final(output_encoding='binary') +### decipher.final([output_encoding]) Returns any remaining plaintext which is deciphered, with `output_encoding` being one of: `'binary'`, `'ascii'` or `'utf8'`. +Defaults to `'binary'`. Note: `decipher` object can not be used after `final()` method been called. @@ -148,12 +159,13 @@ the available signing algorithms. Examples are `'RSA-SHA256'`. Updates the signer object with data. This can be called many times with new data as it is streamed. -### signer.sign(private_key, output_format='binary') +### signer.sign(private_key, [output_format]) Calculates the signature on all the updated data passed through the signer. `private_key` is a string containing the PEM encoded private key for signing. -Returns the signature in `output_format` which can be `'binary'`, `'hex'` or `'base64'`. +Returns the signature in `output_format` which can be `'binary'`, `'hex'` or +`'base64'`. Defaults to `'binary'`. Note: `signer` object can not be used after `sign()` method been called. @@ -168,13 +180,13 @@ This is the mirror of the signing object above. Updates the verifier object with data. This can be called many times with new data as it is streamed. -### verifier.verify(object, signature, signature_format='binary') +### verifier.verify(object, signature, [signature_format]) Verifies the signed data by using the `object` and `signature`. `object` is a string containing a PEM encoded object, which can be one of RSA public key, DSA public key, or X.509 certificate. `signature` is the previously calculated signature for the data, in the `signature_format` which can be `'binary'`, -`'hex'` or `'base64'`. +`'hex'` or `'base64'`. Defaults to `'binary'`. Returns true or false depending on the validity of the signature for the data and public key. @@ -185,54 +197,57 @@ Note: `verifier` object can not be used after `verify()` method been called. Creates a Diffie-Hellman key exchange object and generates a prime of the given bit length. The generator used is `2`. -### crypto.createDiffieHellman(prime, encoding='binary') +### crypto.createDiffieHellman(prime, [encoding]) Creates a Diffie-Hellman key exchange object using the supplied prime. The generator used is `2`. Encoding can be `'binary'`, `'hex'`, or `'base64'`. +Defaults to `'binary'`. -### diffieHellman.generateKeys(encoding='binary') +### diffieHellman.generateKeys([encoding]) Generates private and public Diffie-Hellman key values, and returns the public key in the specified encoding. This key should be transferred to the other party. Encoding can be `'binary'`, `'hex'`, or `'base64'`. +Defaults to `'binary'`. -### diffieHellman.computeSecret(other_public_key, input_encoding='binary', output_encoding=input_encoding) +### diffieHellman.computeSecret(other_public_key, [input_encoding], [output_encoding]) Computes the shared secret using `other_public_key` as the other party's public key and returns the computed shared secret. Supplied key is interpreted using specified `input_encoding`, and secret is encoded using specified `output_encoding`. Encodings can be `'binary'`, `'hex'`, or -`'base64'`. If no output encoding is given, the input encoding is used as -output encoding. +`'base64'`. The input encoding defaults to `'binary'`. +If no output encoding is given, the input encoding is used as output encoding. -### diffieHellman.getPrime(encoding='binary') +### diffieHellman.getPrime([encoding]) Returns the Diffie-Hellman prime in the specified encoding, which can be -`'binary'`, `'hex'`, or `'base64'`. +`'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`. -### diffieHellman.getGenerator(encoding='binary') +### diffieHellman.getGenerator([encoding]) Returns the Diffie-Hellman prime in the specified encoding, which can be -`'binary'`, `'hex'`, or `'base64'`. +`'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`. -### diffieHellman.getPublicKey(encoding='binary') +### diffieHellman.getPublicKey([encoding]) Returns the Diffie-Hellman public key in the specified encoding, which can -be `'binary'`, `'hex'`, or `'base64'`. +be `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`. -### diffieHellman.getPrivateKey(encoding='binary') +### diffieHellman.getPrivateKey([encoding]) Returns the Diffie-Hellman private key in the specified encoding, which can -be `'binary'`, `'hex'`, or `'base64'`. +be `'binary'`, `'hex'`, or `'base64'`. Defaults to `'binary'`. -### diffieHellman.setPublicKey(public_key, encoding='binary') +### diffieHellman.setPublicKey(public_key, [encoding]) Sets the Diffie-Hellman public key. Key encoding can be `'binary'`, `'hex'`, -or `'base64'`. +or `'base64'`. Defaults to `'binary'`. -### diffieHellman.setPrivateKey(public_key, encoding='binary') +### diffieHellman.setPrivateKey(public_key, [encoding]) -Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'`, or `'base64'`. +Sets the Diffie-Hellman private key. Key encoding can be `'binary'`, `'hex'`, +or `'base64'`. Defaults to `'binary'`. ### pbkdf2(password, salt, iterations, keylen, callback) diff --git a/doc/api/dns.markdown b/doc/api/dns.markdown index caca9e4826..1f54e2dd3c 100644 --- a/doc/api/dns.markdown +++ b/doc/api/dns.markdown @@ -31,10 +31,12 @@ resolves the IP addresses which are returned. }); }); -### dns.lookup(domain, family=null, callback) +### dns.lookup(domain, [family], callback) Resolves a domain (e.g. `'google.com'`) into the first found A (IPv4) or AAAA (IPv6) record. +The `family` can be the integer `4` or `6`. Defaults to `null` that indicates +both Ip v4 and v6 address family. The callback has arguments `(err, address, family)`. The `address` argument is a string representation of a IP v4 or v6 address. The `family` argument @@ -42,13 +44,13 @@ is either the integer 4 or 6 and denotes the family of `address` (not necessarily the value initially passed to `lookup`). -### dns.resolve(domain, rrtype='A', callback) +### dns.resolve(domain, [rrtype], callback) Resolves a domain (e.g. `'google.com'`) into an array of the record types -specified by rrtype. Valid rrtypes are `A` (IPV4 addresses), `AAAA` (IPV6 -addresses), `MX` (mail exchange records), `TXT` (text records), `SRV` (SRV -records), `PTR` (used for reverse IP lookups), `NS` (name server records) -and `CNAME` (canonical name records). +specified by rrtype. Valid rrtypes are `'A'` (IPV4 addresses, default), +`'AAAA'` (IPV6 addresses), `'MX'` (mail exchange records), `'TXT'` (text +records), `'SRV'` (SRV records), `'PTR'` (used for reverse IP lookups), +`'NS'` (name server records) and `'CNAME'` (canonical name records). The callback has arguments `(err, addresses)`. The type of each item in `addresses` is determined by the record type, and described in the diff --git a/doc/api/fs.markdown b/doc/api/fs.markdown index 445fd59c2b..88d4c28294 100644 --- a/doc/api/fs.markdown +++ b/doc/api/fs.markdown @@ -317,10 +317,10 @@ without waiting for the callback. For this scenario, Synchronous version of buffer-based `fs.write()`. Returns the number of bytes written. -### fs.writeSync(fd, str, position, encoding='utf8') +### fs.writeSync(fd, str, position, [encoding]) -Synchronous version of string-based `fs.write()`. Returns the number of _bytes_ -written. +Synchronous version of string-based `fs.write()`. `encoding` defaults to +`'utf8'`. Returns the number of _bytes_ written. ### fs.read(fd, buffer, offset, length, position, [callback]) @@ -370,11 +370,11 @@ If `encoding` is specified then this function returns a string. Otherwise it returns a buffer. -### fs.writeFile(filename, data, encoding='utf8', [callback]) +### fs.writeFile(filename, data, [encoding], [callback]) Asynchronously writes data to a file, replacing the file if it already exists. `data` can be a string or a buffer. The `encoding` argument is ignored if -`data` is a buffer. +`data` is a buffer. It defaults to `'utf8'`. Example: @@ -383,7 +383,7 @@ Example: console.log('It\'s saved!'); }); -### fs.writeFileSync(filename, data, encoding='utf8') +### fs.writeFileSync(filename, data, [encoding]) The synchronous version of `fs.writeFile`. diff --git a/doc/api/http.markdown b/doc/api/http.markdown index 27bb3986a1..8dd9935a1e 100644 --- a/doc/api/http.markdown +++ b/doc/api/http.markdown @@ -216,7 +216,7 @@ Also `request.httpVersionMajor` is the first integer and `request.httpVersionMinor` is the second. -### request.setEncoding(encoding=null) +### request.setEncoding([encoding]) Set the encoding for the request body. Either `'utf8'` or `'binary'`. Defaults to `null`, which means that the `'data'` event will emit a `Buffer` object.. @@ -327,7 +327,7 @@ Example: response.removeHeader("Content-Encoding"); -### response.write(chunk, encoding='utf8') +### response.write(chunk, [encoding]) If this method is called and `response.writeHead()` has not been called, it will switch to implicit header mode and flush the implicit headers. @@ -653,7 +653,7 @@ Emitted when the server sends a '100 Continue' HTTP response, usually because the request contained 'Expect: 100-continue'. This is an instruction that the client should send the request body. -### request.write(chunk, encoding='utf8') +### request.write(chunk, [encoding]) Sends a chunk of the body. By calling this method many times, the user can stream a request body to a @@ -664,8 +664,8 @@ creating the request. The `chunk` argument should be an array of integers or a string. -The `encoding` argument is optional and only -applies when `chunk` is a string. +The `encoding` argument is optional and only applies when `chunk` is a string. +Defaults to `'utf8'`. ### request.end([data], [encoding]) @@ -674,8 +674,8 @@ Finishes sending the request. If any parts of the body are unsent, it will flush them to the stream. If the request is chunked, this will send the terminating `'0\r\n\r\n'`. -If `data` is specified, it is equivalent to calling `request.write(data, encoding)` -followed by `request.end()`. +If `data` is specified, it is equivalent to calling +`request.write(data, encoding)` followed by `request.end()`. ### request.abort() @@ -687,13 +687,13 @@ Once a socket is assigned to this request and is connected [socket.setTimeout(timeout, [callback])](net.html#socket.setTimeout) will be called. -### request.setNoDelay(noDelay=true) +### request.setNoDelay([noDelay]) Once a socket is assigned to this request and is connected [socket.setNoDelay(noDelay)](net.html#socket.setNoDelay) will be called. -### request.setSocketKeepAlive(enable=false, [initialDelay]) +### request.setSocketKeepAlive([enable], [initialDelay]) Once a socket is assigned to this request and is connected [socket.setKeepAlive(enable, [initialDelay])](net.html#socket.setKeepAlive) @@ -748,10 +748,11 @@ The response headers object. The response trailers object. Only populated after the 'end' event. -### response.setEncoding(encoding=null) +### response.setEncoding([encoding]) -Set the encoding for the response body. Either `'utf8'`, `'ascii'`, or `'base64'`. -Defaults to `null`, which means that the `'data'` event will emit a `Buffer` object.. +Set the encoding for the response body. Either `'utf8'`, `'ascii'`, or +`'base64'`. Defaults to `null`, which means that the `'data'` event will emit +a `Buffer` object.. ### response.pause() diff --git a/doc/api/net.markdown b/doc/api/net.markdown index 1eb02ddba3..1e3dfbdd4d 100644 --- a/doc/api/net.markdown +++ b/doc/api/net.markdown @@ -269,10 +269,10 @@ Users who experience large or growing `bufferSize` should attempt to "throttle" the data flows in their program with `pause()` and `resume()`. -#### socket.setEncoding(encoding=null) +#### socket.setEncoding([encoding]) Sets the encoding (either `'ascii'`, `'utf8'`, or `'base64'`) for data that is -received. +received. Defaults to `null`. #### socket.setSecure() @@ -333,20 +333,23 @@ If `timeout` is 0, then the existing idle timeout is disabled. The optional `callback` parameter will be added as a one time listener for the `'timeout'` event. -#### socket.setNoDelay(noDelay=true) +#### socket.setNoDelay([noDelay]) Disables the Nagle algorithm. By default TCP connections use the Nagle -algorithm, they buffer data before sending it off. Setting `noDelay` will -immediately fire off data each time `socket.write()` is called. +algorithm, they buffer data before sending it off. Setting `true` for +`noDelay` will immediately fire off data each time `socket.write()` is called. +`noDelay` defaults to `true`. -#### socket.setKeepAlive(enable=false, [initialDelay]) +#### socket.setKeepAlive([enable], [initialDelay]) Enable/disable keep-alive functionality, and optionally set the initial delay before the first keepalive probe is sent on an idle socket. +`enable` defaults to `false`. + Set `initialDelay` (in milliseconds) to set the delay between the last data packet received and the first keepalive probe. Setting 0 for initialDelay will leave the value unchanged from the default -(or previous) setting. +(or previous) setting. Defaults to `0`. #### socket.address() diff --git a/doc/api/process.markdown b/doc/api/process.markdown index 365e975734..57a139f298 100644 --- a/doc/api/process.markdown +++ b/doc/api/process.markdown @@ -172,7 +172,7 @@ Returns the current working directory of the process. An object containing the user environment. See environ(7). -### process.exit(code=0) +### process.exit([code]) Ends the process with the specified `code`. If omitted, exit uses the 'success' code `0`. @@ -260,7 +260,7 @@ A compiled-in property that exposes `NODE_PREFIX`. console.log('Prefix: ' + process.installPrefix); -### process.kill(pid, signal='SIGTERM') +### process.kill(pid, [signal]) Send a signal to a process. `pid` is the process id and `signal` is the string describing the signal to send. Signal names are strings like diff --git a/doc/api/querystring.markdown b/doc/api/querystring.markdown index 81ba1a6569..25741804dc 100644 --- a/doc/api/querystring.markdown +++ b/doc/api/querystring.markdown @@ -3,10 +3,11 @@ This module provides utilities for dealing with query strings. It provides the following methods: -### querystring.stringify(obj, sep='&', eq='=') +### querystring.stringify(obj, [sep], [eq]) Serialize an object to a query string. -Optionally override the default separator and assignment characters. +Optionally override the default separator (`'&'`) and assignment (`'='`) +characters. Example: @@ -18,10 +19,11 @@ Example: // returns 'foo:bar;baz:qux' -### querystring.parse(str, sep='&', eq='=') +### querystring.parse(str, [sep], [eq]) Deserialize a query string to an object. -Optionally override the default separator and assignment characters. +Optionally override the default separator (`'&'`) and assignment (`'='`) +characters. Example: diff --git a/doc/api/repl.markdown b/doc/api/repl.markdown index 91181ca124..a55835ae84 100644 --- a/doc/api/repl.markdown +++ b/doc/api/repl.markdown @@ -27,17 +27,18 @@ For example, you could add this to your bashrc file: alias node="env NODE_NO_READLINE=1 rlwrap node" -### repl.start(prompt='> ', stream=process.stdin, eval=eval, useGlobal=false, ignoreUndefined=false) +### repl.start([prompt], [stream], [eval], [useGlobal], [ignoreUndefined]) Starts a REPL with `prompt` as the prompt and `stream` for all I/O. `prompt` is optional and defaults to `> `. `stream` is optional and defaults to -`process.stdin`. `eval` is optional too and defaults to async wrapper for `eval`. +`process.stdin`. `eval` is optional too and defaults to async wrapper for +`eval()`. If `useGlobal` is set to true, then the repl will use the global object, -instead of running scripts in a separate context. +instead of running scripts in a separate context. Defaults to `false`. If `ignoreUndefined` is set to true, then the repl will not output return value -of command if it's `undefined`. +of command if it's `undefined`. Defaults to `false`. You can use your own `eval` function if it has following signature: diff --git a/doc/api/streams.markdown b/doc/api/streams.markdown index 6637b39544..4c353212e3 100644 --- a/doc/api/streams.markdown +++ b/doc/api/streams.markdown @@ -128,7 +128,7 @@ Emitted when the stream is passed to a readable stream's pipe method. A boolean that is `true` by default, but turns `false` after an `'error'` occurred or `end()` / `destroy()` was called. -### stream.write(string, encoding='utf8', [fd]) +### stream.write(string, [encoding], [fd]) Writes `string` with the given `encoding` to the stream. Returns `true` if the string has been flushed to the kernel buffer. Returns `false` to diff --git a/doc/api/url.markdown b/doc/api/url.markdown index 372dae8083..a4dbec92cc 100644 --- a/doc/api/url.markdown +++ b/doc/api/url.markdown @@ -45,16 +45,17 @@ string will not be in the parsed object. Examples are shown for the URL The following methods are provided by the URL module: -### url.parse(urlStr, parseQueryString=false, slashesDenoteHost=false) +### url.parse(urlStr, [parseQueryString], [slashesDenoteHost]) Take a URL string, and return an object. Pass `true` as the second argument to also parse the query string using the `querystring` module. +Defaults to `false`. Pass `true` as the third argument to treat `//foo/bar` as `{ host: 'foo', pathname: '/bar' }` rather than -`{ pathname: '//foo/bar' }`. +`{ pathname: '//foo/bar' }`. Defaults to `false`. ### url.format(urlObj) diff --git a/doc/api/util.markdown b/doc/api/util.markdown index ee0622ae5e..fefe22707a 100644 --- a/doc/api/util.markdown +++ b/doc/api/util.markdown @@ -50,12 +50,12 @@ Output with timestamp on `stdout`. require('util').log('Timestamped message.'); -### util.inspect(object, showHidden=false, depth=2, colors=false) +### util.inspect(object, [showHidden], [depth], [colors]) Return a string representation of `object`, which is useful for debugging. If `showHidden` is `true`, then the object's non-enumerable properties will be -shown too. +shown too. Defaults to `false`. If `depth` is provided, it tells `inspect` how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. @@ -64,6 +64,7 @@ The default is to only recurse twice. To make it recurse indefinitely, pass in `null` for `depth`. If `colors` is `true`, the output will be styled with ANSI color codes. +Defaults to `false`. Example of inspecting all properties of the `util` object: From a848a3efbfeb70181a95383e022474fdf2c83aae Mon Sep 17 00:00:00 2001 From: koichik Date: Wed, 28 Dec 2011 15:13:57 +0900 Subject: [PATCH 7/9] net: fix Socket.pause null reference when called on a closed Stream Fixes #1980. --- lib/net.js | 9 +++-- test/simple/test-net-after-close.js | 52 +++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 test/simple/test-net-after-close.js diff --git a/lib/net.js b/lib/net.js index b6697136d2..072896b4c4 100644 --- a/lib/net.js +++ b/lib/net.js @@ -166,7 +166,10 @@ Socket.prototype.setKeepAlive = function(setting, msecs) { Socket.prototype.address = function() { - return this._handle.getsockname(); + if (this._handle && this._handle.getsockname) { + return this._handle.getsockname(); + } + return null; }; @@ -189,7 +192,9 @@ Object.defineProperty(Socket.prototype, 'readyState', { Object.defineProperty(Socket.prototype, 'bufferSize', { get: function() { - return this._handle.writeQueueSize + this._connectQueueSize; + if (this._handle) { + return this._handle.writeQueueSize + this._connectQueueSize; + } } }); diff --git a/test/simple/test-net-after-close.js b/test/simple/test-net-after-close.js new file mode 100644 index 0000000000..65fda21900 --- /dev/null +++ b/test/simple/test-net-after-close.js @@ -0,0 +1,52 @@ +// 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'); +var net = require('net'); +var closed = false; + +var server = net.createServer(function(s) { + s.end(); +}); + +server.listen(common.PORT, function() { + var c = net.createConnection(common.PORT); + c.on('close', function() { + assert.strictEqual(c._handle, null); + closed = true; + assert.doesNotThrow(function() { + c.setNoDelay(); + c.setKeepAlive(); + c.bufferSize; + c.pause(); + c.resume(); + c.address(); + c.remoteAddress; + c.remotePort; + }); + server.close(); + }); +}); + +process.on('exit', function() { + assert(closed); +}); From d483acc5d9c67052366f10a23ebd46a96f989e05 Mon Sep 17 00:00:00 2001 From: Andreas Madsen Date: Wed, 28 Dec 2011 17:13:28 +0100 Subject: [PATCH 8/9] test: remove internet test from test/simple/ --- test/simple/test-c-ares.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/simple/test-c-ares.js b/test/simple/test-c-ares.js index 62b7e81b41..7210dc2f14 100644 --- a/test/simple/test-c-ares.js +++ b/test/simple/test-c-ares.js @@ -42,13 +42,6 @@ dns.lookup('::1', function(error, result, addressType) { assert.equal(6, addressType); }); -dns.lookup('ipv6.google.com', function(error, result, addressType) { - if (error) throw error; - console.dir(arguments); - //assert.equal('string', typeof result); - assert.equal(6, addressType); -}); - // Windows doesn't usually have an entry for localhost 127.0.0.1 in // C:\Windows\System32\drivers\etc\hosts // so we disable this test on Windows. From 448c5e07ca594399f3d3f93ea6f97124ea56af95 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Wed, 28 Dec 2011 14:08:19 -0800 Subject: [PATCH 9/9] Revert "Add HandleScope to http-parser binding" This commit did not actually fix the production crashes. This reverts commit 73cf8e82e768af870964d6f3375ab758e774165c. --- src/node_http_parser.cc | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index 32fd08d676..38251a1e7c 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -119,17 +119,15 @@ static size_t current_buffer_len; #define HTTP_CB(name) \ - static int name(http_parser* p_) { \ - HandleScope scope; \ - Parser* self = container_of(p_, Parser, parser_); \ - return self->name##_(); \ - } \ - int always_inline name##_() + static int name(http_parser* p_) { \ + Parser* self = container_of(p_, Parser, parser_); \ + return self->name##_(); \ + } \ + int always_inline name##_() #define HTTP_DATA_CB(name) \ static int name(http_parser* p_, const char* at, size_t length) { \ - HandleScope scope; \ Parser* self = container_of(p_, Parser, parser_); \ return self->name##_(at, length); \ } \ @@ -214,12 +212,10 @@ struct StringPtr { Handle ToString() const { - HandleScope scope; - if (str_) { - return scope.Close(String::New(str_, size_)); - } else { - return scope.Close(String::Empty()); - } + if (str_) + return String::New(str_, size_); + else + return String::Empty(); } @@ -517,8 +513,6 @@ public: private: Local CreateHeaders() { - HandleScope scope; - // num_values_ is either -1 or the entry # of the last header // so num_values_ == 0 means there's a single header Local headers = Array::New(2 * (num_values_ + 1)); @@ -528,7 +522,7 @@ private: headers->Set(2 * i + 1, values_[i].ToString()); } - return scope.Close(headers); + return headers; }