summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benchmark/crypto/get-ciphers.js20
-rw-r--r--lib/crypto.js36
-rw-r--r--lib/internal/util.js31
-rw-r--r--lib/tls.js16
4 files changed, 65 insertions, 38 deletions
diff --git a/benchmark/crypto/get-ciphers.js b/benchmark/crypto/get-ciphers.js
new file mode 100644
index 0000000000..257c9af2fd
--- /dev/null
+++ b/benchmark/crypto/get-ciphers.js
@@ -0,0 +1,20 @@
+'use strict';
+
+const common = require('../common.js');
+
+const bench = common.createBenchmark(main, {
+ n: [1, 5000],
+ v: ['crypto', 'tls']
+});
+
+function main(conf) {
+ const n = +conf.n;
+ const v = conf.v;
+ const method = require(v).getCiphers;
+ var i = 0;
+
+ common.v8ForceOptimization(method);
+ bench.start();
+ for (; i < n; i++) method();
+ bench.end(n);
+}
diff --git a/lib/crypto.js b/lib/crypto.js
index 4bce371701..9ffff06f7f 100644
--- a/lib/crypto.js
+++ b/lib/crypto.js
@@ -632,41 +632,23 @@ exports.randomBytes = exports.pseudoRandomBytes = randomBytes;
exports.rng = exports.prng = randomBytes;
-exports.getCiphers = function() {
- return filterDuplicates(getCiphers());
-};
-
-
-exports.getHashes = function() {
- return filterDuplicates(getHashes());
-};
+exports.getCiphers = internalUtil.cachedResult(() => {
+ return internalUtil.filterDuplicateStrings(getCiphers());
+});
+exports.getHashes = internalUtil.cachedResult(() => {
+ return internalUtil.filterDuplicateStrings(getHashes());
+});
-exports.getCurves = function() {
- return filterDuplicates(getCurves());
-};
+exports.getCurves = internalUtil.cachedResult(() => {
+ return internalUtil.filterDuplicateStrings(getCurves());
+});
Object.defineProperty(exports, 'fips', {
get: getFipsCrypto,
set: setFipsCrypto
});
-function filterDuplicates(names) {
- // Drop all-caps names in favor of their lowercase aliases,
- // for example, 'sha1' instead of 'SHA1'.
- var ctx = {};
- names.forEach(function(name) {
- var key = name;
- if (/^[0-9A-Z\-]+$/.test(key)) key = key.toLowerCase();
- if (!ctx.hasOwnProperty(key) || ctx[key] < name)
- ctx[key] = name;
- });
-
- return Object.getOwnPropertyNames(ctx).map(function(key) {
- return ctx[key];
- }).sort();
-}
-
// Legacy API
Object.defineProperty(exports, 'createCredentials', {
configurable: true,
diff --git a/lib/internal/util.js b/lib/internal/util.js
index 8e7e51aab9..e3d9a66b3b 100644
--- a/lib/internal/util.js
+++ b/lib/internal/util.js
@@ -121,3 +121,34 @@ exports.normalizeEncoding = function normalizeEncoding(enc) {
}
}
};
+
+// Filters duplicate strings. Used to support functions in crypto and tls
+// modules. Implemented specifically to maintain existing behaviors in each.
+exports.filterDuplicateStrings = function filterDuplicateStrings(items, low) {
+ if (!Array.isArray(items))
+ return [];
+ const len = items.length;
+ if (len <= 1)
+ return items;
+ const map = new Map();
+ for (var i = 0; i < len; i++) {
+ const item = items[i];
+ const key = item.toLowerCase();
+ if (low) {
+ map.set(key, key);
+ } else {
+ if (!map.has(key) || map.get(key) <= item)
+ map.set(key, item);
+ }
+ }
+ return Array.from(map.values()).sort();
+};
+
+exports.cachedResult = function cachedResult(fn) {
+ var result;
+ return () => {
+ if (result === undefined)
+ result = fn();
+ return result;
+ };
+};
diff --git a/lib/tls.js b/lib/tls.js
index 80ea0d7697..695edd8c5a 100644
--- a/lib/tls.js
+++ b/lib/tls.js
@@ -1,6 +1,7 @@
'use strict';
-require('internal/util').assertCrypto(exports);
+const internalUtil = require('internal/util');
+internalUtil.assertCrypto(exports);
const net = require('net');
const url = require('url');
@@ -21,16 +22,9 @@ exports.DEFAULT_CIPHERS =
exports.DEFAULT_ECDH_CURVE = 'prime256v1';
-exports.getCiphers = function() {
- const names = binding.getSSLCiphers();
- // Drop all-caps names in favor of their lowercase aliases,
- var ctx = {};
- names.forEach(function(name) {
- if (/^[0-9A-Z\-]+$/.test(name)) name = name.toLowerCase();
- ctx[name] = true;
- });
- return Object.getOwnPropertyNames(ctx).sort();
-};
+exports.getCiphers = internalUtil.cachedResult(() => {
+ return internalUtil.filterDuplicateStrings(binding.getSSLCiphers(), true);
+});
// Convert protocols array into valid OpenSSL protocols list
// ("\x06spdy/2\x08http/1.1\x08http/1.0")