forked from af83/nodetk
-
Notifications
You must be signed in to change notification settings - Fork 1
/
server_tools.js
107 lines (99 loc) · 2.99 KB
/
server_tools.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
var URL = require("url");
var utils = require("nodetk/utils");
exports.get_connector_from_str_routes = function(routes) {
/* Returns connect middleware from given routes.
*
* Arguments:
* - routes: hash looking like:
* {'GET': {"/toto": fct, "/titi": fct},
* 'POST': {"/toto": fct},
* 'DELETE': {"/tutu/tata/": fct}
* }
*
* The routes arg is used to search where to route the current req.
* If nothing found, next() is called.
*
* NOTE: pathnames must be strings, no regexp.
*
*/
return function(req, res, next) {
var url = URL.parse(req.url);
var method = routes[req.method] && routes[req.method][url.pathname];
if(method) method(req, res);
else next();
};
};
exports.get_connector_from_regexp_routes = function(routes) {
/* Returns connect middleware from given routes.
*
* Arguments:
* - routes: hash looking like this:
* {'GET': [['/toto/(\\w+)'}, fct]],
* 'POST': [['...', fct(req, res, match)],
* ['...', fct]],
* }
*
* The given routes dictionnary is used to associate a route
* to a fct to execute.
* - If a route doesn't match any route in the dictionnary,
* next() is called.
* - If a route is matched, then the associated fct is called
* with the match object as argument.
*
* NOTE: pathnames must be strings compilable to regexp or regexps.
* String are modified as following to construct the regexps:
* - '^' is appended at beggining and '$' at end;
* - '/' ar escaped.
* In case of strings, '/' are escaped.
* Beginning/end of line chars will be added before compiling.
*
*/
// Copy routes and replace strings by regexps:
routes = utils.deep_extend({}, routes);
utils.each(routes, function(verb, actions) {
for(var i; i=0; i<actions.length) {
var route = actions[i][0];
if (typeof(route) == 'string') {
route = route.replace(/\//g, '\\/')
actions[i][0] = new RegExp('^' + route + '$');
}
}
});
return function(req, res, next) {
var url = URL.parse(req.url);
var actions = routes[req.method] || [];
for(var i=0; i<actions.length; i++) {
var match = url.pathname.match(actions[i][0]);
if (match) return actions[i][1](req, res, match);
};
next();
};
}
exports.redirect = function(res, url) {
/* Send redirection HTTP reply to result.
*
* Arguments:
* - res: nodejs result object.
* - url: where to redirect.
*
*/
res.writeHead(303, {'Location': url});
res.end();
};
exports.server_error = function(res, err) {
/* Send HTTP 500 result with details about error in body.
* The content-type is set to text/plain.
*
* Arguments:
* - res: nodejs result object.
* - err: error object or string.
*
*/
res.writeHead(500, {'Content-Type': 'text/plain'});
if(typeof err == "string") res.end(err);
else {
res.write('An error has occured: ' + err.message);
res.write('\n\n');
res.end(err.stack);
}
};