Merge remote branch 'origin/v0.4'
Conflicts: ChangeLog Makefile deps/libev/wscript doc/index.html doc/template.html lib/net.js src/node_version.h src/platform_cygwin.cc test/pummel/test-net-write-callbacks.js test/simple/test-buffer.js
This commit is contained in:
Коммит
493d3b9f7c
25
ChangeLog
25
ChangeLog
|
@ -370,7 +370,30 @@
|
||||||
* DTrace probes: support X-Forwarded-For (Dave Pacheco)
|
* DTrace probes: support X-Forwarded-For (Dave Pacheco)
|
||||||
|
|
||||||
|
|
||||||
2011.08.17, Version 0.4.11 (stable)
|
2011.09.15, Version 0.4.12 (stable)
|
||||||
|
|
||||||
|
* Improve docs
|
||||||
|
|
||||||
|
* #1563 overflow in ChildProcess custom_fd.
|
||||||
|
|
||||||
|
* #1569, parse error on multi-line HTTP headers. (Ben Noordhuis)
|
||||||
|
|
||||||
|
* #1586 net: Socket write encoding case sensitivity (koichik)
|
||||||
|
|
||||||
|
* #1610 Remove DigiNotar CA from trusted list (isaacs)
|
||||||
|
|
||||||
|
* #1624 buffer: Avoid overrun with 'binary' encoding. (koichik)
|
||||||
|
|
||||||
|
* #1633 buffer: write() should always set _charsWritten. (koichik)
|
||||||
|
|
||||||
|
* #1707 hasOwnProperty usage security hole in querystring (isaacs)
|
||||||
|
|
||||||
|
* #1719 Drain OpenSSL error queue
|
||||||
|
|
||||||
|
* Fix error reporting in net.Server.listen
|
||||||
|
|
||||||
|
|
||||||
|
2011.08.17, Version 0.4.11 (stable), a745d19ce7d1c0e3778371af4f0346be70cf2c8e
|
||||||
|
|
||||||
* #738 Fix crypto encryption/decryption with Base64. (SAWADA Tadashi)
|
* #738 Fix crypto encryption/decryption with Base64. (SAWADA Tadashi)
|
||||||
|
|
||||||
|
|
|
@ -141,6 +141,10 @@ Example of checking for failed exec:
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Note that if spawn receives an empty options object, it will result in
|
||||||
|
spawning the process with an empty environment rather than using
|
||||||
|
`process.env`. This due to backwards compatibility issues with a deprecated
|
||||||
|
API.
|
||||||
|
|
||||||
See also: `child_process.exec()`
|
See also: `child_process.exec()`
|
||||||
|
|
||||||
|
|
|
@ -485,7 +485,7 @@ be found in the [MDN JavaScript Reference][MDN-Date] page.
|
||||||
|
|
||||||
## fs.ReadStream
|
## fs.ReadStream
|
||||||
|
|
||||||
`ReadStream` is a `Readable Stream`.
|
`ReadStream` is a [Readable Stream](streams.html#readable_Stream).
|
||||||
|
|
||||||
### Event: 'open'
|
### Event: 'open'
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ An example to read the last 10 bytes of a file which is 100 bytes long:
|
||||||
|
|
||||||
## fs.WriteStream
|
## fs.WriteStream
|
||||||
|
|
||||||
`WriteStream` is a `Writable Stream`.
|
`WriteStream` is a [Writable Stream](streams.html#writable_Stream).
|
||||||
|
|
||||||
### Event: 'open'
|
### Event: 'open'
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,15 @@ h4 + h4 {
|
||||||
margin: 0 0 0.5em;
|
margin: 0 0 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h3 a,
|
||||||
|
h4 a {
|
||||||
|
font-size: 0.8em;
|
||||||
|
float: right;
|
||||||
|
color: #000;
|
||||||
|
text-decoration: none;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
h5 {
|
h5 {
|
||||||
font-size: 1.125em;
|
font-size: 1.125em;
|
||||||
line-height: 1.4em;
|
line-height: 1.4em;
|
||||||
|
@ -232,4 +241,4 @@ a.octothorpe {
|
||||||
h5:hover > a.octothorpe,
|
h5:hover > a.octothorpe,
|
||||||
h6:hover > a.octothorpe {
|
h6:hover > a.octothorpe {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
48
lib/tls.js
48
lib/tls.js
|
@ -77,6 +77,7 @@ function CryptoStream(pair) {
|
||||||
this.readable = this.writable = true;
|
this.readable = this.writable = true;
|
||||||
|
|
||||||
this._paused = false;
|
this._paused = false;
|
||||||
|
this._needDrain = false;
|
||||||
this._pending = [];
|
this._pending = [];
|
||||||
this._pendingCallbacks = [];
|
this._pendingCallbacks = [];
|
||||||
this._pendingBytes = 0;
|
this._pendingBytes = 0;
|
||||||
|
@ -111,7 +112,7 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
|
||||||
data = new Buffer(data, encoding);
|
data = new Buffer(data, encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
debug('clearIn data');
|
debug((this === this.pair.cleartext ? 'clear' : 'encrypted') + 'In data');
|
||||||
|
|
||||||
this._pending.push(data);
|
this._pending.push(data);
|
||||||
this._pendingCallbacks.push(cb);
|
this._pendingCallbacks.push(cb);
|
||||||
|
@ -120,7 +121,26 @@ CryptoStream.prototype.write = function(data /* , encoding, cb */) {
|
||||||
this.pair._writeCalled = true;
|
this.pair._writeCalled = true;
|
||||||
this.pair.cycle();
|
this.pair.cycle();
|
||||||
|
|
||||||
return this._pendingBytes < 128 * 1024;
|
// In the following cases, write() should return a false,
|
||||||
|
// then this stream should eventually emit 'drain' event.
|
||||||
|
//
|
||||||
|
// 1. There are pending data more than 128k bytes.
|
||||||
|
// 2. A forward stream shown below is paused.
|
||||||
|
// A) EncryptedStream for CleartextStream.write().
|
||||||
|
// B) CleartextStream for EncryptedStream.write().
|
||||||
|
//
|
||||||
|
if (!this._needDrain) {
|
||||||
|
if (this._pendingBytes >= 128 * 1024) {
|
||||||
|
this._needDrain = true;
|
||||||
|
} else {
|
||||||
|
if (this === this.pair.cleartext) {
|
||||||
|
this._needDrain = this.pair.encrypted._paused;
|
||||||
|
} else {
|
||||||
|
this._needDrain = this.pair.cleartext._paused;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !this._needDrain;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -420,11 +440,25 @@ CryptoStream.prototype._pull = function() {
|
||||||
assert(rv === tmp.length);
|
assert(rv === tmp.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we've cleared all of incoming encrypted data, emit drain.
|
// If pending data has cleared, 'drain' event should be emitted
|
||||||
if (havePending && this._pending.length === 0) {
|
// after write() returns a false.
|
||||||
debug('drain');
|
// Except when a forward stream shown below is paused.
|
||||||
this.emit('drain');
|
// A) EncryptedStream for CleartextStream._pull().
|
||||||
if (this.__destroyOnDrain) this.end();
|
// B) CleartextStream for EncryptedStream._pull().
|
||||||
|
//
|
||||||
|
if (this._needDrain && this._pending.length === 0) {
|
||||||
|
var paused;
|
||||||
|
if (this === this.pair.cleartext) {
|
||||||
|
paused = this.pair.encrypted._paused;
|
||||||
|
} else {
|
||||||
|
paused = this.pair.cleartext._paused;
|
||||||
|
}
|
||||||
|
if (!paused) {
|
||||||
|
debug('drain');
|
||||||
|
process.nextTick(this.emit.bind(this, 'drain'));
|
||||||
|
this._needDrain = false;
|
||||||
|
if (this.__destroyOnDrain) this.end();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
if (!process.versions.openssl) {
|
||||||
|
console.error('Skipping because node compiled without OpenSSL.');
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var common = require('../common');
|
||||||
|
var assert = require('assert');
|
||||||
|
var tls = require('tls');
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
var options = {
|
||||||
|
key: fs.readFileSync(path.join(common.fixturesDir, 'test_key.pem')),
|
||||||
|
cert: fs.readFileSync(path.join(common.fixturesDir, 'test_cert.pem'))
|
||||||
|
};
|
||||||
|
|
||||||
|
var bufSize = 1024 * 1024;
|
||||||
|
var sent = 0;
|
||||||
|
var received = 0;
|
||||||
|
|
||||||
|
var server = tls.Server(options, function(socket) {
|
||||||
|
socket.pipe(socket);
|
||||||
|
});
|
||||||
|
|
||||||
|
server.listen(common.PORT, function() {
|
||||||
|
var resumed = false;
|
||||||
|
var client = tls.connect(common.PORT, function() {
|
||||||
|
client.pause();
|
||||||
|
common.debug('paused');
|
||||||
|
send();
|
||||||
|
function send() {
|
||||||
|
if (client.write(new Buffer(bufSize))) {
|
||||||
|
sent += bufSize;
|
||||||
|
assert.ok(sent < 100 * 1024 * 1024); // max 100MB
|
||||||
|
return process.nextTick(send);
|
||||||
|
}
|
||||||
|
sent += bufSize;
|
||||||
|
common.debug('sent: ' + sent);
|
||||||
|
resumed = true;
|
||||||
|
client.resume();
|
||||||
|
common.debug('resumed');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
client.on('data', function(data) {
|
||||||
|
assert.ok(resumed);
|
||||||
|
received += data.length;
|
||||||
|
if (received >= sent) {
|
||||||
|
common.debug('received: ' + received);
|
||||||
|
client.end();
|
||||||
|
server.close();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
process.on('exit', function() {
|
||||||
|
assert.equal(sent, received);
|
||||||
|
});
|
|
@ -88,6 +88,9 @@ function convertData(data) {
|
||||||
.replace(/<hr><\/hr>/g, "<hr />")
|
.replace(/<hr><\/hr>/g, "<hr />")
|
||||||
.replace(/(\<h[2-6])\>([^<]+)(\<\/h[1-6]\>)/gmi, function(o, ts, c, te) {
|
.replace(/(\<h[2-6])\>([^<]+)(\<\/h[1-6]\>)/gmi, function(o, ts, c, te) {
|
||||||
return ts+' id="'+formatIdString(c)+'">'+c+te;
|
return ts+' id="'+formatIdString(c)+'">'+c+te;
|
||||||
|
})
|
||||||
|
.replace(/(\<h[3-4][^>]+\>)([^<]+)(\<\/h[3-4]\>)/gmi, function(o, ts, c, te) {
|
||||||
|
return ts+c+' <a href="#'+formatIdString(c)+'">#</a>'+te;
|
||||||
});
|
});
|
||||||
|
|
||||||
return html;
|
return html;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче