diff --git a/History.md b/History.md
new file mode 100644
index 0000000..0073b2f
--- /dev/null
+++ b/History.md
@@ -0,0 +1,100 @@
+
+1.2.0 / 2011-11-17
+==================
+
+ * Added an option 'client' to reuse an existing redis Client [Thomas Fritz]
+
+1.1.0 / 2011-10-05
+==================
+
+ * Added `prefix` option
+ * Removed `clear()` and `length()` methods
+
+1.0.7 / 2011-08-04
+==================
+
+ * Fixed: re-select db on connection (reconnection logic issue with node_redis)
+
+1.0.6 / 2011-06-21
+==================
+
+ * Added `socket` option so that we can connect to a sockets as well [mekwall]
+
+1.0.5 / 2011-06-02
+==================
+
+ * Implemented `require("connect-redis")(connect)` for npm 1.x. Closes #23
+
+1.0.4 / 2011-05-01
+==================
+
+ * Changed; issue SELECT immediately since it is queued
+
+1.0.3 / 2011-04-17
+==================
+
+ * Fixed auth support again [garrensmith]
+
+1.0.2 / 2011-04-15
+==================
+
+ * Fixed auth support [garrensmith]
+
+1.0.1 / 2011-04-14
+==================
+
+ * Added authentication support [garrensmith]
+
+1.0.0 / 2011-02-25
+==================
+
+ * Added connect 1.0 support.
+ This release will _not_ work with older versions of connect.
+
+0.2.3 / 2011-02-01
+==================
+
+ * Refactoring
+
+0.2.2 / 2011-01-02
+==================
+
+ * Added `db` option [Clément]
+
+0.2.1 / 2010-12-20
+==================
+
+ * Redis is now an npm dep
+
+0.2.0 / 2010-11-01
+==================
+
+ * Use __SETEX__ instead of __SET__ / __EXPIRE__ combo
+ this should be reasonably faster.
+
+0.1.3 / 2010-10-25
+==================
+
+ * Updated redis
+
+0.1.2 / 2010-09-22
+==================
+
+ * Updated redis
+
+0.1.1 / 2010-09-20
+==================
+
+ * Fixed expires, `maxAge` in seconds
+ * Updated redis
+
+0.1.0 / 2010-09-17
+==================
+
+ * Now using node_redis as the client, much faster
+
+0.0.2 / 2010-07-27
+==================
+
+ * Moved redis to lib/redis
+ * Added lib/connect-redis.js
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..621191e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+
+index.html: lib/connect-redis.js
+ dox \
+ --title "Connect Redis" \
+ --desc "Redis session store for connect backed by [node_redis](http://github.com/mranney/node_redis)." \
+ --ribbon "http://github.com/visionmedia/connect-redis" \
+ $< > $@
diff --git a/README.md b/README.md
deleted file mode 100644
index 4ec1ece..0000000
--- a/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-connect-mredis
-==============
-
-conenct-redis for multi_redis
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
new file mode 100644
index 0000000..b244934
--- /dev/null
+++ b/Readme.md
@@ -0,0 +1,37 @@
+
+# Connect Redis
+
+connect-redis is a Redis session store backed by [node_redis](http://github.com/mranney/node_redis), and is insanely fast :). Requires redis >= `1.3.10` for the _SETEX_ command.
+
+ connect-redis `>= 1.0.0` support only connect `>= 1.0.0`.
+
+## Installation
+
+ $ npm install connect-redis
+
+## Options
+
+ - `client` An existing redis client object you normally get from `redis.createClient()`
+ - `host` Redis server hostname
+ - `port` Redis server portno
+ - `db` Database index to use
+ - `pass` Password for Redis authentication
+ - `prefix` Key prefix defaulting to "sess:"
+ - ... Remaining options passed to the redis `createClient()` method.
+
+## Usage
+
+ Due to npm 1.x changes, we now need to pass connect to the function `connect-redis` exports in order to extend `connect.session.Store`:
+
+ var connect = require('connect')
+ , RedisStore = require('connect-redis')(connect);
+
+ connect.createServer(
+ connect.cookieParser(),
+ // 5 minutes
+ connect.session({ store: new RedisStore, secret: 'keyboard cat' })
+ );
+
+ This means express users may do the following, since `express.session.Store` points to the `connect.session.Store` function:
+
+ var RedisStore = require('connect-redis')(express);
diff --git a/bm.js b/bm.js
new file mode 100644
index 0000000..54741f1
--- /dev/null
+++ b/bm.js
@@ -0,0 +1,21 @@
+
+var redis = require('./lib/redis')
+ , times = 100000;
+
+var n = times
+ , pending = n
+ , client = redis.createClient()
+ , start = new Date;
+
+client.on('connect', function(){
+ while (n--) {
+ client.set('foo:' + n, 'bar', function(err){
+ if (err) throw err;
+ --pending || report();
+ });
+ }
+});
+
+function report() {
+ console.log('\x1b[33m%d\x1b[0m sets in \x1b[32m%d\x1b[0m milliseconds', times, new Date - start);
+}
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..8b54ea8
--- /dev/null
+++ b/index.html
@@ -0,0 +1,232 @@
+
+
+ Connect Redis
+
+
+
+
+
+Connect RedisRedis session store for connect backed by node_redis. | |
| lib/connect-redis.js |
+
+ Module dependencies.
+
+ |
+
+var Store = require('connect').session.Store,
+ redis = require('./redis');
+ |
+
+
+
+ Initialize RedisStore with the given options .
+
+
+
+param: Object options api: public
+ |
+
+var RedisStore = module.exports = function RedisStore(options) {
+ options = options || {};
+ Store.call(this, options);
+ this.client = new redis.createClient(options.port, options.host, options);
+};
+ |
+
+
+
+ Inherit from Store .
+
+ |
+
+RedisStore.prototype.__proto__ = Store.prototype;
+ |
+
+
+
+ Attempt to fetch session by the given hash .
+
+
+
+param: String hash param: Function fn api: public
+ |
+
+RedisStore.prototype.get = function(hash, fn){
+ this.client.get(hash, function(err, data){
+ try {
+ fn(null, data
+ ? JSON.parse(data.toString())
+ : data);
+ } catch (err) {
+ fn(err);
+ }
+ });
+};
+ |
+
+
+
+ Commit the given sess object associated with the given hash .
+
+
+
+param: String hash param: Session sess param: Function fn api: public
+ |
+
+RedisStore.prototype.set = function(hash, sess, fn){
+ var self = this;
+ try {
+ this.client.set(hash, JSON.stringify(sess), function(){
+ self.client.expire(hash, self.maxAge / 1000 | 0);
+ fn && fn.apply(this, arguments);
+ });
+ } catch (err) {
+ fn && fn(err);
+ }
+};
+ |
+
+
+
+ Destroy the session associated with the given hash .
+
+
+
+param: String hash api: public
+ |
+
+RedisStore.prototype.destroy = function(hash, fn){
+ this.client.del(hash, fn);
+};
+ |
+
+
+
+ Fetch number of sessions.
+
+
+
+param: Function fn api: public
+ |
+
+RedisStore.prototype.length = function(fn){
+ this.client.dbsize(fn);
+};
+ |
+
+
+
+ Clear all sessions.
+
+
+
+param: Function fn api: public
+ |
+
+RedisStore.prototype.clear = function(fn){
+ this.client.flushdb(fn);
+};
+ |
+
+
\ No newline at end of file
diff --git a/index.js b/index.js
new file mode 100644
index 0000000..64efef5
--- /dev/null
+++ b/index.js
@@ -0,0 +1,2 @@
+
+module.exports = require('./lib/connect-mredis');
diff --git a/lib/connect-mredis.js b/lib/connect-mredis.js
new file mode 100644
index 0000000..fb4a18d
--- /dev/null
+++ b/lib/connect-mredis.js
@@ -0,0 +1,131 @@
+/*!
+ * Connect - Redis
+ * Copyright(c) 2010 TJ Holowaychuk
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+
+var redis = require('mredis');
+
+/**
+ * One day in seconds.
+ */
+
+var oneDay = 86400;
+
+/**
+ * Return the `RedisStore` extending `connect`'s session Store.
+ *
+ * @param {object} connect
+ * @return {Function}
+ * @api public
+ */
+
+module.exports = function(connect){
+
+ /**
+ * Connect's Store.
+ */
+
+ var Store = connect.session.Store;
+
+ /**
+ * Initialize RedisStore with the given `options`.
+ *
+ * @param {Object} options
+ * @api public
+ */
+
+ function RedisStore(options) {
+ options = options || {};
+ Store.call(this, options);
+ this.prefix = null == options.prefix
+ ? 'sess:'
+ : options.prefix;
+ //this.client = options.client || new redis.createClient(options.port || options.socket, options.host, options);
+ this.client = options.client || new redis.createClient(options);
+ if (options.pass) {
+ this.client.auth(options.pass, function(err){
+ if (err) throw err;
+ });
+ }
+
+ if (options.db) {
+ var self = this;
+ self.client.select(options.db);
+ self.client.on("connect", function(client) {
+ client.send_anyways = true;
+ client.select(options.db);
+ client.send_anyways = false;
+ });
+ }
+ };
+
+ /**
+ * Inherit from `Store`.
+ */
+
+ RedisStore.prototype.__proto__ = Store.prototype;
+
+ /**
+ * Attempt to fetch session by the given `sid`.
+ *
+ * @param {String} sid
+ * @param {Function} fn
+ * @api public
+ */
+
+ RedisStore.prototype.get = function(sid, fn){
+ sid = this.prefix + sid;
+ this.client.get(sid, function(err, data){
+ if (!data) return fn();
+ try {
+ var dataJson = JSON.parse(data.toString());
+ } catch (err) {
+ return fn(err);
+ }
+ fn(null, dataJson);
+ });
+ };
+ /**
+ * Commit the given `sess` object associated with the given `sid`.
+ *
+ * @param {String} sid
+ * @param {Session} sess
+ * @param {Function} fn
+ * @api public
+ */
+
+ RedisStore.prototype.set = function(sid, sess, fn){
+ sid = this.prefix + sid;
+ try {
+ var maxAge = sess.cookie.maxAge
+ , ttl = 'number' == typeof maxAge
+ ? maxAge / 1000 | 0
+ : oneDay
+ , sess = JSON.stringify(sess);
+ }catch(err){
+ return fn&&fn(err);
+ }
+ this.client.setex(sid, ttl, sess, function(){
+ fn && fn.apply(this, arguments);
+ });
+ };
+
+ /**
+ * Destroy the session associated with the given `sid`.
+ *
+ * @param {String} sid
+ * @api public
+ */
+
+ RedisStore.prototype.destroy = function(sid, fn){
+ sid = this.prefix + sid;
+ this.client.del(sid, fn);
+ };
+
+ return RedisStore;
+};
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..80d0804
--- /dev/null
+++ b/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "connect-mredis",
+ "description": "Redis session store for Connect",
+ "version": "1.0.6",
+ "author": {
+ "name": "dead_horse",
+ "email": "heyiyu.deadhorse@gmail.com"
+ },
+ "main": "./index.js",
+ "dependencies": {
+ "mredis": ">= 1.1.0"
+ },
+ "devDependencies": {
+ "connect": ">=1.4.x"
+ },
+ "engines": {
+ "node": ">= 0.1.98"
+ },
+ "_id": "connect-mredis@1.0.6",
+ "dist": {
+ "shasum": "45352c25c299fe5e42bb62b5bab3d8a08bd8edbd"
+ },
+ "_from": "connect-mredis@=1.0.6"
+}
diff --git a/test.js b/test.js
new file mode 100644
index 0000000..1b96973
--- /dev/null
+++ b/test.js
@@ -0,0 +1,40 @@
+
+/**
+ * Module dependencies.
+ */
+
+var assert = require('assert')
+ , connect = require('connect')
+ , RedisStore = require('./')(connect);
+
+var store = new RedisStore;
+store.client.on('connect', function(){
+ // #set()
+ store.set('123', { cookie: { maxAge: 2000 }, name: 'tj' }, function(err, ok){
+ assert.ok(!err, '#set() got an error');
+ assert.ok(ok, '#set() is not ok');
+ // #get()
+ store.get('123', function(err, data){
+ assert.ok(!err, '#get() got an error');
+ //throw new Error('uncaughtException');
+ assert.deepEqual({ cookie: { maxAge: 2000 }, name: 'tj' }, data);
+ store.destroy('123', function(){
+ store.get('123',function(err, data){
+ assert.ok(!err, '#get() null got an error');
+ assert.ok(!data, '#get() null got data error');
+ throw new Error('uncaughtException');
+ store.client.end();
+ })
+ });
+ })
+ });
+});
+
+process.on('uncaughtException', function (err) {
+ if(err.message==='uncaughtException'){
+ console.log('done');
+ }else{
+ console.log(err.message);
+ }
+ store.client.end();
+});