/* automatically generated by JSCoverage - do not edit */
if (typeof _$jscoverage === 'undefined') _$jscoverage = {};
if (! _$jscoverage['middleware/session.js']) {
  _$jscoverage['middleware/session.js'] = [];
  _$jscoverage['middleware/session.js'][13] = 0;
  _$jscoverage['middleware/session.js'][25] = 0;
  _$jscoverage['middleware/session.js'][31] = 0;
  _$jscoverage['middleware/session.js'][37] = 0;
  _$jscoverage['middleware/session.js'][38] = 0;
  _$jscoverage['middleware/session.js'][39] = 0;
  _$jscoverage['middleware/session.js'][40] = 0;
  _$jscoverage['middleware/session.js'][46] = 0;
  _$jscoverage['middleware/session.js'][188] = 0;
  _$jscoverage['middleware/session.js'][189] = 0;
  _$jscoverage['middleware/session.js'][198] = 0;
  _$jscoverage['middleware/session.js'][199] = 0;
  _$jscoverage['middleware/session.js'][203] = 0;
  _$jscoverage['middleware/session.js'][204] = 0;
  _$jscoverage['middleware/session.js'][205] = 0;
  _$jscoverage['middleware/session.js'][206] = 0;
  _$jscoverage['middleware/session.js'][209] = 0;
  _$jscoverage['middleware/session.js'][210] = 0;
  _$jscoverage['middleware/session.js'][212] = 0;
  _$jscoverage['middleware/session.js'][214] = 0;
  _$jscoverage['middleware/session.js'][218] = 0;
  _$jscoverage['middleware/session.js'][221] = 0;
  _$jscoverage['middleware/session.js'][225] = 0;
  _$jscoverage['middleware/session.js'][228] = 0;
  _$jscoverage['middleware/session.js'][231] = 0;
  _$jscoverage['middleware/session.js'][235] = 0;
  _$jscoverage['middleware/session.js'][238] = 0;
  _$jscoverage['middleware/session.js'][241] = 0;
  _$jscoverage['middleware/session.js'][243] = 0;
  _$jscoverage['middleware/session.js'][244] = 0;
  _$jscoverage['middleware/session.js'][248] = 0;
  _$jscoverage['middleware/session.js'][249] = 0;
  _$jscoverage['middleware/session.js'][250] = 0;
  _$jscoverage['middleware/session.js'][257] = 0;
  _$jscoverage['middleware/session.js'][260] = 0;
  _$jscoverage['middleware/session.js'][261] = 0;
  _$jscoverage['middleware/session.js'][263] = 0;
  _$jscoverage['middleware/session.js'][264] = 0;
  _$jscoverage['middleware/session.js'][267] = 0;
  _$jscoverage['middleware/session.js'][268] = 0;
  _$jscoverage['middleware/session.js'][269] = 0;
  _$jscoverage['middleware/session.js'][270] = 0;
  _$jscoverage['middleware/session.js'][274] = 0;
  _$jscoverage['middleware/session.js'][275] = 0;
  _$jscoverage['middleware/session.js'][276] = 0;
  _$jscoverage['middleware/session.js'][277] = 0;
  _$jscoverage['middleware/session.js'][278] = 0;
  _$jscoverage['middleware/session.js'][279] = 0;
  _$jscoverage['middleware/session.js'][280] = 0;
  _$jscoverage['middleware/session.js'][281] = 0;
  _$jscoverage['middleware/session.js'][282] = 0;
  _$jscoverage['middleware/session.js'][287] = 0;
  _$jscoverage['middleware/session.js'][288] = 0;
  _$jscoverage['middleware/session.js'][292] = 0;
  _$jscoverage['middleware/session.js'][295] = 0;
  _$jscoverage['middleware/session.js'][296] = 0;
  _$jscoverage['middleware/session.js'][297] = 0;
  _$jscoverage['middleware/session.js'][298] = 0;
  _$jscoverage['middleware/session.js'][299] = 0;
  _$jscoverage['middleware/session.js'][303] = 0;
  _$jscoverage['middleware/session.js'][304] = 0;
  _$jscoverage['middleware/session.js'][305] = 0;
  _$jscoverage['middleware/session.js'][307] = 0;
  _$jscoverage['middleware/session.js'][308] = 0;
  _$jscoverage['middleware/session.js'][309] = 0;
  _$jscoverage['middleware/session.js'][310] = 0;
  _$jscoverage['middleware/session.js'][314] = 0;
  _$jscoverage['middleware/session.js'][315] = 0;
  _$jscoverage['middleware/session.js'][316] = 0;
  _$jscoverage['middleware/session.js'][317] = 0;
  _$jscoverage['middleware/session.js'][318] = 0;
  _$jscoverage['middleware/session.js'][320] = 0;
  _$jscoverage['middleware/session.js'][323] = 0;
  _$jscoverage['middleware/session.js'][324] = 0;
  _$jscoverage['middleware/session.js'][325] = 0;
  _$jscoverage['middleware/session.js'][326] = 0;
  _$jscoverage['middleware/session.js'][329] = 0;
  _$jscoverage['middleware/session.js'][330] = 0;
  _$jscoverage['middleware/session.js'][331] = 0;
  _$jscoverage['middleware/session.js'][332] = 0;
  _$jscoverage['middleware/session.js'][333] = 0;
  _$jscoverage['middleware/session.js'][337] = 0;
  _$jscoverage['middleware/session.js'][348] = 0;
  _$jscoverage['middleware/session.js'][349] = 0;
  _$jscoverage['middleware/session.js'][350] = 0;
}
_$jscoverage['middleware/session.js'][13]++;
var Session = require("./session/session"), debug = require("debug")("connect:session"), MemoryStore = require("./session/memory"), signature = require("cookie-signature"), Cookie = require("./session/cookie"), Store = require("./session/store"), utils = require("./../utils"), parse = utils.parseUrl, crc16 = require("crc").crc16;
_$jscoverage['middleware/session.js'][25]++;
var env = process.env.NODE_ENV;
_$jscoverage['middleware/session.js'][31]++;
exports = module.exports = session;
_$jscoverage['middleware/session.js'][37]++;
exports.Store = Store;
_$jscoverage['middleware/session.js'][38]++;
exports.Cookie = Cookie;
_$jscoverage['middleware/session.js'][39]++;
exports.Session = Session;
_$jscoverage['middleware/session.js'][40]++;
exports.MemoryStore = MemoryStore;
_$jscoverage['middleware/session.js'][46]++;
var warning = "Warning: connection.session() MemoryStore is not\ndesigned for a production environment, as it will leak\nmemory, and will not scale past a single process.";
_$jscoverage['middleware/session.js'][188]++;
function session(options) {
  _$jscoverage['middleware/session.js'][189]++;
  var options = options || {}, key = options.key || "connect.sid", store = options.store || new MemoryStore(), cookie = options.cookie || {}, trustProxy = options.proxy, storeReady = true;
  _$jscoverage['middleware/session.js'][198]++;
  if ("production" == env && store instanceof MemoryStore) {
    _$jscoverage['middleware/session.js'][199]++;
    console.warn(warning);
  }
  _$jscoverage['middleware/session.js'][203]++;
  store.generate = (function (req) {
  _$jscoverage['middleware/session.js'][204]++;
  req.sessionID = utils.uid(24);
  _$jscoverage['middleware/session.js'][205]++;
  req.session = new Session(req);
  _$jscoverage['middleware/session.js'][206]++;
  req.session.cookie = new Cookie(cookie);
});
  _$jscoverage['middleware/session.js'][209]++;
  store.on("disconnect", (function () {
  _$jscoverage['middleware/session.js'][209]++;
  storeReady = false;
}));
  _$jscoverage['middleware/session.js'][210]++;
  store.on("connect", (function () {
  _$jscoverage['middleware/session.js'][210]++;
  storeReady = true;
}));
  _$jscoverage['middleware/session.js'][212]++;
  return (function session(req, res, next) {
  _$jscoverage['middleware/session.js'][214]++;
  if (req.session) {
    _$jscoverage['middleware/session.js'][214]++;
    return next();
  }
  _$jscoverage['middleware/session.js'][218]++;
  if (! storeReady) {
    _$jscoverage['middleware/session.js'][218]++;
    return debug("store is disconnected"), next();
  }
  _$jscoverage['middleware/session.js'][221]++;
  if (0 != req.originalUrl.indexOf(cookie.path || "/")) {
    _$jscoverage['middleware/session.js'][221]++;
    return next();
  }
  _$jscoverage['middleware/session.js'][225]++;
  var secret = options.secret || req.secret;
  _$jscoverage['middleware/session.js'][228]++;
  if (! secret) {
    _$jscoverage['middleware/session.js'][228]++;
    throw new Error("`secret` option required for sessions");
  }
  _$jscoverage['middleware/session.js'][231]++;
  var originalHash, originalId;
  _$jscoverage['middleware/session.js'][235]++;
  req.sessionStore = store;
  _$jscoverage['middleware/session.js'][238]++;
  var rawCookie = req.cookies[key];
  _$jscoverage['middleware/session.js'][241]++;
  var unsignedCookie = req.signedCookies[key];
  _$jscoverage['middleware/session.js'][243]++;
  if (! unsignedCookie && rawCookie) {
    _$jscoverage['middleware/session.js'][244]++;
    unsignedCookie = utils.parseSignedCookie(rawCookie, secret);
  }
  _$jscoverage['middleware/session.js'][248]++;
  res.on("header", (function () {
  _$jscoverage['middleware/session.js'][249]++;
  if (! req.session) {
    _$jscoverage['middleware/session.js'][249]++;
    return;
  }
  _$jscoverage['middleware/session.js'][250]++;
  var cookie = req.session.cookie, proto = (req.headers["x-forwarded-proto"] || "").toLowerCase(), tls = req.connection.encrypted || (trustProxy && "https" == proto), secured = cookie.secure && tls, isNew = unsignedCookie != req.sessionID;
  _$jscoverage['middleware/session.js'][257]++;
  if (cookie.secure && ! secured) {
    _$jscoverage['middleware/session.js'][257]++;
    return debug("not secured");
  }
  _$jscoverage['middleware/session.js'][260]++;
  if (null == cookie.expires) {
    _$jscoverage['middleware/session.js'][261]++;
    if (! isNew) {
      _$jscoverage['middleware/session.js'][261]++;
      return debug("already set browser-session cookie");
    }
  }
  else {
    _$jscoverage['middleware/session.js'][263]++;
    if (originalHash == hash(req.session) && originalId == req.session.id) {
      _$jscoverage['middleware/session.js'][264]++;
      return debug("unmodified session");
    }
  }
  _$jscoverage['middleware/session.js'][267]++;
  var val = "s:" + signature.sign(req.sessionID, secret);
  _$jscoverage['middleware/session.js'][268]++;
  val = cookie.serialize(key, val);
  _$jscoverage['middleware/session.js'][269]++;
  debug("set-cookie %s", val);
  _$jscoverage['middleware/session.js'][270]++;
  res.setHeader("Set-Cookie", val);
}));
  _$jscoverage['middleware/session.js'][274]++;
  var end = res.end;
  _$jscoverage['middleware/session.js'][275]++;
  res.end = (function (data, encoding) {
  _$jscoverage['middleware/session.js'][276]++;
  res.end = end;
  _$jscoverage['middleware/session.js'][277]++;
  if (! req.session) {
    _$jscoverage['middleware/session.js'][277]++;
    return res.end(data, encoding);
  }
  _$jscoverage['middleware/session.js'][278]++;
  debug("saving");
  _$jscoverage['middleware/session.js'][279]++;
  req.session.resetMaxAge();
  _$jscoverage['middleware/session.js'][280]++;
  req.session.save((function () {
  _$jscoverage['middleware/session.js'][281]++;
  debug("saved");
  _$jscoverage['middleware/session.js'][282]++;
  res.end(data, encoding);
}));
});
  _$jscoverage['middleware/session.js'][287]++;
  function generate() {
    _$jscoverage['middleware/session.js'][288]++;
    store.generate(req);
}
  _$jscoverage['middleware/session.js'][292]++;
  req.sessionID = unsignedCookie;
  _$jscoverage['middleware/session.js'][295]++;
  if (! req.sessionID) {
    _$jscoverage['middleware/session.js'][296]++;
    debug("no SID sent, generating session");
    _$jscoverage['middleware/session.js'][297]++;
    generate();
    _$jscoverage['middleware/session.js'][298]++;
    next();
    _$jscoverage['middleware/session.js'][299]++;
    return;
  }
  _$jscoverage['middleware/session.js'][303]++;
  var pause = utils.pause(req);
  _$jscoverage['middleware/session.js'][304]++;
  debug("fetching %s", req.sessionID);
  _$jscoverage['middleware/session.js'][305]++;
  store.get(req.sessionID, (function (err, sess) {
  _$jscoverage['middleware/session.js'][307]++;
  var _next = next;
  _$jscoverage['middleware/session.js'][308]++;
  next = (function (err) {
  _$jscoverage['middleware/session.js'][309]++;
  _next(err);
  _$jscoverage['middleware/session.js'][310]++;
  pause.resume();
});
  _$jscoverage['middleware/session.js'][314]++;
  if (err) {
    _$jscoverage['middleware/session.js'][315]++;
    debug("error");
    _$jscoverage['middleware/session.js'][316]++;
    if ("ENOENT" == err.code) {
      _$jscoverage['middleware/session.js'][317]++;
      generate();
      _$jscoverage['middleware/session.js'][318]++;
      next();
    }
    else {
      _$jscoverage['middleware/session.js'][320]++;
      next(err);
    }
  }
  else {
    _$jscoverage['middleware/session.js'][323]++;
    if (! sess) {
      _$jscoverage['middleware/session.js'][324]++;
      debug("no session found");
      _$jscoverage['middleware/session.js'][325]++;
      generate();
      _$jscoverage['middleware/session.js'][326]++;
      next();
    }
    else {
      _$jscoverage['middleware/session.js'][329]++;
      debug("session found");
      _$jscoverage['middleware/session.js'][330]++;
      store.createSession(req, sess);
      _$jscoverage['middleware/session.js'][331]++;
      originalId = req.sessionID;
      _$jscoverage['middleware/session.js'][332]++;
      originalHash = hash(sess);
      _$jscoverage['middleware/session.js'][333]++;
      next();
    }
  }
}));
});
}
_$jscoverage['middleware/session.js'][337]++;
;
_$jscoverage['middleware/session.js'][348]++;
function hash(sess) {
  _$jscoverage['middleware/session.js'][349]++;
  return crc16(JSON.stringify(sess, (function (key, val) {
  _$jscoverage['middleware/session.js'][350]++;
  if ("cookie" != key) {
    _$jscoverage['middleware/session.js'][350]++;
    return val;
  }
})));
}
_$jscoverage['middleware/session.js'].source = ["","/*!"," * Connect - session"," * Copyright(c) 2010 Sencha Inc."," * Copyright(c) 2011 TJ Holowaychuk"," * MIT Licensed"," */","","/**"," * Module dependencies."," */","","var Session = require('./session/session')","  , debug = require('debug')('connect:session')","  , MemoryStore = require('./session/memory')","  , signature = require('cookie-signature')","  , Cookie = require('./session/cookie')","  , Store = require('./session/store')","  , utils = require('./../utils')","  , parse = utils.parseUrl","  , crc16 = require('crc').crc16;","","// environment","","var env = process.env.NODE_ENV;","","/**"," * Expose the middleware."," */","","exports = module.exports = session;","","/**"," * Expose constructors."," */","","exports.Store = Store;","exports.Cookie = Cookie;","exports.Session = Session;","exports.MemoryStore = MemoryStore;","","/**"," * Warning message for `MemoryStore` usage in production."," */","","var warning = 'Warning: connection.session() MemoryStore is not\\n'","  + 'designed for a production environment, as it will leak\\n'","  + 'memory, and will not scale past a single process.';","","/**"," * Session:"," * "," *   Setup session store with the given `options`."," *"," *   Session data is _not_ saved in the cookie itself, however"," *   cookies are used, so we must use the [cookieParser()](cookieParser.html)"," *   middleware _before_ `session()`."," *"," * Examples:"," *"," *     connect()"," *       .use(connect.cookieParser())"," *       .use(connect.session({ secret: 'keyboard cat', key: 'sid', cookie: { secure: true }}))"," *"," * Options:"," *"," *   - `key` cookie name defaulting to `connect.sid`"," *   - `store` session store instance"," *   - `secret` session cookie is signed with this secret to prevent tampering"," *   - `cookie` session cookie settings, defaulting to `{ path: '/', httpOnly: true, maxAge: null }`"," *   - `proxy` trust the reverse proxy when setting secure cookies (via \"x-forwarded-proto\")"," *"," * Cookie option:"," *"," *  By default `cookie.maxAge` is `null`, meaning no \"expires\" parameter is set"," *  so the cookie becomes a browser-session cookie. When the user closes the "," *  browser the cookie (and session) will be removed."," *"," * ## req.session"," *"," *  To store or access session data, simply use the request property `req.session`,"," *  which is (generally) serialized as JSON by the store, so nested objects "," *  are typically fine. For example below is a user-specific view counter:"," *"," *       connect()"," *         .use(connect.favicon())"," *         .use(connect.cookieParser())"," *         .use(connect.session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))"," *         .use(function(req, res, next){"," *           var sess = req.session;"," *           if (sess.views) {"," *             res.setHeader('Content-Type', 'text/html');"," *             res.write('&lt;p&gt;views: ' + sess.views + '&lt;/p&gt;');"," *             res.write('&lt;p&gt;expires in: ' + (sess.cookie.maxAge / 1000) + 's&lt;/p&gt;');"," *             res.end();"," *             sess.views++;"," *           } else {"," *             sess.views = 1;"," *             res.end('welcome to the session demo. refresh!');"," *           }"," *         }"," *       )).listen(3000);"," *"," * ## Session#regenerate()"," *"," *  To regenerate the session simply invoke the method, once complete"," *  a new SID and `Session` instance will be initialized at `req.session`."," *"," *      req.session.regenerate(function(err){"," *        // will have a new session here"," *      });"," *"," * ## Session#destroy()"," *"," *  Destroys the session, removing `req.session`, will be re-generated next request."," *"," *      req.session.destroy(function(err){"," *        // cannot access session here"," *      });"," * "," * ## Session#reload()"," *"," *  Reloads the session data."," *"," *      req.session.reload(function(err){"," *        // session updated"," *      });"," *"," * ## Session#save()"," *"," *  Save the session."," *"," *      req.session.save(function(err){"," *        // session saved"," *      });"," *"," * ## Session#touch()"," *"," *   Updates the `.maxAge` property. Typically this is"," *   not necessary to call, as the session middleware does this for you."," *"," * ## Session#cookie"," *"," *  Each session has a unique cookie object accompany it. This allows"," *  you to alter the session cookie per visitor. For example we can"," *  set `req.session.cookie.expires` to `false` to enable the cookie"," *  to remain for only the duration of the user-agent."," *"," * ## Session#maxAge"," *"," *  Alternatively `req.session.cookie.maxAge` will return the time"," *  remaining in milliseconds, which we may also re-assign a new value"," *  to adjust the `.expires` property appropriately. The following"," *  are essentially equivalent"," *"," *     var hour = 3600000;"," *     req.session.cookie.expires = new Date(Date.now() + hour);"," *     req.session.cookie.maxAge = hour;"," *"," * For example when `maxAge` is set to `60000` (one minute), and 30 seconds"," * has elapsed it will return `30000` until the current request has completed,"," * at which time `req.session.touch()` is called to reset `req.session.maxAge`"," * to its original value."," *"," *     req.session.cookie.maxAge;"," *     // =&gt; 30000"," *"," * Session Store Implementation:"," *"," * Every session store _must_ implement the following methods"," *"," *    - `.get(sid, callback)`"," *    - `.set(sid, session, callback)`"," *    - `.destroy(sid, callback)`"," *"," * Recommended methods include, but are not limited to:"," *"," *    - `.length(callback)`"," *    - `.clear(callback)`"," *"," * For an example implementation view the [connect-redis](http://github.com/visionmedia/connect-redis) repo."," *"," * @param {Object} options"," * @return {Function}"," * @api public"," */","","function session(options){","  var options = options || {}","    , key = options.key || 'connect.sid'","    , store = options.store || new MemoryStore","    , cookie = options.cookie || {}","    , trustProxy = options.proxy","    , storeReady = true;","","  // notify user that this store is not","  // meant for a production environment","  if ('production' == env &amp;&amp; store instanceof MemoryStore) {","    console.warn(warning);","  }","","  // generates the new session","  store.generate = function(req){","    req.sessionID = utils.uid(24);","    req.session = new Session(req);","    req.session.cookie = new Cookie(cookie);","  };","","  store.on('disconnect', function(){ storeReady = false; });","  store.on('connect', function(){ storeReady = true; });","","  return function session(req, res, next) {","    // self-awareness","    if (req.session) return next();","","    // Handle connection as if there is no session if","    // the store has temporarily disconnected etc","    if (!storeReady) return debug('store is disconnected'), next();","","    // pathname mismatch","    if (0 != req.originalUrl.indexOf(cookie.path || '/')) return next();","","    // backwards compatibility for signed cookies","    // req.secret is passed from the cookie parser middleware","    var secret = options.secret || req.secret;","","    // ensure secret is available or bail","    if (!secret) throw new Error('`secret` option required for sessions');","","    // parse url","    var originalHash","      , originalId;","","    // expose store","    req.sessionStore = store;","","    // grab the session cookie value and check the signature","    var rawCookie = req.cookies[key];","","    // get signedCookies for backwards compat with signed cookies","    var unsignedCookie = req.signedCookies[key];","","    if (!unsignedCookie &amp;&amp; rawCookie) {","      unsignedCookie = utils.parseSignedCookie(rawCookie, secret);","    }","","    // set-cookie","    res.on('header', function(){","      if (!req.session) return;","      var cookie = req.session.cookie","        , proto = (req.headers['x-forwarded-proto'] || '').toLowerCase()","        , tls = req.connection.encrypted || (trustProxy &amp;&amp; 'https' == proto)","        , secured = cookie.secure &amp;&amp; tls","        , isNew = unsignedCookie != req.sessionID;","","      // only send secure cookies via https","      if (cookie.secure &amp;&amp; !secured) return debug('not secured');","","      // browser-session length cookie","      if (null == cookie.expires) {","        if (!isNew) return debug('already set browser-session cookie');","      // compare hashes and ids","      } else if (originalHash == hash(req.session) &amp;&amp; originalId == req.session.id) {","        return debug('unmodified session');","      }","","      var val = 's:' + signature.sign(req.sessionID, secret);","      val = cookie.serialize(key, val);","      debug('set-cookie %s', val);","      res.setHeader('Set-Cookie', val);","    });","","    // proxy end() to commit the session","    var end = res.end;","    res.end = function(data, encoding){","      res.end = end;","      if (!req.session) return res.end(data, encoding);","      debug('saving');","      req.session.resetMaxAge();","      req.session.save(function(){","        debug('saved');","        res.end(data, encoding);","      });","    };","","    // generate the session","    function generate() {","      store.generate(req);","    }","","    // get the sessionID from the cookie","    req.sessionID = unsignedCookie;","","    // generate a session if the browser doesn't send a sessionID","    if (!req.sessionID) {","      debug('no SID sent, generating session');","      generate();","      next();","      return;","    }","","    // generate the session object","    var pause = utils.pause(req);","    debug('fetching %s', req.sessionID);","    store.get(req.sessionID, function(err, sess){","      // proxy to resume() events","      var _next = next;","      next = function(err){","        _next(err);","        pause.resume();","      };","","      // error handling","      if (err) {","        debug('error');","        if ('ENOENT' == err.code) {","          generate();","          next();","        } else {","          next(err);","        }","      // no session","      } else if (!sess) {","        debug('no session found');","        generate();","        next();","      // populate req.session","      } else {","        debug('session found');","        store.createSession(req, sess);","        originalId = req.sessionID;","        originalHash = hash(sess);","        next();","      }","    });","  };","};","","/**"," * Hash the given `sess` object omitting changes"," * to `.cookie`."," *"," * @param {Object} sess"," * @return {String}"," * @api private"," */","","function hash(sess) {","  return crc16(JSON.stringify(sess, function(key, val){","    if ('cookie' != key) return val;","  }));","}"];
