From c1ca9ca164c012801f81ec602c4ff6960f66afb5 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Fri, 27 Oct 2017 16:32:33 -0500 Subject: [PATCH 1/2] feat: add support for rediss protocol in url --- README.md | 2 +- lib/createClient.js | 6 +++++- test/tls.spec.js | 23 +++++++++++++++++++++++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 088f1be9828..5a73332614d 100644 --- a/README.md +++ b/README.md @@ -216,7 +216,7 @@ using unix sockets if possible to increase throughput. | host | 127.0.0.1 | IP address of the Redis server | | port | 6379 | Port of the Redis server | | path | null | The UNIX socket string of the Redis server | -| url | null | The URL of the Redis server. Format: `[redis:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]` (More info avaliable at [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)). | +| url | null | The URL of the Redis server. Format: `[redis:][rediss:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]` (More info avaliable at [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)). | | parser | javascript | __Deprecated__ Use either the built-in JS parser [`javascript`]() or the native [`hiredis`]() parser. __Note__ `node_redis` < 2.6 uses hiredis as default if installed. This changed in v.2.6.0. | | string_numbers | null | Set to `true`, `node_redis` will return Redis number values as Strings instead of javascript Numbers. Useful if you need to handle big numbers (above `Number.MAX_SAFE_INTEGER === 2^53`). Hiredis is incapable of this behavior, so setting this option to `true` will result in the built-in javascript parser being used no matter the value of the `parser` option. | | return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. | diff --git a/lib/createClient.js b/lib/createClient.js index 2f3b09fdb36..8c3a8508a28 100644 --- a/lib/createClient.js +++ b/lib/createClient.js @@ -32,7 +32,11 @@ module.exports = function createClient (port_arg, host_arg, options) { options.password = parsed.auth.split(':')[1]; } if (parsed.protocol && parsed.protocol !== 'redis:') { - console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!'); + if (parsed.protocol === 'rediss:') { + options.tls = options.tls || {}; + } else { + console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!'); + } } if (parsed.pathname && parsed.pathname !== '/') { options.db = parsed.pathname.substr(1); diff --git a/test/tls.spec.js b/test/tls.spec.js index d977ee7d9ac..6a7e021e33c 100644 --- a/test/tls.spec.js +++ b/test/tls.spec.js @@ -108,6 +108,29 @@ describe('TLS connection tests', function () { client.get('foo', helper.isString('bar', done)); }); + describe('using rediss as url protocol', function (done) { + var tls = require('tls') + var tlsConnect = tls.connect + beforeEach(function () { + tls.connect = function (options) { + options = utils.clone(options) + options.ca = tls_options.ca; + return tlsConnect.call(tls, options); + } + }) + afterEach(function () { + tls.connect = tlsConnect; + }) + it('connect with tls when rediss is used as the protocol', function (done) { + if (skip) this.skip(); + client = redis.createClient('rediss://localhost:' + tls_port); + // verify connection is using TCP, not UNIX socket + assert(client.stream.encrypted); + client.set('foo', 'bar'); + client.get('foo', helper.isString('bar', done)); + }); + }) + it('fails to connect because the cert is not correct', function (done) { if (skip) this.skip(); var faulty_cert = utils.clone(tls_options); From b0cafe98b61b7333f7f465871540f9f2c3eab923 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Tue, 9 Jan 2018 10:54:16 -0600 Subject: [PATCH 2/2] docs: add note about rediss usage --- README.md | 4 +++- lib/createClient.js | 4 ++-- test/tls.spec.js | 16 ++++++++-------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 5a73332614d..96d2cee4d35 100644 --- a/README.md +++ b/README.md @@ -210,13 +210,15 @@ arguments. `createClient()` returns a `RedisClient` object. Otherwise, __Tip:__ If the Redis server runs on the same machine as the client consider using unix sockets if possible to increase throughput. +__Note:__ Using `'rediss://...` for the protocol in a `redis_url` will enable a TLS socket connection. However, additional TLS options will need to be passed in `options`, if required. + #### `options` object properties | Property | Default | Description | |-----------|-----------|-------------| | host | 127.0.0.1 | IP address of the Redis server | | port | 6379 | Port of the Redis server | | path | null | The UNIX socket string of the Redis server | -| url | null | The URL of the Redis server. Format: `[redis:][rediss:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]` (More info avaliable at [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)). | +| url | null | The URL of the Redis server. Format: `[redis[s]:]//[[user][:password@]][host][:port][/db-number][?db=db-number[&password=bar[&option=value]]]` (More info avaliable at [IANA](http://www.iana.org/assignments/uri-schemes/prov/redis)). | | parser | javascript | __Deprecated__ Use either the built-in JS parser [`javascript`]() or the native [`hiredis`]() parser. __Note__ `node_redis` < 2.6 uses hiredis as default if installed. This changed in v.2.6.0. | | string_numbers | null | Set to `true`, `node_redis` will return Redis number values as Strings instead of javascript Numbers. Useful if you need to handle big numbers (above `Number.MAX_SAFE_INTEGER === 2^53`). Hiredis is incapable of this behavior, so setting this option to `true` will result in the built-in javascript parser being used no matter the value of the `parser` option. | | return_buffers | false | If set to `true`, then all replies will be sent to callbacks as Buffers instead of Strings. | diff --git a/lib/createClient.js b/lib/createClient.js index 8c3a8508a28..133f0b758e9 100644 --- a/lib/createClient.js +++ b/lib/createClient.js @@ -31,10 +31,10 @@ module.exports = function createClient (port_arg, host_arg, options) { if (parsed.auth) { options.password = parsed.auth.split(':')[1]; } - if (parsed.protocol && parsed.protocol !== 'redis:') { + if (parsed.protocol) { if (parsed.protocol === 'rediss:') { options.tls = options.tls || {}; - } else { + } else if (parsed.protocol !== 'redis:') { console.warn('node_redis: WARNING: You passed "' + parsed.protocol.substring(0, parsed.protocol.length - 1) + '" as protocol instead of the "redis" protocol!'); } } diff --git a/test/tls.spec.js b/test/tls.spec.js index 6a7e021e33c..3b0e18197ac 100644 --- a/test/tls.spec.js +++ b/test/tls.spec.js @@ -7,6 +7,7 @@ var helper = require('./helper'); var path = require('path'); var redis = config.redis; var utils = require('../lib/utils'); +var tls = require('tls'); var tls_options = { servername: 'redis.js.org', @@ -90,12 +91,12 @@ describe('TLS connection tests', function () { it('connect with host and port provided in the tls object', function (done) { if (skip) this.skip(); - var tls = utils.clone(tls_options); - tls.port = tls_port; - tls.host = 'localhost'; + var tls_opts = utils.clone(tls_options); + tls_opts.port = tls_port; + tls_opts.host = 'localhost'; client = redis.createClient({ connect_timeout: 1000, - tls: tls + tls: tls_opts }); // verify connection is using TCP, not UNIX socket @@ -109,17 +110,16 @@ describe('TLS connection tests', function () { }); describe('using rediss as url protocol', function (done) { - var tls = require('tls') - var tlsConnect = tls.connect + var tls_connect = tls.connect beforeEach(function () { tls.connect = function (options) { options = utils.clone(options) options.ca = tls_options.ca; - return tlsConnect.call(tls, options); + return tls_connect.call(tls, options); } }) afterEach(function () { - tls.connect = tlsConnect; + tls.connect = tls_connect; }) it('connect with tls when rediss is used as the protocol', function (done) { if (skip) this.skip();