Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

V0.35

  • Loading branch information...
commit 22611ad42993a73e796e4b8065de31ec6e66a5e2 1 parent 52c6ec7
@mrohad authored
View
16 ChangeLog
@@ -1,3 +1,15 @@
+Change LOG 0.35
+================================
+Features:
+1) Support script only file (SJS)
+2) Performance improvements
+ 2.1) Cache Eval Functions
+ 2.2) prototyping
+
+3) Support for NodeJS 0.2 has been verified
+
+
+
Change LOG 0.3
================================
Features:
@@ -7,6 +19,8 @@ BugFixes
1) bugs with static files support
+
+
Change LOG 0.29
================================
Features:
@@ -15,6 +29,8 @@ Features:
BugFixes
1) forward() is now working again
+
+
Change LOG 0.28
================================
Features:
View
53 README.markdown
@@ -1,6 +1,6 @@
Alligator is a simple application server built on top of AntiNode and Node.js
-Latest Version 0.3
+Latest Version 0.35
# Usage
@@ -21,27 +21,29 @@ Example settings file:
{
"web_app_name" : "Alligator TestApp",
- "port" : 82,
+ "port" : 8080,
"path" : {
- "root":"/home/vadmin/Alligator/WWW/",
- "lib":"/home/vadmin/Alligator/WWWlib/"
+ "root" : "/home/vadmin/ws/Alligator/WWW/",
+ "lib" : "/home/vadmin/ws/Alligator/WWWlib/"
},
"server_script": {
- "ext":"jssp",
- "begin":"<?",
- "begin_additional_write":"=",
- "end":"?>",
- "session_minutes":1,
- "memcached":{
- "enable":0,
- "server":"localhost",
- "port":11211
- }
- },
+ "template_ext" : "jssp",
+ "script_ext" : "sjs",
+ "begin" : "<?",
+ "begin_additional_write": "=",
+ "end" : "?>",
+ "session_minutes" : 1,
+ "memcached" : {
+ "enable" : 0,
+ "server" : "localhost",
+ "port" :11211
+ }
+ },
"debug_mode" : 1,
- "nodes" : 2
+ "nodes" : 1
}
+
This server listens on port 8080 for HTTP requests.
Explanation of properties:
@@ -50,7 +52,8 @@ Explanation of properties:
- `port` - the server listen to this port (default = 80)
- `path.root` - the root folder for the static and dynamic files (default = WWW)
- `path.lib` - the folder for JavaScript files that will get loaded automatically - you can access those via lib.fileName.yourStuff (default = None)
-- `server_script.ext` - the extension of files that contains of server-side script (default = jssp)
+- `server_script.template_ext` - the extension of files that contains of server-side template (default = jssp)
+- `server_script.script_ext` - the extension of files that contains of server-side script (default = sjs)
- `server_script.begin` - the beginning tag for server-side scripting (default = <?)
- `server_script.end` - the end tag for server-side scripting (default = ?>)
- `server_script.session_minutes` - session timeout after X minutes (default = 30)
@@ -143,6 +146,22 @@ view.jssp:
</BODY>
</HTML>
+In case you had like to write JS only you can use a file with the 'script_ext', here is a different way to write logic.jssp
+logic.sjs: (no script tags)
+ var counter = 1;
+ application.get("counter",function(value){
+ log.debug("ApplicationLOGIC.JSSP, value - " +value);
+ if(value == undefined){
+ application.set("counter",1);
+ }else{
+ counter = value+1;
+ application.set("counter",counter);
+ }
+ request.parameters.counter = counter;
+ commands.forward("counter/view.jssp");
+ });
+
+
In case Memcached is enabled, the application and session contexts are being saved there.
# Bugs and Contribution
View
12 WWW/counter/applicationLogi.sjs
@@ -0,0 +1,12 @@
+commands.writeEscapedText("var%20counter%20%3D%201%3B%0A");
+commands.writeEscapedText("application.get%28%22counter%22%2Cfunction%28value%29%7B%0A");
+commands.writeEscapedText("%09log.debug%28%22ApplicationLOGIC.JSSP%2C%20value%20-%20%22%20+value%29%3B%0A");
+commands.writeEscapedText("%09if%28value%20%3D%3D%20undefined%29%7B%0A");
+commands.writeEscapedText("%09%09application.set%28%22counter%22%2C1%29%3B%0A");
+commands.writeEscapedText("%09%7Delse%7B%0A");
+commands.writeEscapedText("%09%09counter%20%3D%20value+1%3B%0A");
+commands.writeEscapedText("%09%09application.set%28%22counter%22%2Ccounter%29%3B%0A");
+commands.writeEscapedText("%09%7D%0A");
+commands.writeEscapedText("%09request.parameters.counter%20%3D%20counter%3B%0A");
+commands.writeEscapedText("%09commands.forward%28%22counter/view.jssp%22%29%3B%09%09%09%09%0A");
+commands.writeEscapedText("%7D%29%3B%09%09%09%09%0A");
View
12 WWW/counter/applicationLogic.sjs
@@ -0,0 +1,12 @@
+var counter = 1;
+application.get("counter",function(value){
+ log.debug("ApplicationLOGIC.JSSP, value - " +value);
+ if(value == undefined){
+ application.set("counter",1);
+ }else{
+ counter = value+1;
+ application.set("counter",counter);
+ }
+ request.parameters.counter = counter;
+ commands.forward("counter/view.jssp");
+});
View
3  WWW/counter/sessionLogic.js
@@ -9,8 +9,7 @@
session.set("counter",counter);
}
request.parameters.counter = counter;
- commands.forward("counter/view.jssp");
- d
+ commands.forward("counter/view.jssp");
});
})
View
14 WWW/counter/sessionLogic.sjs
@@ -0,0 +1,14 @@
+commands.writeEscapedText("");
+ var counter = 1;
+ session.get("counter",function(value){
+ log.debug("SESSIONLOGIC.JSSP, value - " +value);
+ if(value == undefined){
+ session.set("counter",1);
+ }else{
+ counter = value+1;
+ session.set("counter",counter);
+ }
+ request.parameters.counter = counter;
+ commands.forward("counter/view.jssp");
+ });
+
View
13 WWW/counter/view.sjs
@@ -0,0 +1,13 @@
+commands.writeEscapedText("%3CHTML%3E%0A");
+commands.writeEscapedText("%09%3CHEAD%3E%3CTITLE%3EApplication%20Scope%20Counter%20Tester%3C/TITLE%3E%3C/HEAD%3E%0A");
+commands.writeEscapedText("%09%3CBODY%3E%0A");
+commands.writeEscapedText("%09");
+ var counter = request.parameters.counter;
+ if(counter==1)
+ commands.write("First Time");
+ else
+ commands.write("Number of users:" + counter);
+
+
+commands.writeEscapedText("%09%3C/BODY%3E%0A");
+commands.writeEscapedText("%3C/HTML%3E%0A");
View
19 WWW/hello.sjs
@@ -0,0 +1,19 @@
+commands.writeEscapedText("%3CHTML%3E%0A");
+commands.writeEscapedText("%09%09");commands.write("<head><title>nodeJS and antiNode+</title></head>");
+commands.writeEscapedText("%09%3CBODY%3E%0A");
+commands.writeEscapedText("%09%09HELLO%20WORLD%3Cbr/%3E%0A");
+commands.writeEscapedText("%09%09%3Cbr/%3Erequest.parameters.night%3A%20");commands.write(request.parameters.night);commands.writeEscapedText("%3C/br%3E%0A");
+commands.writeEscapedText("%09%09"); if(request.parameters.night != undefined && request.parameters.night=="1"){
+
+commands.writeEscapedText("%09%09Good%20night%21%20%0A");
+commands.writeEscapedText("%09%09");}else{
+commands.writeEscapedText("%09%09Good%20Day%21%0A");
+commands.writeEscapedText("%09%09");}
+commands.writeEscapedText("%09%09%3Cbr/%3E%0A");
+commands.writeEscapedText("%09%09");for (index=0;index<5;index++){ commands.write(index);commands.writeEscapedText("%3B"); }
+commands.writeEscapedText("%09%09%3Cbr/%3E%0A");
+commands.writeEscapedText("%09%09Testing%20the%20lib%3A%09%09%3Cbr/%3E%0A");
+commands.writeEscapedText("%09%09Request%20headers%3A%20");commands.write(lib.test.arrayToString(request.headers));commands.writeEscapedText("%3C/br%3E%0A");
+commands.writeEscapedText("%09%09%3Cbr/%3E%0A");
+commands.writeEscapedText("%09%3C/BODY%3E%0A");
+commands.writeEscapedText("%3C/HTML%3E%0A");
View
8 futureFeatures.txt
@@ -1,5 +1,7 @@
-1) enableing multi-node using memcahced
+1) GZIP and keep-alive
2) require instead of eval (when loading compiled jssp file)
-3) enabling websockets variables
-4) enableing 2-sides tag (script that runs on both server and client side)
+3) enabling WebSockets variables
+4) enabling 2-sides tag (script that runs on both server and client side)
+5) separation of compiled js and jssp files
+6) session - add expire and domain
View
164 lib/application.js
@@ -3,58 +3,58 @@ asemaphore = require('./asemaphore'),
log = require('./log');
-function applicationScope(webAppName,mcOptions){
+var applicationScope = function(webAppName,mcOptions){
this.webAppName = webAppName.replace(" ","");
this.mcOptions = mcOptions;
-
- this.get = function(seprator,key,cb){
- if(this.mcOptions.enable){
- var connection = new Memcache(this.mcOptions.server, this.mcOptions.port);
- log.debug("connectin memcache for get key("+seprator+this.webAppName+key+")");
- connection.get(seprator+this.webAppName+key, function(response) {
- log.debug("Memecahe GET results("+response.success+") - "+response.data);
- if (cb){
- if(response.success)
- try{
-
- cb(JSON.parse(response.data));
- }
- catch(err){
- cb(undefined);
- }
- else
+};
+
+applicationScope.prototype.get = function(seprator,key,cb){
+ if(this.mcOptions.enable){
+ var connection = new Memcache(this.mcOptions.server, this.mcOptions.port);
+ log.debug("connectin memcache for get key("+seprator+this.webAppName+key+")");
+ connection.get(seprator+this.webAppName+key, function(response) {
+ log.debug("Memecahe GET results("+response.success+") - "+response.data);
+ if (cb){
+ if(response.success)
+ try{
+
+ cb(JSON.parse(response.data));
+ }
+ catch(err){
cb(undefined);
- }
- });
- }else
- if (cb) cb(this[seprator+this.webAppName+key]);
- };
+ }
+ else
+ cb(undefined);
+ }
+ });
+ }else
+ if (cb) cb(this[seprator+this.webAppName+key]);
+};
- this.set = function(seprator,key,value,cb){
- if(this.mcOptions.enable){
- var connection = new Memcache(this.mcOptions.server, this.mcOptions.port);
- log.debug("connectin memcache for get key("+seprator+this.webAppName+key+")");
- connection.set(seprator+this.webAppName+key, JSON.stringify(value), {expires:0,flags:0,callback: function () {
- if (cb) cb();
- }});
- }else{
- this[seprator+this.webAppName+key] = value;
+applicationScope.prototype.set = function(seprator,key,value,cb){
+ if(this.mcOptions.enable){
+ var connection = new Memcache(this.mcOptions.server, this.mcOptions.port);
+ log.debug("connectin memcache for get key("+seprator+this.webAppName+key+")");
+ connection.set(seprator+this.webAppName+key, JSON.stringify(value), {expires:0,flags:0,callback: function () {
if (cb) cb();
- }
- };
-
- this.remove = function(seprator,key,cb){
- if(this.mcOptions.enable){
- var connection = new Memcache(this.mcOptions.server, this.mcOptions.port);
- log.debug("connectin memcache for get "+this.mcOptions.server+" " +this.mcOptions.port);
- connection.del(seprator+this.webAppName+key, {callback: function () {
- if (cb) cb();
- }});
- }else
- this[seprator+this.webAppName+key] = undefined;
+ }});
+ }else{
+ this[seprator+this.webAppName+key] = value;
if (cb) cb();
- };
-}
+ }
+};
+
+applicationScope.prototype.remove = function(seprator,key,cb){
+ if(this.mcOptions.enable){
+ var connection = new Memcache(this.mcOptions.server, this.mcOptions.port);
+ log.debug("connectin memcache for get "+this.mcOptions.server+" " +this.mcOptions.port);
+ connection.del(seprator+this.webAppName+key, {callback: function () {
+ if (cb) cb();
+ }});
+ }else
+ this[seprator+this.webAppName+key] = undefined;
+ if (cb) cb();
+};
var instance = undefined;
exports.start = function(webAppName,mcOptions){
@@ -64,44 +64,38 @@ exports.start = function(webAppName,mcOptions){
return instance;
};
-function warpCallBackWithAsemaphore(cb,asemaphore){
- if(!cb)
- return undefined;
- else{
- asemaphore.v();
- return function(){
- asemaphore.p();
- cb.apply(this, Array.prototype.slice.call(arguments, 0));
- };
- }
-}
+var manager = function(seprator,currentAsemaphore){
+ this.seprator = seprator;
+ this.currentAsemaphore = currentAsemaphore;
+};
+
+manager.prototype.get = function(key,cb){
+ if(instance==undefined)
+ throw "You have to call start() first";
+ if(cb!=undefined)
+ instance.get(this.seprator, key, this.currentAsemaphore.warpCallBack(cb));
+ else
+ instance.get(this.seprator, key, undefined);
+};
+
+manager.prototype.set = function(key,value,cb){
+ if(instance==undefined)
+ throw "You have to call start() first";
+ if(cb!=undefined)
+ instance.set(this.seprator, key, value, this.currentAsemaphore.warpCallBack(cb));
+ else
+ instance.set(this.seprator, key, value, undefined);
+};
+
+manager.prototype.remove = function(key,cb){
+ if(instance==undefined)
+ throw "You have to call start() first";
+ if(cb!=undefined)
+ instance.remove(this.seprator, key, this.currentAsemaphore.warpCallBack(cb));
+ else
+ instance.remove(this.seprator, key, undefined);
+};
+
exports.getManager = function(seprator,currentAsemaphore){
- return {
- get : function(key,cb){
- if(instance==undefined)
- throw "You have to call start() first";
- if(cb!=undefined)
- instance.get(seprator, key, asemaphore.warpCallBack(currentAsemaphore,cb));
- else
- instance.get(seprator, key, undefined);
- },
-
- set : function(key,value,cb){
- if(instance==undefined)
- throw "You have to call start() first";
- if(cb!=undefined)
- instance.set(seprator, key, value, asemaphore.warpCallBack(currentAsemaphore,cb));
- else
- instance.set(seprator, key, value, undefined);
- },
-
- remove : function(key,cb){
- if(instance==undefined)
- throw "You have to call start() first";
- if(cb!=undefined)
- instance.remove(seprator, key, asemaphore.warpCallBack(currentAsemaphore,cb));
- else
- instance.remove(seprator, key, undefined);
- }
- };
+ return new manager(seprator,currentAsemaphore);
};
View
54 lib/asemaphore.js
@@ -1,42 +1,40 @@
-//Async semaphore
+//Async Semaphore
var log = require('./log');
-function asemaphore(counter,fireFunc){
- this.counter = (counter==undefined?0:counter);
+var ASemaphore = function(semaphore,fireFunc){
+ this.semaphore = (semaphore==undefined?0:semaphore);
this.fire = fireFunc;
- log.debug("Starting Asemaphore with counter:" +this.counter);
-
-
- this.v = function(){
- ++this.counter;
- log.debug("Asemaphore counter after v(): " +this.counter);
- return this.counter;
- };
-
- this.p = function(){
- if((--this.counter)<1){
- log.debug("Asemaphore fire() after p()");
- this.fire();
- }
- //log.debug("Asemaphore counter after p(): " +this.counter);
- return this.counter;
- };
-
+ log.debug("Starting Asemaphore with semaphore:" +this.semaphore);
+};
-}
+ASemaphore.prototype.v = function(){
+ ++this.semaphore;
+ log.debug("Asemaphore semaphore after v(): " +this.semaphore);
+ return this.semaphore;
+};
-exports.ctor = function(counter,fireFunc){
- return new asemaphore(counter,fireFunc);
+ASemaphore.prototype.p = function(){
+ if((--this.semaphore)<1){
+ log.debug("Asemaphore fire() after p()");
+ this.fire.apply(this,arguments);
+ }
+ //log.debug("Asemaphore counter after p(): " +this.counter);
+ return this.counter;
};
-exports.warpCallBack = function(asemaphore,cb){
+ASemaphore.prototype.warpCallBack = function(cb){
if(cb == undefined)
return undefined;
else{
- asemaphore.v();
+ var sem = this;
+ sem.v();
return function(){
- cb.apply(this, Array.prototype.slice.call(arguments, 0));
- asemaphore.p();
+ cb.apply(sem, Array.prototype.slice.call(arguments, 0));
+ sem.p();
};
}
+};
+
+exports.ctor = function(semaphore,fireFunc){
+ return new ASemaphore(semaphore,fireFunc);
};
View
34 lib/commands.js
@@ -0,0 +1,34 @@
+var log = require('./log');
+
+var commands = function(afterEval,request,response,result,responseHead,handleRequest,flushFunction,flushResponse){
+ this.afterEval = afterEval;
+ this.request = request;
+ this.response = response;
+ this.result = result;
+ this.responseHead = responseHead;
+ this.handleRequest = handleRequest;
+ this.flushFunction = flushFunction;
+ this.flushResponse = flushResponse;
+};
+
+commands.prototype.write = function(text){
+ this.afterEval.push(text);
+};
+
+commands.prototype.writeEscapedText = function(text){
+ this.afterEval.push(unescape(text));
+};
+
+commands.prototype.forward = function(resource){
+ this.flushFunction = this.handleRequest(this.request,this.response,this.resource,this.result.sessionId);
+ this.flushResponse = false;
+};
+
+commands.prototype.sendRedirect = function(url){
+ this.responseHead.status = 301;
+ this.responseHead.headers["location"] = url;
+};
+
+exports.getCommands = function(afterEval,request,response,result,responseHead,handleRequest,flushFunction,flushResponse){
+ return new commands(afterEval,request,response,result,responseHead,handleRequest,flushFunction,flushResponse);
+};
View
251 lib/jssp.js
@@ -1,18 +1,18 @@
var EventEmitter = require('events').EventEmitter,
- http = require('http'),
- fs = require('fs'),
- mime = require('./content-type'),
- pathlib = require('path'),
- uri = require('url'),
- log = require('./log'),
- sys = require('sys'),
- Script = process.binding('evals').Script,
- utils = require('./utils'),
- sessionManager = require('./session'),
- incomingForm = require('./incoming_form').incomingForm,
- multi = require('./multinode/multi-node'),
- asemaphore = require('./asemaphore'),
- applicationManager = require('./application');
+http = require('http'),
+fs = require('fs'),
+mime = require('./content-type'),
+pathlib = require('path'),
+uri = require('url'),
+log = require('./log'),
+sys = require('sys'),
+Script = process.binding('evals').Script,
+utils = require('./utils'),
+sessionManager = require('./session'),
+incomingForm = require('./incoming_form').incomingForm,
+multi = require('./multinode/multi-node'),
+asemaphore = require('./asemaphore'),
+applicationManager = require('./application');
var cachedJssp = [];
var lib = new Object();
@@ -30,7 +30,7 @@ exports.start = function(settings) {
//setting up sessionScope and applicationScope:
applicationScope = applicationManager.start(globalSettings.web_app_name,globalSettings.server_script.memcached);
sessionScope = sessionManager.start(globalSettings.server_script.session_minutes,globalSettings.web_app_name);
-
+
//Load utils dynamicly
if(globalSettings.path.lib != undefined)
fs.stat(globalSettings.path.lib, function (err, stats) {
@@ -57,8 +57,8 @@ exports.start = function(settings) {
var url = uri.parse(req.url,true);
var pathname = (url.pathname || '/');
var cleanPathname = pathname
- .replace(/\.\.\//g,'') //disallow parent directory access
- .replace(/\%20/g,' '); //convert spaces
+ .replace(/\.\.\//g,'') //disallow parent directory access
+ .replace(/\%20/g,' '); //convert spaces
if(req.method == "GET"){
var params = url.query;
if(params == undefined)
@@ -76,96 +76,98 @@ exports.start = function(settings) {
}
else //Other Methods
handleRequest(req,res,cleanPathname);
-
-
+
+
});
multi.listen({
- port: globalSettings.port,
- nodes: globalSettings.nodes
- }, server);
+ port: globalSettings.port,
+ nodes: globalSettings.nodes
+ }, server);
- console.log('Server running at port '+globalSettings.port);
+ log.warn('Server running at port '+globalSettings.port);
};
function handleRequest(req,res,cleanPathname,newSessionId){
- var root = globalSettings.path.root;
- var path = pathlib.join(root, cleanPathname);
- log.info("Handling request to: " +path + " pid("+process.pid+")");
- //log.debug("Request headers: "+utils.arrayToString(req.headers));
- fs.stat(path, function (err, stats) {
- if (err) {
- // ENOENT is normal on 'file not found'
- if (err.errno != process.ENOENT) {
+ var root = globalSettings.path.root;
+ var path = pathlib.join(root, cleanPathname);
+ log.info("Handling request to: " +path + " pid("+process.pid+")");
+ //log.debug("Request headers: "+utils.arrayToString(req.headers));
+ fs.stat(path, function (err, stats) {
+ if (err) {
+ // ENOENT is normal on 'file not found'
+ if (err.errno != process.ENOENT) {
// any other error is abnormal - log it
log.error("fs.stat(",path,") failed: ", err);
- }
- return fileNotFound(req,res,path);
}
- if (!stats.isFile() && !stats.isDirectory())
- return fileNotFound(req,res,path);
+ return fileNotFound(req,res,path);
+ }
+ if (!stats.isFile() && !stats.isDirectory())
+ return fileNotFound(req,res,path);
+ else{
+ if (stats.isDirectory())
+ path = pathlib.join(path, "index.html");
+ var cookie = req.headers["cookie"];
+ var sessionId = utils.getSessionId(cookie);
+ if(newSessionId!=undefined)//forward
+ sessionId = newSessionId;
else{
- if (stats.isDirectory())
- path = pathlib.join(path, "index.html");
- var cookie = req.headers["cookie"];
- var sessionId = utils.getSessionId(cookie);
- if(newSessionId!=undefined)//forward
- sessionId = newSessionId;
- else{
- sessionScope.hello(sessionId);
- }
- if(!path.endsWith("."+globalSettings.server_script.ext)){
- sendHeaders(req, res,undefined, stats.size, mime.mimeType(path), stats.mtime);
+ sessionScope.hello(sessionId);
+ }
+ if(!(path.endsWith("."+globalSettings.server_script.template_ext) || path.endsWith("."+globalSettings.server_script.script_ext))){
+ log.info("Static request");
+ sendHeaders(req, res,undefined, stats.size, mime.mimeType(path), stats.mtime);
+ var readStream = fs.createReadStream(path);
+ sys.pump(readStream,res);
+ }else{
+ log.info("Dyanmic request");
+ if(path.endsWith("."+globalSettings.server_script.template_ext) && (cachedJssp[path] == undefined || cachedJssp[path+"#date"] != stats.mtime.toUTCString())){
var readStream = fs.createReadStream(path);
- sys.pump(readStream,res);
- }else{
+ var script = [];
+ readStream.addListener("data", function (chunk) {
+ script.push(chunk.toString());
+ });
+ readStream.addListener("end", function () {
+ log.info("STARTING PROCESSING JSSP");
+ serverSideProcessing(script.join(""),req,res,path,stats.mtime,sessionId);
+ log.info("END OF JSSP PROCESSING");
+ });
+ req.connection.addListener('timeout', function() {
+ /* dont destroy it when the fd's already closed */
+ if (readStream.readable) {
+ log.debug('timed out. destroying file read stream');
+ readStream.destroy();
+ }
+ });
+ res.addListener('error', function (err) {
+ log.error('error writing',file,sys.inspect(err));
+ readStream.destroy();
+ });
+ readStream.addListener('fd', function(fd) {
+ log.debug("opened",path,"on fd",fd);
+ });
- if(cachedJssp[path] == undefined || cachedJssp[path+"#date"] != stats.mtime.toUTCString()){
- if(cachedJssp[path] != undefined)
- log.debug("CacheDate = "+cachedJssp[path+"#date"] +" REAL DATE = "+stats.mtime.toUTCString());
- var readStream = fs.createReadStream(path);
- var script = [];
- readStream.addListener("data", function (chunk) {
- script.push(chunk.toString());
- });
- readStream.addListener("end", function () {
- log.info("STARTING PROCESSING JSSP");
- var forward = serverSideProcessing(script.join(""),req,res,path,stats.mtime,sessionId);
- log.info("END OF JSSP PROCESSING");
- });
- req.connection.addListener('timeout', function() {
- /* dont destroy it when the fd's already closed */
- if (readStream.readable) {
- log.debug('timed out. destroying file read stream');
- readStream.destroy();
- }
- });
+ readStream.addListener('error', function (err) {
+ log.error('error reading',file,sys.inspect(err));
+ resp.end('');
+ });
- readStream.addListener('fd', function(fd) {
- log.debug("opened",path,"on fd",fd);
- });
-
- readStream.addListener('error', function (err) {
- log.error('error reading',file,sys.inspect(err));
- resp.end('');
- });
- res.addListener('error', function (err) {
- log.error('error writing',file,sys.inspect(err));
- readStream.destroy();
- });
- }
- else{
- log.info("RUN JSSP FROM CACHE");
- serverSideRunning(cachedJssp[path],req,res,path,stats.mtime,sessionId);
- }
-
+ }
+ else{
+ log.info("RUN JSSP FROM CACHE");
+ var currentFileNameToRead = cachedJssp[path];
+ if(path.endsWith("."+globalSettings.server_script.script_ext))
+ currentFileNameToRead = path.substring(0,path.length-globalSettings.server_script.script_ext.length-1);;
+ serverSideRunning(currentFileNameToRead,req,res,path,stats.mtime,sessionId,false);
}
- }
-
- });
+ }
+
+ }
+
+ });
};
-function serverSideRunning(newfileName,request,response,file,lastMod,sessionId){
+function serverSideRunning(newfileName,request,response,file,lastMod,sessionId,isForceEval){
var responseHead= new Object();
var result = new Object();
result.html = "";
@@ -175,6 +177,7 @@ function serverSideRunning(newfileName,request,response,file,lastMod,sessionId){
responseHead.status = 200;
responseHead.headers = {};
var afterEval = [];
+ //log.debug(asemaphore);
var currentAsemaphore = asemaphore.ctor(1,function(){
if(!error)
result.html = afterEval.join("");
@@ -190,7 +193,7 @@ function serverSideRunning(newfileName,request,response,file,lastMod,sessionId){
//log.debug("WRITE afterEval : "+ afterEval);
afterEval.push(text);
},
- writeEscapedText :function(text){
+ writeEscapedText :function(text){
afterEval.push(unescape(text));
},
forward :function(resource){
@@ -202,32 +205,8 @@ function serverSideRunning(newfileName,request,response,file,lastMod,sessionId){
responseHead.headers["location"] = url;
}
};
- //Waiting for a bug fix(V8)
- /*try{
-
- var script = require(newfileName);
- script.run(lib,application,request,responseHead,writeEscapedText,forward,sendRedirect,write,session);
- result.html = afterEval.join("");
- log.debug("ServerSide result:"+utils.arrayToString(result));
- }
- catch(er){
- log.warn("parse problem:"+err);
- responseHead.status = 500;
- result.html = "<h1>"+globalSettings.web_app_name+" - SERVER ERROR</h1>";
- if(globalSettings.debug_mode){
- result.html += "(Debug Mode) Could not parse jssp<br/> ";
- var erStr = "Details: ";
- result.html += erStr+er.stack;
- }
- else
- result.html += "Could not parse jssp";
- }
- if(allGood){//otherwise, we are probably forwarding...
- var ctHTML = "text/html";
- sendHeaders(request,response,responseHead,result.html.length,mime.mimeType(file,ctHTML),lastMod,result.sessionId);
- response.end(result.html);
- }*/
- var runningFunc = function (errRead, data) {
+
+ var runningFunc = function (errRead, functoRun) {
try{
if (errRead) throw errRead;
//Handling session and application with asemphore
@@ -235,8 +214,11 @@ function serverSideRunning(newfileName,request,response,file,lastMod,sessionId){
var application = applicationManager.getManager("",currentAsemaphore);
var session = sessionManager.getManager(sessionId,currentAsemaphore,applicationManager,result);
//-----------
- command = ["functoRun = ",data.toString()].join("");
- eval(command);
+ if(!(functoRun instanceof Function)){//not in cache
+ command = ["functoRun = (function(log,lib,application,request,responseHead,commands,session) {",functoRun.toString(),"})"].join("");
+ eval(command);
+ cachedJssp[file + "#func"] = functoRun;
+ }
functoRun(log,lib,application,request,responseHead,commands,session);
currentAsemaphore.p();
//log.debug("sessionId - "+result.sessionId);
@@ -256,7 +238,13 @@ function serverSideRunning(newfileName,request,response,file,lastMod,sessionId){
while(currentAsemaphore.p()>0);
}
};
- fs.readFile([newfileName,".js"].join(""),runningFunc);
+ if(cachedJssp[file + "#func"]!= undefined && !isForceEval)//funcCaching
+ runningFunc(undefined,cachedJssp[file + "#func"]);
+ else{
+ var fileNameToRead = [newfileName,".",globalSettings.server_script.script_ext].join("");
+ log.debug("Reading file: "+fileNameToRead);
+ fs.readFile(fileNameToRead,runningFunc);
+ }
}
function serverSideProcessing(str,request,response,file,lastMod,sessionId){
@@ -303,26 +291,25 @@ function serverSideProcessing(str,request,response,file,lastMod,sessionId){
line = line.substring(endTagIndex+endTag.length);
if(line.length==0)
toEvalArray.push(nextLine);
-
+
isInScript = false;
}
}
}
}
-
- var toEval =toEvalArray.join("");
+ //var toEval =
//Waiting for a bug fix(V8)
//http://groups.google.com/group/nodejs/browse_thread/thread/7a2e409ec970198e/d9336b7b2764f129?lnk=gst&q=require+exception#d9336b7b2764f129
//var finalFunction = "exports.run = (function(lib,application,request,responseHead,writeEscapedText,forward,sendRedirect,write,session) {"
// +toEval+"})";
- var finalFunction = "(function(log,lib,application,request,responseHead,commands,session) {"+toEval+"})";
- var newfileName = file.substring(0,file.length-globalSettings.server_script.ext.length-1);
- fs.writeFile(newfileName+".js", finalFunction, function (err) {
+ var finalFunction = toEvalArray.join("");
+ var newfileName = file.substring(0,file.length-globalSettings.server_script.template_ext.length-1);
+ fs.writeFile([newfileName,".",globalSettings.server_script.script_ext].join(""), finalFunction, function (err) {
//log.debug("Error writin cache file: "+err);
cachedJssp[file] = newfileName;
cachedJssp[file + "#date"] = lastMod.toUTCString();
log.info("Caching - "+file + ",last mod - "+ lastMod.toUTCString());
- serverSideRunning(newfileName,request,response,file,lastMod,sessionId);
+ serverSideRunning(newfileName,request,response,file,lastMod,sessionId,true);
});
}
@@ -360,9 +347,9 @@ function fileNotFound(req,res,path) {
responseHead.status = 404;
sendHeaders(req, res,responseHead,body.length,"text/plain");
if (req.method != 'HEAD')
- res.end(body, 'utf-8');
+ res.end(body, 'utf-8');
else
- res.end('');
+ res.end('');
}
function defaultSettings(settings){
@@ -376,8 +363,10 @@ function defaultSettings(settings){
settings.path.root = "WWW";
if(settings.server_script == undefined)
settings.server_script = new Object();
- if(settings.server_script.ext == undefined)
- settings.server_script.ext = "jssp";
+ if(settings.server_script.temlate_ext == undefined)
+ settings.server_script.temlate_ext = "jssp";
+ if(settings.server_script.script_ext == undefined)
+ settings.server_script.script_ext = "sjs";
if(settings.server_script.begin == undefined)
settings.server_script.begin = "<?";
if(settings.server_script.end == undefined)
View
202 lib/session.js
@@ -13,91 +13,90 @@ function createUUID() {
}
-function sessionScope(sessionTimeOutMinutes,webAppName){
+var sessionScope = function(sessionTimeOutMinutes,webAppName){
this.webAppName = webAppName;
this.timers = new Object();
this.numberOfMin = (sessionTimeOutMinutes==undefined?30:sessionTimeOutMinutes);//default 30 min
this.numberOfMili = this.numberOfMin*60*1000;
log.info("Session has been created, session timeout = "+this.numberOfMin+" minutes");
this.latestApllication = undefined;
-
- this.hello = function(uid){
- log.debug("sessionManger.hello: uid - " + uid);
- if(uid != undefined ){
- if(this.timers[this.webAppName+uid] != undefined)
- clearTimeout(this.timers[this.webAppName+uid]);
- this.timers[this.webAppName+uid] = this.setSessionTimeout(this.latestApllication,uid);
+};
+
+sessionScope.prototype.hello = function(uid){
+ log.debug("sessionManger.hello: uid - " + uid);
+ if(uid != undefined ){
+ if(this.timers[this.webAppName+uid] != undefined)
+ clearTimeout(this.timers[this.webAppName+uid]);
+ this.timers[this.webAppName+uid] = this.setSessionTimeout(this.latestApllication,uid);
+ }
+};
+
+sessionScope.prototype.setSessionTimeout = function(application,uid){//adding *minutes* to the uid timeout
+ log.debug("session.setSessionTimeout: uid - " + uid + " app - " + application);
+ var sessionObj = this;
+ return setTimeout((function(application,uid){
+ if(uid!=undefined && application!=undefined){
+ sessionObj.remove(application,uid);
+ sessionObj.timers[sessionObj.webAppName+uid] = undefined;
+ log.info("Clearing session: "+sessionObj.webAppName+uid);
}
- };
+ })
+ ,this.numberOfMili,application,uid);
+};
+
+sessionScope.prototype.remove = function(application,uid,cb){
+ application.remove(uid,cb);
+};
+
+sessionScope.prototype.saveObjectInSession =function(application,key,value,uid,obj,cb){
+ obj[key] = value;
+ application.set(uid,obj,cb);
+};
- this.setSessionTimeout = function(application,uid){//adding *minutes* to the uid timeout
- log.debug("session.setSessionTimeout: uid - " + uid + " app - " + application);
+sessionScope.prototype.set = function(application,key,value,uid,cb){
+ log.debug("sessionMap.set: key-"+key+" value-" +value+" uid-"+uid);
+ this.latestApllication = application;
+ var cont = true;
+ if(uid==undefined){
+ uid = createUUID();
var sessionObj = this;
- return setTimeout((function(application,uid){
- if(uid!=undefined && application!=undefined){
- sessionObj.remove(application,uid);
- sessionObj.timers[sessionObj.webAppName+uid] = undefined;
- log.info("Clearing session: "+sessionObj.webAppName+uid);
+ application.get(uid,function(result){
+ if(result!=undefined)
+ this.set(application,key, value, undefined, cb);
+ else{
+ log.debug("New session UID:"+uid);
+ sessionObj.setSessionTimeout(application,uid);
+ sessionObj.saveObjectInSession(application,key,value,uid,new Object(),cb);
}
- })
- ,this.numberOfMili,application,uid);
- };
-
- this.remove = function(application,uid,cb){
- application.remove(uid,cb);
- };
-
- this.saveObjectInSession =function(application,key,value,uid,obj,cb){
- obj[key] = value;
- application.set(uid,obj,cb);
- };
-
- this.set = function(application,key,value,uid,cb){
- log.debug("sessionMap.set: key-"+key+" value-" +value+" uid-"+uid);
- this.latestApllication = application;
- var cont = true;
- if(uid==undefined){
- uid = createUUID();
- var sessionObj = this;
- //application.get(uid,function(result){
- //if(result!=undefined)
- // this.set(application,key, value, undefined, cb);
- //else{
- log.debug("New session UID:"+uid);
- sessionObj.setSessionTimeout(application,uid);
- sessionObj.saveObjectInSession(application,key,value,uid,new Object(),cb);
- //}
- //});
- }else{
- var saveFunc = this.saveObjectInSession;
- application.get(uid,function(result){
- if(result!=undefined)
- saveFunc(application,key,value,uid,result,cb);
- else
- saveFunc(application,key,value,uid,new Object(),cb);
- });
- }
- //log.debug("sessionMap.set: return uid-"+uid);
- return uid;
- };
-
-
- this.get = function(application,key,uid,cb){
- log.debug("sessionMap.get: key-"+key+" uid-"+uid);
- this.latestApllication = application;
- if(uid==undefined)
- cb(undefined);
- else{
- application.get(uid,function(obj){
- if(obj!=undefined){
- log.debug("appGet@Session - "+obj);
- cb(obj[key]);
- }else
- cb(undefined);
- });
- }
- };
-}
+ });
+ }else{
+ var saveFunc = this.saveObjectInSession;
+ application.get(uid,function(result){
+ if(result!=undefined)
+ saveFunc(application,key,value,uid,result,cb);
+ else
+ saveFunc(application,key,value,uid,new Object(),cb);
+ });
+ }
+ //log.debug("sessionMap.set: return uid-"+uid);
+ return uid;
+};
+
+
+sessionScope.prototype.get = function(application,key,uid,cb){
+ log.debug("sessionMap.get: key-"+key+" uid-"+uid);
+ this.latestApllication = application;
+ if(uid==undefined)
+ cb(undefined);
+ else{
+ application.get(uid,function(obj){
+ if(obj!=undefined){
+ cb(obj[key]);
+ }else
+ cb(undefined);
+ });
+ }
+};
var instance = undefined;
exports.start = function(sessionTimeOutMinutes,webAppName){
@@ -106,28 +105,35 @@ exports.start = function(sessionTimeOutMinutes,webAppName){
return instance;
};
+var manager = function(uid,currentAsemaphore,applicationManager,result){
+ this.application = applicationManager.getManager("ssn-",currentAsemaphore);
+ this.uid = uid;
+ this.currentAsemaphore = currentAsemaphore;
+ this.applicationManager = applicationManager;
+ this.result = result;
+};
+
+
+manager.prototype.get = function(key,cb){
+ if(instance==undefined)
+ throw "You have to call start() first";
+ if(cb!=undefined)
+ instance.get(this.application,key, this.uid, this.currentAsemaphore.warpCallBack(cb));
+ else
+ instance.get(this.application,key, this.uid, undefined);
+};
+
+manager.prototype.set =function(key,value,cb){
+ if(instance==undefined)
+ throw "You have to call start() first";
+ if(cb!=undefined)
+ this.result.sessionId = instance.set(this.application,key, value, this.uid, this.currentAsemaphore.warpCallBack(cb));
+ else
+ this.result.sessionId = instance.set(this.application,key, value, this.uid, undefined);
+ //log.debug("sessionManager.set: result.sessionId - "+result.sessionId);
+};
+
exports.getManager = function(uid,currentAsemaphore,applicationManager,result){
- var application = applicationManager.getManager("ssn-",currentAsemaphore);
- return {
- get : function(key,cb){
- if(instance==undefined)
- throw "You have to call start() first";
- if(cb!=undefined){
- //log.debug("CB"+cb);
- instance.get(application,key, uid, asemaphore.warpCallBack(currentAsemaphore,cb));
- }else
- instance.get(application,key, uid, undefined);
- },
-
- set : function(key,value,cb){
- if(instance==undefined)
- throw "You have to call start() first";
- if(cb!=undefined)
- result.sessionId = instance.set(application,key, value, uid, asemaphore.warpCallBack(currentAsemaphore,cb));
- else{
- result.sessionId = instance.set(application,key, value, uid, undefined);
- log.debug("sessionManager.set: result.sessionId - "+result.sessionId);
- }
- }
- };
+ return new manager(uid,currentAsemaphore,applicationManager,result);
};
+
View
2  package.json
@@ -1,6 +1,6 @@
{ "name" : "Alligator"
, "description" : "A simple application server for node.js"
-, "version" : "0.3"
+, "version" : "0.35"
, "author" : "Ohad Assulin <mrohad.njs@gmail.com>"
, "contributors" :
[ "Mark Hansen <mark@markhansen.co.nz>"
View
27 settings.json
@@ -2,21 +2,22 @@
"web_app_name" : "Alligator TestApp",
"port" : 82,
"path" : {
- "root":"/home/vadmin/ws/Alligator/WWW/",
- "lib":"/home/vadmin/ws/Alligator/WWWlib/"
+ "root" : "/home/vadmin/ws/Alligator/WWW/",
+ "lib" : "/home/vadmin/ws/Alligator/WWWlib/"
},
"server_script": {
- "ext":"jssp",
- "begin":"<?",
- "begin_additional_write":"=",
- "end":"?>",
- "session_minutes":1,
- "memcached":{
- "enable":0,
- "server":"localhost",
- "port":11211
- }
- },
+ "template_ext" : "jssp",
+ "script_ext" : "sjs",
+ "begin" : "<?",
+ "begin_additional_write": "=",
+ "end" : "?>",
+ "session_minutes" : 1,
+ "memcached" : {
+ "enable" : 0,
+ "server" : "localhost",
+ "port" : 11211
+ }
+ },
"debug_mode" : 1,
"nodes" : 1
}
Please sign in to comment.
Something went wrong with that request. Please try again.