Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Docs

  • Loading branch information...
commit 9d1c18c2eef501a4e4c972cf284415b21f95b13d 1 parent 343cd73
Alexander Dorofeev authored
Showing with 120 additions and 32 deletions.
  1. +33 −29 chain/cookie.js
  2. +87 −3 chain/cookie.md
62 chain/cookie.js
View
@@ -8,7 +8,7 @@ exports.secret = hex_hmac_sha1(Math.random(), Math.random());
*/
Op = {
DEFAULT: function() {
- this.cookies = new Proc(this.request, this.response);
+ this.cookies = new Proc(this.request.headers, this.response);
return this.next();
}
};
@@ -18,16 +18,18 @@ exports.Op = Op;
* Cookie processor.
* @param {http.ServerRequest} request
* @param {http.ServerResponse} response
+ * @param {Boolean} dontDecorate Don't decorate
* @returns {Proc}
*/
-function Proc(request, response) {
- this._request = request;
+function Proc(headers, response, dontDecorate) {
+ this._headers = headers;
this._response = response;
+ this._dontDecorate = dontDecorate;
}
exports.Proc = Proc;
/**
- * Set cookie. At first call decorates method `writeHead` of instance
- * `http.ServerResponse`.
+ * Set cookie. If needed, at first call decorates method `writeHead` of
+ * instance `http.ServerResponse`.
* @param {String} name
* @param value Cookie value
* @param {Object} options Optional options. See readme.
@@ -38,28 +40,30 @@ Proc.prototype.set = function(name, value, options, encrypt) {
if (!this._outgoing) {
this._outgoing = {};
- // Decorate original method
- var _writeHead = this._response.writeHead;
- var COOKIE_KEY = 'Set-Cookie', slice = Array.prototype.slice;
- var self = this;
- this._response.writeHead = function() {
- // Honor the passed args and method signature
- // (see http.writeHead docs)
- var args = slice.call(arguments), headers = args[args.length - 1];
- if (!headers || typeof (headers) != 'object') {
- // No header arg - create and append to args list
- args.push(headers = []);
- }
-
- // Merge cookie values
- var prev = headers[COOKIE_KEY], cookies = self.deploy() || [];
- if (prev) cookies.push(prev);
- if (cookies.length > 0)
- headers[COOKIE_KEY] = cookies;
-
- // Invoke original writeHead()
- _writeHead.apply(this, args);
- };
+ if (!this._dontDecorate) {
+ // Decorate original method
+ var _writeHead = this._response.writeHead;
+ var COOKIE_KEY = 'Set-Cookie', slice = Array.prototype.slice;
+ var self = this;
+ this._response.writeHead = function() {
+ // Honor the passed args and method signature
+ // (see http.writeHead docs)
+ var args = slice.call(arguments), headers = args[args.length - 1];
+ if (!headers || typeof (headers) != 'object') {
+ // No header arg - create and append to args list
+ args.push(headers = []);
+ }
+
+ // Merge cookie values
+ var prev = headers[COOKIE_KEY], cookies = self.deploy() || [];
+ if (prev) cookies.push(prev);
+ if (cookies.length > 0)
+ headers[COOKIE_KEY] = cookies;
+
+ // Invoke original writeHead()
+ _writeHead.apply(this, args);
+ };
+ }
}
// determine expiration date
@@ -100,7 +104,7 @@ Proc.prototype.set = function(name, value, options, encrypt) {
Proc.prototype.get = function(name, decrypt) {
// Parse cookies if not yet parsed
if (!this._incoming) {
- var header = this._request.headers["cookie"] || "";
+ var header = this._headers["cookie"] || "";
var self = this;
this._incoming = {};
@@ -155,7 +159,7 @@ Proc.prototype.clear = function(name) {
* @returns {Array}
*/
Proc.prototype.deploy = function() {
- if (this._outgoing) return;
+ if (!this._outgoing) return;
var stream = [];
for (var k in this._outgoing) {
stream.push(this._outgoing[k]);
90 chain/cookie.md
View
@@ -5,7 +5,91 @@ Architecture independent *node.js* module for work with cookies.
This module written on the basis of
[cookie-node](https://github.com/jed/cookie-node) (with large parts of code).
But unlike it, didn't extends `http.ServerRequest` and
-`http.ServerResponse` objects. Instead that *kaph cookie* decorate
-`writeHead` method of `http.ServerResponse` instance on first set of cookie.
+`http.ServerResponse` objects. Instead that. if it's not forbidden, *kaph
+cookie* decorate `writeHead` method of `http.ServerResponse` instance on first
+set of cookie. This design gives slightly higher but quite acceptable overhead.
+
+## Usage
+
+For use cookies you need make new instance of `cookie.Proc` with two
+argiments given to constructor: `request.headers` and `response`.
+
+ var http = require('http');
+ var kaphCookie = require('kaph/chain/cookie');
+
+ kaphCookie.secret = 'myRandomSecretThatNoOneWillGuess';
+
+ http.createServer(function(request, response) {
+ // Make cookies object
+ var cookie = new kaphCookie.Proc(request.headers, response);
+
+ // Set simple cookie
+ cookie.set('simple', 'Simple value');
+ // ... and encrypted
+ cookie.set('encrypted', 'Secret value', {days: 30}, true);
+
+ // get some cookies
+ var simple = cookie.get('simple');
+ var encrypted = cookie.get('encrypted', true);
+
+ response.writeHead(200, {'Content-Type': "text/html"});
+ response.end('simple: ' + simple +
+ ', encrypted: ' + encrypted);
+ }).listen(9080);
+
+New `cookie` object has two methods `set` and `get`.
+
+`set` method of `cookie` object as is evident from its name, sets new cookie
+and takes four arguments:
+
+* `name` Cookie name
+* `value` Cookie value
+* `options` Optional cookie options (see below)
+* `encrypt` Optional flag to encrypt cookie (see below)
+
+Cookie `options` is object that may contain several optional properties:
+
+* `expires` Cookie expiration `Date`
+* `days` Expiration period in days from `expires` date. If `expires` not given,
+ expiration period sets relative to current date.
+* `path` Cookie path
+* `domain` Cookie domain
+* `secure` Secure (but not encrypted) cookie
+* `httpOnly` HTTP only cookie
+
+`get` method takes two arguments `name` and `decrypt` (see below), and returns
+cookie value or `undefined` if cookie not exists.
+
+### Encrypted cookies
+
+You can encrypt and decrypt your cookies. All that is needed for this - set
+`true` for `encrypt` of `set` method and `decrypt` of `get`. Also you need to
+set `secret` property of cookie module.
+
+*You don't need to set the secret, but your cookies will end up being
+invalidated when the server restarts, and you will be yelled at.*
+
+## Independent usage
+
+If for any reason you don't want to decorate `writeHead` method, just add
+`true` as third argument of constructor:
+
+ var http = require('http');
+ var kaphCookie = require('kaph/chain/cookie');
+
+ http.createServer(function(request, response) {
+ // Make cookies object
+ var cookie = new kaphCookie.Proc(request.headers, response, true);
+
+ cookie.set('simple', 'Simple value');
+ var simple = cookie.get('simple');
+
+ response.writeHead(200, {'Content-Type': "text/html",
+ 'Set-Cookie': cookie.deploy()});
+ response.end('simple: ' + simple);
+ }).listen(9080);
+
+
+
+## Kaph chain usage
-
Please sign in to comment.
Something went wrong with that request. Please try again.