-
Notifications
You must be signed in to change notification settings - Fork 1
/
webapp.js
84 lines (82 loc) · 1.98 KB
/
webapp.js
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
const toKeyValue = kv=>{
let parts = kv.split('=');
return {key:parts[0].trim(),value:parts[1].trim()};
};
const accumulate = (o,kv)=> {
o[kv.key] = kv.value;
return o;
};
const parseBody = text=> text && text.split('&').map(toKeyValue).reduce(accumulate,{}) || {};
let redirect = function(path){
console.log(`redirecting to ${path}`);
this.statusCode = 302;
this.setHeader('location',path);
this.end();
};
const parseCookies = text=> {
try {
return text && text.split(';').map(toKeyValue).reduce(accumulate,{}) || {};
}catch(e){
return {};
}
}
let invoke = function(req,res){
let handler = this._handlers[req.method][req.url];
if(!handler){
return;
}
handler(req,res);
}
const initialize = function(){
this._handlers = {GET:{},POST:{}};
this._preprocess = [];
this._postprocess = [];
};
const get = function(url,handler){
this._handlers.GET[url] = handler;
}
const post = function(url,handler){
this._handlers.POST[url] = handler;
};
const use = function(handler){
this._preprocess.push(handler);
};
const usePostProcess = function(handler){
this._postprocess.push(handler);
}
let urlIsOneOf = function(urls){
return urls.includes(this.url);
}
const main = function(req,res){
res.redirect = redirect.bind(res);
req.urlIsOneOf = urlIsOneOf.bind(req);
req.cookies = parseCookies(req.headers.cookie||'');
let content="";
req.on('data',data=>content+=data.toString())
req.on('end',()=>{
req.body = parseBody(content);
content="";
this._preprocess.forEach(middleware=>{
if(res.finished) return;
middleware(req,res);
});
if(res.finished) return;
invoke.call(this,req,res);
this._postprocess.forEach(middleware=>{
if(res.finished) return;
middleware(req,res);
});
});
};
let create = ()=>{
let rh = (req,res)=>{
main.call(rh,req,res)
};
initialize.call(rh);
rh.get = get;
rh.post = post;
rh.use = use;
rh.usePostProcess = usePostProcess;
return rh;
}
exports.create = create;