diff --git a/README.md b/README.md index 4a60486b48a..fe04c81391b 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,8 @@ port and host are probably fine and you don't need to supply any arguments. `cre * `redis.createClient(redis_url, options)` * `redis.createClient(port, host, options)` +Note: when `options.socket` is specified the reconnect feature won't work. + #### `options` is an object with the following possible properties: * `host`: *127.0.0.1*; The host to connect to * `port`: *6370*; The port to connect to diff --git a/index.js b/index.js index cfb123ee6cf..ccc4307e5c0 100644 --- a/index.js +++ b/index.js @@ -33,9 +33,21 @@ function handle_detect_buffers_reply (reply, command, buffer_args) { exports.debug_mode = /\bredis\b/i.test(process.env.NODE_DEBUG); -function RedisClient (options) { +function RedisClient (globalOptions) { + globalOptions = globalOptions || {}; + + // extract socket if present + var socket = globalOptions.socket; + + // ensure clone won't try to clone a socket + globalOptions.socket = null; + // Copy the options so they are not mutated - options = clone(options); + var options = clone(globalOptions); + + // add socket if present + options.socket = socket; + events.EventEmitter.call(this); var cnx_options = {}; if (options.path) { @@ -109,8 +121,8 @@ function RedisClient (options) { returnError: function (data) { self.return_error(data); }, - returnBuffers: options.return_buffers || options.detect_buffers, - name: options.parser + returnBuffers: this.options.return_buffers || this.options.detect_buffers, + name: this.options.parser }); this.create_stream(); } @@ -120,24 +132,29 @@ util.inherits(RedisClient, events.EventEmitter); RedisClient.prototype.create_stream = function () { var self = this; - // On a reconnect destroy the former stream and retry - if (this.stream) { + if(!this.options.socket){ + // On a reconnect destroy the former stream and retry + if (this.stream) { this.stream.removeAllListeners(); this.stream.destroy(); - } + } + + /* istanbul ignore if: travis does not work with stunnel atm. Therefor the tls tests are skipped on travis */ + if (this.options.tls) { + this.stream = tls.connect(this.connection_options); + } else { + this.stream = net.createConnection(this.connection_options); + } - /* istanbul ignore if: travis does not work with stunnel atm. Therefor the tls tests are skipped on travis */ - if (this.options.tls) { - this.stream = tls.connect(this.connection_options); } else { - this.stream = net.createConnection(this.connection_options); - } + this.stream = this.options.socket; + } if (this.options.connect_timeout) { - this.stream.setTimeout(this.connect_timeout, function () { - self.retry_totaltime = self.connect_timeout; - self.connection_gone('timeout'); - }); + this.stream.setTimeout(this.connect_timeout, function () { + self.retry_totaltime = self.connect_timeout; + self.connection_gone('timeout'); + }); } /* istanbul ignore next: travis does not work with stunnel atm. Therefor the tls tests are skipped on travis */ @@ -1281,6 +1298,9 @@ var createClient = function (port_arg, host_arg, options) { } else { options.path = port_arg; } + } else if (port_arg instanceof net.Socket && typeof host_arg === 'object') { + options = clone(host_arg); + options.socket = port_arg; } else if (typeof port_arg === 'object' || port_arg === undefined) { options = clone(port_arg || options); options.host = options.host || host_arg; diff --git a/test/connection.spec.js b/test/connection.spec.js index d731fee5fde..46168874e8e 100644 --- a/test/connection.spec.js +++ b/test/connection.spec.js @@ -1,6 +1,7 @@ 'use strict'; var assert = require("assert"); +var net = require("net"); var config = require("./lib/config"); var helper = require('./helper'); var redis = config.redis; @@ -339,6 +340,12 @@ describe("connection tests", function () { assert(create_stream_string === String(redis.RedisClient.prototype.create_stream)); }); + it('supports a socket parameter in options object', function () { + var socket = new net.Socket(); + client = new redis.RedisClient({socket: socket}); + assert.strictEqual(client.stream, socket); + }); + it("throws on strange connection info", function () { client = { end: function() {}