summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-05-15 11:37:34 -0700
committerisaacs <i@izs.me>2012-05-15 11:37:34 -0700
commit5164ae38380dadce74e8f64d7bd3eaa1935dd101 (patch)
treefa29fd7bcac679e69b1e9d7eff299aa38f9288a7
parent01103d077bce626a332be998813382d15bed3501 (diff)
parentf19f980724fa07347a0d0a9d92e48b267555da5d (diff)
downloadandroid-node-v8-5164ae38380dadce74e8f64d7bd3eaa1935dd101.tar.gz
android-node-v8-5164ae38380dadce74e8f64d7bd3eaa1935dd101.tar.bz2
android-node-v8-5164ae38380dadce74e8f64d7bd3eaa1935dd101.zip
Merge remote-tracking branch 'ry/v0.6' into v0.6-merge
Conflicts: ChangeLog deps/uv/include/uv-private/uv-unix.h deps/uv/src/unix/core.c deps/uv/src/unix/sunos.c deps/v8/src/runtime.cc doc/api/crypto.markdown lib/http.js src/node_version.h test/gc/test-http-client-timeout.js wscript
-rw-r--r--ChangeLog29
-rw-r--r--Makefile2
-rw-r--r--doc/api/buffer.markdown8
-rw-r--r--doc/api/crypto.markdown3
-rw-r--r--doc/api/https.markdown16
-rw-r--r--doc/api/stream.markdown5
-rw-r--r--doc/api/tls.markdown66
-rw-r--r--lib/crypto.js8
-rw-r--r--lib/fs.js4
-rw-r--r--lib/http.js3
-rw-r--r--lib/path.js3
-rw-r--r--lib/tls.js2
-rw-r--r--src/node.js4
-rw-r--r--src/node_crypto.cc79
-rw-r--r--src/node_crypto.h2
-rw-r--r--src/pipe_wrap.cc4
-rw-r--r--test/fixtures/test_cert.pfxbin0 -> 1970 bytes
-rw-r--r--test/gc/test-http-client-timeout.js2
-rw-r--r--test/simple/test-child-process-fork-and-spawn.js53
-rw-r--r--test/simple/test-crypto.js19
-rw-r--r--test/simple/test-fs-read-stream-resume.js51
-rw-r--r--test/simple/test-https-pfx.js56
-rw-r--r--test/simple/test-path.js2
23 files changed, 400 insertions, 21 deletions
diff --git a/ChangeLog b/ChangeLog
index b66faae59e..20394bec1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -255,6 +255,35 @@
* Bug fixes
+2012.05.15 Version 0.6.18 (stable), 4bc1d395de6abed2cf1e4d0b7b3a1480a21c368f
+
+* windows: skip GetFileAttributes call when opening a file (Bert Belder)
+
+* crypto: add PKCS12/PFX support (Sambasiva Suda)
+
+* #3240: child_process: delete NODE_CHANNEL_FD from env in spawn (Ben Noordhuis)
+
+* windows: add test for path.normalize with UNC paths (Bert Belder)
+
+* windows: make path.normalize convert all slashes to backslashes (Bert Belder)
+
+* fs: Automatically close FSWatcher on error (Bert Belder)
+
+* #3258: fs.ReadStream.pause() emits duplicate data event (koichik)
+
+* pipe_wrap: don't assert() on pipe accept errors (Ben Noordhuis)
+
+* Better exception output for module load and process.nextTick (Felix Geisendörfer)
+
+* zlib: fix error reporting (Ben Noordhuis)
+
+* http: Don't destroy on timeout (isaacs)
+
+* #3231: http: Don't try to emit error on a null'ed req object (isaacs)
+
+* #3236: http: Refactor ClientRequest.onSocket (isaacs)
+
+
2012.05.04 Version 0.6.17 (stable), 4ced23deaf36493f4303a18f6fdce768c58becc0
* Upgrade npm to 1.1.21
diff --git a/Makefile b/Makefile
index cc913ff75d..a80da5141f 100644
--- a/Makefile
+++ b/Makefile
@@ -154,7 +154,7 @@ out/doc/api/%.html: doc/api/%.markdown
out/Release/node tools/doc/generate.js --format=html --template=doc/template.html $< > $@
email.md: ChangeLog tools/email-footer.md
- bash tools/changelog-head.sh > $@
+ bash tools/changelog-head.sh | sed 's|^\* #|* \\#|g' > $@
cat tools/email-footer.md | sed -e 's|__VERSION__|'$(VERSION)'|g' >> $@
blog.html: email.md
diff --git a/doc/api/buffer.markdown b/doc/api/buffer.markdown
index a444adb67d..11c7097a89 100644
--- a/doc/api/buffer.markdown
+++ b/doc/api/buffer.markdown
@@ -70,7 +70,7 @@ Allocates a new buffer containing the given `str`.
* `string` String - data to be written to buffer
* `offset` Number, Optional, Default: 0
-* `length` Number, Optional
+* `length` Number, Optional, Default: `buffer.length - offset`
* `encoding` String, Optional, Default: 'utf8'
Writes `string` to the buffer at `offset` using the given encoding.
@@ -93,7 +93,7 @@ next time `buf.write()` is called.
* `encoding` String, Optional, Default: 'utf8'
* `start` Number, Optional, Default: 0
-* `end` Number, Optional
+* `end` Number, Optional, Default: `buffer.length`
Decodes and returns a string from buffer data encoded with `encoding`
(defaults to `'utf8'`) beginning at `start` (defaults to `0`) and ending at
@@ -171,7 +171,7 @@ buffer object. It does not change when the contents of the buffer are changed.
* `targetBuffer` Buffer object - Buffer to copy into
* `targetStart` Number, Optional, Default: 0
* `sourceStart` Number, Optional, Default: 0
-* `sourceEnd` Number, Optional, Default: 0
+* `sourceEnd` Number, Optional, Default: `buffer.length`
Does copy between buffers. The source and target regions can be overlapped.
`targetStart` and `sourceStart` default to `0`.
@@ -197,7 +197,7 @@ into `buf2`, starting at the 8th byte in `buf2`.
### buf.slice([start], [end])
* `start` Number, Optional, Default: 0
-* `end` Number, Optional, Default: 0
+* `end` Number, Optional, Default: `buffer.length`
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
diff --git a/doc/api/crypto.markdown b/doc/api/crypto.markdown
index 610154c7b3..3537fc13b9 100644
--- a/doc/api/crypto.markdown
+++ b/doc/api/crypto.markdown
@@ -14,8 +14,9 @@ It also offers a set of wrappers for OpenSSL's hash, hmac, cipher, decipher, sig
Creates a credentials object, with the optional details being a dictionary with keys:
+* `pfx` : A string or buffer holding the PFX or PKCS12 encoded private key, certificate and CA certificates
* `key` : A string holding the PEM encoded private key
-* `passphrase` : A string of passphrase for the private key
+* `passphrase` : A string of passphrase for the private key or pfx
* `cert` : A string holding the PEM encoded certificate
* `ca` : Either a string or list of strings of PEM encoded CA certificates to trust.
* `crl` : Either a string or list of strings of PEM encoded CRLs (Certificate Revocation List)
diff --git a/doc/api/https.markdown b/doc/api/https.markdown
index 9f51e5fc5e..10c9a3e3ba 100644
--- a/doc/api/https.markdown
+++ b/doc/api/https.markdown
@@ -32,6 +32,19 @@ Example:
res.end("hello world\n");
}).listen(8000);
+Or
+
+ var https = require('https');
+ var fs = require('fs');
+
+ var options = {
+ pfx: fs.readFileSync('server.pfx')
+ };
+
+ https.createServer(options, function (req, res) {
+ res.writeHead(200);
+ res.end("hello world\n");
+ }).listen(8000);
## https.request(options, callback)
@@ -91,8 +104,9 @@ The options argument has the following options
The following options from [tls.connect()](tls.html#tls.connect) can also be
specified. However, a [globalAgent](#https.globalAgent) silently ignores these.
+- `pfx`: Certificate, Private key and CA certificates to use for SSL. Default `null`.
- `key`: Private key to use for SSL. Default `null`.
-- `passphrase`: A string of passphrase for the private key. Default `null`.
+- `passphrase`: A string of passphrase for the private key or pfx. Default `null`.
- `cert`: Public x509 certificate to use. Default `null`.
- `ca`: An authority certificate or array of authority certificates to check
the remote host against.
diff --git a/doc/api/stream.markdown b/doc/api/stream.markdown
index cd43c77e7a..7ddca6cc99 100644
--- a/doc/api/stream.markdown
+++ b/doc/api/stream.markdown
@@ -74,11 +74,6 @@ Resumes the incoming `'data'` events after a `pause()`.
Closes the underlying file descriptor. Stream will not emit any more events.
-
-### stream.destroySoon()
-
-After the write queue is drained, close the file descriptor.
-
### stream.pipe(destination, [options])
This is a `Stream.prototype` method available on all `Stream`s.
diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown
index a659006479..f5283c3f95 100644
--- a/doc/api/tls.markdown
+++ b/doc/api/tls.markdown
@@ -28,6 +28,17 @@ Alternatively you can send the CSR to a Certificate Authority for signing.
(TODO: docs on creating a CA, for now interested users should just look at
`test/fixtures/keys/Makefile` in the Node source code)
+To create .pfx or .p12, do this:
+
+ openssl pkcs12 -export -in agent5-cert.pem -inkey agent5-key.pem \
+ -certfile ca-cert.pem -out agent5.pfx
+
+ - `in`: certificate
+ - `inkey`: private key
+ - `certfile`: all CA certs concatenated in one file like
+ `cat ca1-cert.pem ca2-cert.pem > ca-cert.pem`
+
+
## Client-initiated renegotiation attack mitigation
<!-- type=misc -->
@@ -72,10 +83,14 @@ The `connectionListener` argument is automatically set as a listener for the
[secureConnection](#event_secureConnection_) event.
The `options` object has these possibilities:
+ - `pfx`: A string or `Buffer` containing the private key, certificate and
+ CA certs of the server in PFX or PKCS12 format. (Mutually exclusive with
+ the `key`, `cert` and `ca` options.)
+
- `key`: A string or `Buffer` containing the private key of the server in
PEM format. (Required)
- - `passphrase`: A string of passphrase for the private key.
+ - `passphrase`: A string of passphrase for the private key or pfx.
- `cert`: A string or `Buffer` containing the certificate key of the server in
PEM format. (Required)
@@ -155,7 +170,29 @@ Here is a simple example echo server:
console.log('server bound');
});
+Or
+
+ var tls = require('tls');
+ var fs = require('fs');
+
+ var options = {
+ pfx: fs.readFileSync('server.pfx'),
+ // This is necessary only if using the client certificate authentication.
+ requestCert: true,
+
+ };
+
+ var server = tls.createServer(options, function(cleartextStream) {
+ console.log('server connected',
+ cleartextStream.authorized ? 'authorized' : 'unauthorized');
+ cleartextStream.write("welcome!\n");
+ cleartextStream.setEncoding('utf8');
+ cleartextStream.pipe(cleartextStream);
+ });
+ server.listen(8000, function() {
+ console.log('server bound');
+ });
You can test this server by connecting to it with `openssl s_client`:
@@ -177,10 +214,13 @@ Creates a new client connection to the given `port` and `host` (old API) or
creating a new socket. If this option is specified, `host` and `port`
are ignored.
+ - `pfx`: A string or `Buffer` containing the private key, certificate and
+ CA certs of the server in PFX or PKCS12 format.
+
- `key`: A string or `Buffer` containing the private key of the client in
PEM format.
- - `passphrase`: A string of passphrase for the private key.
+ - `passphrase`: A string of passphrase for the private key or pfx.
- `cert`: A string or `Buffer` containing the certificate key of the client in
PEM format.
@@ -233,6 +273,28 @@ Here is an example of a client of echo server as described previously:
server.close();
});
+Or
+
+ var tls = require('tls');
+ var fs = require('fs');
+
+ var options = {
+ pfx: fs.readFileSync('client.pfx')
+ };
+
+ var cleartextStream = tls.connect(8000, options, function() {
+ console.log('client connected',
+ cleartextStream.authorized ? 'authorized' : 'unauthorized');
+ process.stdin.pipe(cleartextStream);
+ process.stdin.resume();
+ });
+ cleartextStream.setEncoding('utf8');
+ cleartextStream.on('data', function(data) {
+ console.log(data);
+ });
+ cleartextStream.on('end', function() {
+ server.close();
+ });
## tls.createSecurePair([credentials], [isServer], [requestCert], [rejectUnauthorized])
diff --git a/lib/crypto.js b/lib/crypto.js
index 05b19755be..67d9ab7cf7 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -115,6 +115,14 @@ exports.createCredentials = function(options, context) {
c.context.setSessionIdContext(options.sessionIdContext);
}
+ if (options.pfx) {
+ if (options.passphrase) {
+ c.context.loadPKCS12(options.pfx, options.passphrase);
+ } else {
+ c.context.loadPKCS12(options.pfx);
+ }
+ }
+
return c;
};
diff --git a/lib/fs.js b/lib/fs.js
index a3e68cb06b..f943719665 100644
--- a/lib/fs.js
+++ b/lib/fs.js
@@ -740,6 +740,7 @@ function FSWatcher() {
this._handle.onchange = function(status, event, filename) {
if (status) {
+ self._handle.close();
self.emit('error', errnoException(errno, 'watch'));
} else {
self.emit('change', event, filename);
@@ -1286,8 +1287,9 @@ ReadStream.prototype.resume = function() {
this.paused = false;
if (this.buffer) {
- this._emitData(this.buffer);
+ var buffer = this.buffer;
this.buffer = null;
+ this._emitData(buffer);
}
// hasn't opened yet.
diff --git a/lib/http.js b/lib/http.js
index ec562da86f..ff9b3cfc03 100644
--- a/lib/http.js
+++ b/lib/http.js
@@ -1315,6 +1315,7 @@ function socketErrorListener(err) {
socket.destroy();
}
+
function responseOnEnd() {
var req = this.req;
var socket = req.socket;
@@ -1397,7 +1398,6 @@ function socketOnEnd() {
socket.destroy();
}
-
function socketOnData(d, start, end) {
var socket = this;
var req = this._httpMessage;
@@ -1461,7 +1461,6 @@ ClientRequest.prototype.onSocket = function(socket) {
socket._httpMessage = req;
-
// Setup "drain" propogation.
httpSocketSetup(socket);
socket.ondata = socketOnData;
diff --git a/lib/path.js b/lib/path.js
index ad8fd8d787..961dc400a5 100644
--- a/lib/path.js
+++ b/lib/path.js
@@ -179,6 +179,9 @@ if (isWindows) {
tail += '\\';
}
+ // Convert slashes to backslashes when `device` points to an UNC root.
+ device = device.replace(/\//g, '\\');
+
return device + (isAbsolute ? '\\' : '') + tail;
};
diff --git a/lib/tls.js b/lib/tls.js
index c7b0825873..9977233563 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -932,6 +932,7 @@ function Server(/* [options], listener */) {
this.setOptions(options);
var sharedCreds = crypto.createCredentials({
+ pfx : self.pfx,
key: self.key,
passphrase: self.passphrase,
cert: self.cert,
@@ -1016,6 +1017,7 @@ Server.prototype.setOptions = function(options) {
this.rejectUnauthorized = false;
}
+ if (options.pfx) this.pfx = options.pfx;
if (options.key) this.key = options.key;
if (options.passphrase) this.passphrase = options.passphrase;
if (options.cert) this.cert = options.cert;
diff --git a/src/node.js b/src/node.js
index 5f2dd87bda..ef0301267f 100644
--- a/src/node.js
+++ b/src/node.js
@@ -480,6 +480,10 @@
// start parsing data from that stream.
if (process.env.NODE_CHANNEL_FD) {
assert(parseInt(process.env.NODE_CHANNEL_FD) >= 0);
+
+ // Make sure it's not accidentally inherited by child processes.
+ delete process.env.NODE_CHANNEL_FD;
+
var cp = NativeModule.require('child_process');
// Load tcp_wrap to avoid situation where we might immediately receive
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 134e58800e..14269d5507 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -43,6 +43,7 @@
# include <pthread.h>
#endif
+
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
# define OPENSSL_CONST const
#else
@@ -150,6 +151,7 @@ void SecureContext::Initialize(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "setSessionIdContext",
SecureContext::SetSessionIdContext);
NODE_SET_PROTOTYPE_METHOD(t, "close", SecureContext::Close);
+ NODE_SET_PROTOTYPE_METHOD(t, "loadPKCS12", SecureContext::LoadPKCS12);
target->Set(String::NewSymbol("SecureContext"), t->GetFunction());
}
@@ -576,6 +578,83 @@ Handle<Value> SecureContext::Close(const Arguments& args) {
return False();
}
+//Takes .pfx or .p12 and password in string or buffer format
+Handle<Value> SecureContext::LoadPKCS12(const Arguments& args) {
+ HandleScope scope;
+
+ BIO* in = NULL;
+ PKCS12* p12 = NULL;
+ EVP_PKEY* pkey = NULL;
+ X509* cert = NULL;
+ STACK_OF(X509)* extraCerts = NULL;
+ char* pass = NULL;
+ bool ret = false;
+
+ SecureContext *sc = ObjectWrap::Unwrap<SecureContext>(args.Holder());
+
+ if (args.Length() < 1) {
+ return ThrowException(Exception::TypeError(
+ String::New("Bad parameter")));
+ }
+
+ in = LoadBIO(args[0]);
+ if (in == NULL) {
+ return ThrowException(Exception::Error(
+ String::New("Unable to load BIO")));
+ }
+
+ if (args.Length() >= 2) {
+ ASSERT_IS_STRING_OR_BUFFER(args[1]);
+
+ int passlen = DecodeBytes(args[1], BINARY);
+ if (passlen < 0) {
+ BIO_free(in);
+ return ThrowException(Exception::TypeError(
+ String::New("Bad password")));
+ }
+ pass = new char[passlen + 1];
+ int pass_written = DecodeWrite(pass, passlen, args[1], BINARY);
+
+ assert(pass_written == passlen);
+ pass[passlen] = '\0';
+ }
+
+ if (d2i_PKCS12_bio(in, &p12) &&
+ PKCS12_parse(p12, pass, &pkey, &cert, &extraCerts) &&
+ SSL_CTX_use_certificate(sc->ctx_, cert) &&
+ SSL_CTX_use_PrivateKey(sc->ctx_, pkey))
+ {
+ // set extra certs
+ while (X509* x509 = sk_X509_pop(extraCerts)) {
+ if (!sc->ca_store_) {
+ sc->ca_store_ = X509_STORE_new();
+ SSL_CTX_set_cert_store(sc->ctx_, sc->ca_store_);
+ }
+
+ X509_STORE_add_cert(sc->ca_store_, x509);
+ SSL_CTX_add_client_CA(sc->ctx_, x509);
+ }
+
+ EVP_PKEY_free(pkey);
+ X509_free(cert);
+ sk_X509_free(extraCerts);
+
+ ret = true;
+ }
+
+ PKCS12_free(p12);
+ BIO_free(in);
+ delete[] pass;
+
+ if (!ret) {
+ unsigned long err = ERR_get_error();
+ const char *str = ERR_reason_error_string(err);
+ return ThrowException(Exception::Error(String::New(str)));
+ }
+
+ return True();
+}
+
#ifdef SSL_PRINT_DEBUG
# define DEBUG_PRINT(...) fprintf (stderr, __VA_ARGS__)
diff --git a/src/node_crypto.h b/src/node_crypto.h
index 9fcddf0133..1ee23c8a74 100644
--- a/src/node_crypto.h
+++ b/src/node_crypto.h
@@ -35,6 +35,7 @@
#include <openssl/x509v3.h>
#include <openssl/hmac.h>
#include <openssl/rand.h>
+#include <openssl/pkcs12.h>
#ifdef OPENSSL_NPN_NEGOTIATED
#include "node_buffer.h"
@@ -68,6 +69,7 @@ class SecureContext : ObjectWrap {
static v8::Handle<v8::Value> SetOptions(const v8::Arguments& args);
static v8::Handle<v8::Value> SetSessionIdContext(const v8::Arguments& args);
static v8::Handle<v8::Value> Close(const v8::Arguments& args);
+ static v8::Handle<v8::Value> LoadPKCS12(const v8::Arguments& args);
SecureContext() : ObjectWrap() {
ctx_ = NULL;
diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc
index 023a009196..f984d3bb3f 100644
--- a/src/pipe_wrap.cc
+++ b/src/pipe_wrap.cc
@@ -205,8 +205,8 @@ void PipeWrap::OnConnection(uv_stream_t* handle, int status) {
assert(wrap->object_.IsEmpty() == false);
if (status != 0) {
- // TODO Handle server error (set errno and call onconnection with NULL)
- assert(0);
+ SetErrno(uv_last_error(uv_default_loop()));
+ MakeCallback(wrap->object_, "onconnection", 0, NULL);
return;
}
diff --git a/test/fixtures/test_cert.pfx b/test/fixtures/test_cert.pfx
new file mode 100644
index 0000000000..fd28781a05
--- /dev/null
+++ b/test/fixtures/test_cert.pfx
Binary files differ
diff --git a/test/gc/test-http-client-timeout.js b/test/gc/test-http-client-timeout.js
index cdf5019fc0..6d705b47eb 100644
--- a/test/gc/test-http-client-timeout.js
+++ b/test/gc/test-http-client-timeout.js
@@ -13,7 +13,7 @@ var http = require('http'),
done = 0,
count = 0,
countGC = 0,
- todo = 400,
+ todo = 550,
common = require('../common.js'),
assert = require('assert'),
PORT = common.PORT;
diff --git a/test/simple/test-child-process-fork-and-spawn.js b/test/simple/test-child-process-fork-and-spawn.js
new file mode 100644
index 0000000000..989bf7ee3a
--- /dev/null
+++ b/test/simple/test-child-process-fork-and-spawn.js
@@ -0,0 +1,53 @@
+// 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 spawn = require('child_process').spawn;
+var fork = require('child_process').fork;
+
+// Fork, then spawn. The spawned process should not hang.
+switch (process.argv[2] || '') {
+case '':
+ fork(__filename, ['fork']).on('exit', checkExit);
+ process.on('exit', haveExit);
+ break;
+case 'fork':
+ spawn(process.execPath, [__filename, 'spawn']).on('exit', checkExit);
+ process.on('exit', haveExit);
+ break;
+case 'spawn':
+ break;
+default:
+ assert(0);
+}
+
+var seenExit = false;
+
+function checkExit(statusCode) {
+ seenExit = true;
+ assert.equal(statusCode, 0);
+ process.nextTick(process.exit);
+}
+
+function haveExit() {
+ assert.equal(seenExit, true);
+}
diff --git a/test/simple/test-crypto.js b/test/simple/test-crypto.js
index 800e3eb5ae..7a23cdf494 100644
--- a/test/simple/test-crypto.js
+++ b/test/simple/test-crypto.js
@@ -38,6 +38,7 @@ var path = require('path');
// Test Certificates
var caPem = fs.readFileSync(common.fixturesDir + '/test_ca.pem', 'ascii');
var certPem = fs.readFileSync(common.fixturesDir + '/test_cert.pem', 'ascii');
+var certPfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx');
var keyPem = fs.readFileSync(common.fixturesDir + '/test_key.pem', 'ascii');
var rsaPubPem = fs.readFileSync(common.fixturesDir + '/test_rsa_pubkey.pem',
'ascii');
@@ -54,8 +55,24 @@ try {
process.exit();
}
-// Test HMAC
+// PFX tests
+assert.doesNotThrow(function() {
+ crypto.createCredentials({pfx:certPfx, passphrase:'sample'});
+});
+assert.throws(function() {
+ crypto.createCredentials({pfx:certPfx});
+}, 'mac verify failure');
+
+assert.throws(function() {
+ crypto.createCredentials({pfx:certPfx, passphrase:'test'});
+}, 'mac verify failure');
+
+assert.throws(function() {
+ crypto.createCredentials({pfx:'sample', passphrase:'test'});
+}, 'not enough data');
+
+// Test HMAC
var h1 = crypto.createHmac('sha1', 'Node')
.update('some data')
.update('to hmac')
diff --git a/test/simple/test-fs-read-stream-resume.js b/test/simple/test-fs-read-stream-resume.js
new file mode 100644
index 0000000000..c3ace49e9f
--- /dev/null
+++ b/test/simple/test-fs-read-stream-resume.js
@@ -0,0 +1,51 @@
+// 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 fs = require('fs');
+var path = require('path');
+
+var file = path.join(common.fixturesDir, 'x.txt');
+var data = '';
+var first = true;
+
+var stream = fs.createReadStream(file);
+stream.setEncoding('utf8');
+stream.on('data', function(chunk) {
+ data += chunk;
+ if (first) {
+ first = false;
+ stream.resume();
+ }
+});
+
+process.nextTick(function() {
+ stream.pause();
+ setTimeout(function() {
+ stream.resume();
+ }, 100);
+});
+
+process.on('exit', function() {
+ assert.equal(data, 'xyz\n');
+});
diff --git a/test/simple/test-https-pfx.js b/test/simple/test-https-pfx.js
new file mode 100644
index 0000000000..bfed64afd6
--- /dev/null
+++ b/test/simple/test-https-pfx.js
@@ -0,0 +1,56 @@
+// 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 https = require('https');
+var fs = require('fs');
+
+var pfx = fs.readFileSync(common.fixturesDir + '/test_cert.pfx');
+
+var options = {
+ host: '127.0.0.1',
+ port: common.PORT,
+ path: '/',
+ pfx: pfx,
+ passphrase: 'sample',
+ requestCert: true
+};
+
+var server = https.createServer(options, function(req, res) {
+ assert.equal(req.socket.authorized, false); // not a client cert
+ assert.equal(req.socket.authorizationError, 'UNABLE_TO_GET_ISSUER_CERT');
+ res.writeHead(200);
+ res.end('OK');
+});
+
+server.listen(options.port, options.host, function() {
+ var data = '';
+
+ https.get(options, function(res) {
+ res.on('data', function(data_) { data += data_ });
+ res.on('end', function() { server.close() });
+ });
+
+ process.on('exit', function() {
+ assert.equal(data, 'OK');
+ });
+});
diff --git a/test/simple/test-path.js b/test/simple/test-path.js
index a5c7372d7d..38a8dab89c 100644
--- a/test/simple/test-path.js
+++ b/test/simple/test-path.js
@@ -194,6 +194,8 @@ if (isWindows) {
assert.equal(path.normalize('a//b//../b'), 'a\\b');
assert.equal(path.normalize('a//b//./c'), 'a\\b\\c');
assert.equal(path.normalize('a//b//.'), 'a\\b');
+ assert.equal(path.normalize('//server/share/dir/file.ext'),
+ '\\\\server\\share\\dir\\file.ext');
} else {
assert.equal(path.normalize('./fixtures///b/../b/c.js'),
'fixtures/b/c.js');