summaryrefslogtreecommitdiffstats
path: root/infrastructure/framework-src/modules/sessions.js
diff options
context:
space:
mode:
Diffstat (limited to 'infrastructure/framework-src/modules/sessions.js')
-rw-r--r--infrastructure/framework-src/modules/sessions.js156
1 files changed, 156 insertions, 0 deletions
diff --git a/infrastructure/framework-src/modules/sessions.js b/infrastructure/framework-src/modules/sessions.js
new file mode 100644
index 0000000..3d0041b
--- /dev/null
+++ b/infrastructure/framework-src/modules/sessions.js
@@ -0,0 +1,156 @@
+/**
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS-IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import("dateutils");
+import("fastJSON");
+import("fileutils");
+import("jsutils.{eachProperty,keys}");
+import("stringutils.{randomHash,startsWith,endsWith}");
+import("sync");
+
+jimport("net.appjet.common.util.ExpiringMapping");
+
+//----------------------------------------------------------------
+
+var _DEFAULT_COOKIE_NAME = "SessionID";
+var _DEFAULT_SERVER_EXPIRATION = 3*24*60*60*1000; // 72 hours
+
+function getSessionId(cookieName, createIfNotPresent, domain) {
+ if (request.isComet || request.isCron) {
+ return null;
+ }
+
+ if (request.cookies[cookieName]) {
+ return request.cookies[cookieName];
+ }
+
+ if (!createIfNotPresent) {
+ return null;
+ }
+
+ // Keep sessionId in requestCache so this function can be called multiple
+ // times per request without multiple calls to setCookie().
+ if (!appjet.requestCache.sessionId) {
+ var sessionId = randomHash(16);
+
+ response.setCookie({
+ name: cookieName,
+ value: sessionId,
+ path: "/",
+ domain: (domain || undefined)
+ });
+
+ appjet.requestCache.sessionId = sessionId;
+ }
+
+ return appjet.requestCache.sessionId;
+}
+
+function _getExpiringSessionMap(db) {
+ sync.callsyncIfTrue(db,
+ function() { return (!db.map); },
+ function() { db.map = new ExpiringMapping(_DEFAULT_SERVER_EXPIRATION); });
+ return db.map;
+}
+
+function _getCachedDb() {
+ return appjet.cacheRoot("net.appjet.ajstdlib.session");
+}
+
+//----------------------------------------------------------------
+
+function getSession(opts) {
+ // Session options.
+ if (!opts) { opts = {}; }
+ var cookieName = opts.cookieName || _DEFAULT_COOKIE_NAME;
+
+ // get cookie ID (sets response cookie if necessary)
+ var sessionId = getSessionId(cookieName, true, opts.domain);
+
+ // get expiring session map
+ var db = _getCachedDb();
+ var map = _getExpiringSessionMap(db);
+
+ // get session data object
+ var domainKey = (opts.domain ? opts.domain : "");
+ var dataKey = [domainKey, sessionId].join('$');
+
+ var sessionData = map.get(dataKey);
+ if (!sessionData) {
+ sessionData = {};
+ map.put(dataKey, sessionData);
+ }
+ else {
+ map.touch(dataKey);
+ }
+
+ return sessionData;
+}
+
+function writeSessionsToDisk() {
+ var dateString = dateutils.dateFormat(new Date(), "yyyy-MM-dd");
+ var dataFile = new Packages.java.io.File(appjet.config.sessionStoreDir+"/sessions-"+dateString+".jslog");
+ dataFile.getParentFile().mkdirs();
+ var writer = new java.io.FileWriter(dataFile);
+ var map = _getCachedDb().map;
+ if (! map) { return; }
+ var keyIterator = map.listAllKeys().iterator();
+ while (keyIterator.hasNext()) {
+ var key = keyIterator.next();
+ var session = map.get(key);
+ if (keys(session).length == 0) { continue; }
+ var obj = { key: key, session: session };
+ var json = fastJSON.stringify(obj);
+ writer.write(json);
+ writer.write("\n");
+ }
+ writer.flush();
+ writer.close();
+}
+
+function _extractDate(fname) {
+ var datePart = fname.substr("sessions-".length, "2009-09-24".length);
+ return Number(datePart.split("-").join(""));
+}
+
+function readLatestSessionsFromDisk() {
+ var dir = new Packages.java.io.File(appjet.config.sessionStoreDir);
+ if (! dir.exists()) { return; }
+ var files = dir.listFiles(new Packages.java.io.FilenameFilter({
+ accept: function(dir, name) {
+ return startsWith(name, "sessions") && endsWith(name, ".jslog")
+ }
+ }));
+ if (files.length == 0) { return; }
+ var latestFile = files[0];
+ for (var i = 1; i < files.length; ++i) {
+ if (_extractDate(files[i].getName()) > _extractDate(latestFile.getName())) {
+ latestFile = files[i];
+ }
+ }
+ var map = _getExpiringSessionMap(_getCachedDb());
+ fileutils.eachFileLine(latestFile, function(json) {
+ try {
+ var obj = fastJSON.parse(json);
+ var key = obj.key;
+ var session = obj.session;
+ map.put(key, session);
+ } catch (err) {
+ Packages.java.lang.System.out.println("Error reading sessions file on line '"+json+"': "+String(err));
+ }
+ });
+ latestFile.renameTo(new Packages.java.io.File(latestFile.getParent()+"/used-"+latestFile.getName()));
+}