-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHost.js
More file actions
113 lines (82 loc) · 2.83 KB
/
Copy pathHost.js
File metadata and controls
113 lines (82 loc) · 2.83 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
'use strict';
var _ = require('lodash');
var BaseServer = require('./BaseServer');
var Func = require('./Func');
var Host = function Host(config) {
BaseServer.call(this, config);
this.functions = Object.create(null);
if (this.config.functions) {
_.forOwn(this.config.functions, function(func, name) {
this.addFunction(name, func);
}, this);
}
};
Host.prototype = Object.create(BaseServer.prototype);
Host.prototype.constructor = Host;
Host.prototype.defaultConfig = _.defaults({
functions: null,
requestDataLimit: '10mb'
}, BaseServer.prototype.defaultConfig);
Host.prototype.getSerializableConfig = function getSerializableConfig() {
var serializableConfig = BaseServer.prototype.getSerializableConfig.call(this);
// Convert `functions` to an array of names
return _.mapValues(serializableConfig, function(val, key) {
if (key === 'functions' && val) {
return Object.keys(val);
}
return val;
});
};
Host.prototype.addFunction = function addFunction(name, func) {
if (this.functions[name] !== undefined) {
throw new Error('A function has already been defined with the name "' + name + '"');
}
this.functions[name] = new Func(name, func);
return this.functions[name];
};
Host.prototype.bindListener = function bindListener(listener) {
BaseServer.prototype.bindListener.call(this, listener);
listener.param('function', function functionLookup(req, res, next, funcName) {
var func = this.functions[funcName];
if (!func) {
this.logger.info('Request for unknown function "' + funcName + '"');
return res.status(404).end('Not found. Unknown function "' + funcName + '"');
}
res.locals.func = func;
next();
}.bind(this));
listener.post('/function/:function', function callFunction(req, res) {
var func = res.locals.func;
this.logger.info('Calling function "' + func.name + '"');
var data = req.body;
var context = {
name: func.name,
host: func,
req: req,
res: res
};
func.call(context, data, this.functionCallbackFactory(context, func));
}.bind(this));
};
Host.prototype.functionCallbackFactory = function functionCallbackFactory(context, func) {
var called = false;
return function functionCallback(err, output) {
if (called) {
err = new Error('Function "' + func.name + '" called its callback more than once');
return this.logger.error(err.stack);
}
// Prevent the callback from being called a second time
called = true;
var res = context.res;
if (err) {
if (!(err instanceof Error)) {
err = new Error(err);
}
this.logger.error('Function: ' + func.name, err.stack);
return res.status(500).end(err.stack);
}
this.logger.info('Function: ' + func.name + ' completed');
res.end(output.toString());
}.bind(this);
};
module.exports = Host;