-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinit.js
More file actions
153 lines (142 loc) · 4.34 KB
/
init.js
File metadata and controls
153 lines (142 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/**
Provides a simple api gateway interface.
author: Cristian Salazar <christiansalazarh@gmail.com>
*/
var fs = require("fs");
var url = require("url");
// var def = JSON.parse(fs.readFileSync("../routes.json"));
var currentRoutes = {};
/**
find a route and parse path variables. (see "Processing Paths" on README.md)
*/
var findRoute = function(routes, path){
for(var pathExpression in routes){
if (routes.hasOwnProperty(pathExpression)) {
var m="";
if(m = path.match(new RegExp(pathExpression,"i"))){
var route = routes[pathExpression];
var values = {};
route.vars.forEach(function(varname,i){
Object.defineProperty( values , varname ,
{ value: m[i+1], writable: true,
enumerable: true, configurable: true });
});
route.values = values;
return route;
}
}
}
return null;
};
/**
parse values taken into a given object:
{
"development" : true,
"params" : { "path" : { "sysid" : "{sysid}" } }
}
values:
{ "{sysid}" : "123" , "{other}" : "ABC" }
*/
var replaceVariables = function(object, values){
return JSON.parse(JSON.stringify(object).replace(
/{[a-z\s0-9\.\-\_]+}/gi,function(fullvar, nameOnly){
return values[fullvar] ? values[fullvar] : "fullvar";
}));
};
/**
execute the route depending on the "request.method".
*/
var executeRoute = function(route, request, response){
var methodInfo = route[request.method];
if((null == methodInfo) || (undefined==methodInfo)){
// method not supported
var msg = "[method "+request.method
+" not supported in your route definition]";
return new Promise((resolve,reject) => {
reject({ route: route, request: request, response: response , msg: msg});
});
}
var event = replaceVariables(methodInfo.event, route.values);
event.body = null;
var context = methodInfo.context;
// execute the lambda function:
var path = process.env.PWD+"/actions/"+route.lambda.name+".js";
console.log("execute: "+route.lambda.name,"("+path+")");
// this environment var can be used inside lambda functions
process.env.LAMBDA_DIR=path;
var lambda = require(path);
return new Promise((resolve,reject) => {
var doJob = function(){
// TODO: use route.lambda.handler insted of hardwired "handler()"
lambda.handler(event,context,function(err,data){
if(err){
reject(err);
}else{
resolve({ route: route, event: event,
method : methodInfo, payload: data,
request: request, response: response });
}
});
};
if('POST'==request.method){
var chunks = [];
request.on('data',chunk => chunks.push(chunk));
request.on('end',()=>{
event.body = Buffer.concat(chunks);
doJob();
});
}else
doJob();
});
};
var handler = function(request, response) {
var path = url.parse(request.url).pathname;
try{
var route = findRoute(currentRoutes.routes,path);
if(route){
try{
console.log("values:",route.values);
console.log("headers:",request.headers);
executeRoute(route, request, response).then(function(r){
r.response.writeHead(200, r.method.responseHeaders);
r.response.write(
("string" == (typeof r.payload)) ? r.payload
: JSON.stringify(r.payload));
r.response.end();
}).catch(function(r){
console.log("executeRoute Promise.catch:",r.msg);
r.response.end();
});
}catch(ex){
console.log("exception at route level:",ex,"route:",route);
response.end();
}
}else{
console.log("invalid path",path);
response.end();
}}catch(ex){
console.log("exception (path="+path+")",ex);
response.end();
}
};
module.exports = function(routes)
{
currentRoutes = routes;
process.on('uncaughtException', function(err) {
console.log("(unhandled exception)",err)
});
/*entry point*/
if(true == routes.secure){
var proto = require("https");
var key = fs.readFileSync(routes.privatekey).toString();
var cert = fs.readFileSync(routes.certificate).toString();
var pass = routes.passphrase;
console.log("https://localhost:"+routes.port+" (is now active) using:\n"
+"cert:"+routes.certificate+"\nkey:"+routes.privatekey+"\n");
proto.createServer({key:key,cert:cert,passphrase:pass},handler).listen(routes.port);
}else{
var proto = require("http");
console.log("http://localhost:"+routes.port+" (is now active)");
proto.createServer(handler).listen(routes.port);
}
};