-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.js
163 lines (141 loc) · 4.27 KB
/
index.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
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
154
155
156
157
158
159
160
161
162
163
// node internal
const fs = require('fs');
const http = require('http');
const https = require('https');
// node modules
const express = require('express');
const expressBasicAuth = require('express-basic-auth')
const axios = require('axios');
// read config
const config = require('./config.js');
// create express app
const app = express();
console.log('PascalCoin proxy running');
// small middleware to get the request text
app.use((req, res, next) => {
req.setEncoding('utf8');
req.rpc = '';
req.on('data', chunk => req.rpc += chunk);
req.on('end', () => next());
});
if(config.basicAuth.enabled === true) {
console.log(' - using basic authentication');
app.use(expressBasicAuth({
users: config.basicAuth.users,
unauthorizedResponse: () => {
return {
code: -32601,
message: "Invalid credentials",
};
}
}))
}
// if ssl is enabled, start https server
if(config.ssl.enabled === true) {
console.log(' - using SSL');
https.createServer({
key: fs.readFileSync(config.ssl.key),
cert: fs.readFileSync(config.ssl.cert)
}, app).listen(config.server.port, config.server.host);
} else {
// standard server
console.log(' - not using SSL!');
http.createServer(app).listen(config.server.port, config.server.host);
}
// a flag indicating that there are active hooks
const hasHooksBefore = config.hooks !== undefined && config.hooks.before !== undefined;
const hasHooksAfter = config.hooks !== undefined && config.hooks.after !== undefined;
// listen to post requests
app.post(config.server.path, function (request, response, next)
{
let rpc;
// parse the json body and
try {
rpc = JSON.parse(request.rpc);
} catch(e) {
return response.status(500).send({
code: -32700,
message: 'Parse error'
});
}
// check if the method is given and configured
if(rpc.method === undefined || !(rpc.method in config.methods)) {
return response.status(404).send({
code: -32601,
message: 'Method not found',
});
}
// check if function is enabled
if(config.methods[rpc.method] === false) {
return response.status(403).send({
code: -32601,
message: "Not allowed",
});
}
if(hasHooksBefore) {
try {
rpc.params = hookParams('*', rpc.params || {});
rpc.params = hookParams(rpc.method, rpc.params || {});
}
catch(error) {
return response.status(403).send({
code: -32599,
message: error.message,
});
}
}
// get random node
const node = config.nodes[Math.floor(Math.random() * config.nodes.length)];
// deletgate request and send response to client
axios.post(node, request.rpc).then((res) => {
let responseData = res.data;
let requestData = JSON.parse(res.config.data);
responseData = hookResponseData('*', responseData);
responseData = hookResponseData(requestData.method, responseData);
response.status(res.status).send(responseData);
}).catch(e => {
// no hook on errors
response.status(res.status).send(
hookResponseData(request.rpc.method, res.data)
);
});
});
/**
* Small function that takes the respoinse of the node and calls a callback
* with the data which either alters it or
*
* @param method
* @param data
* @returns {*}
*/
function hookResponseData(method, data)
{
if(!hasHooksAfter || config.hooks.after[method] === undefined) {
return data;
}
return (method === '*') ?
config.hooks.after[method](method, data) :
config.hooks.after[method](data);
}
/**
* Small function that takes the params of the request and calls hooks with them
*
* @param method
* @param params
* @returns {*}
*/
function hookParams(method, params)
{
if(!hasHooksBefore || config.hooks.before[method] === undefined) {
return params;
}
return (method === '*') ?
config.hooks.before[method](method, params) :
config.hooks.before[method](params);
}
app.use(function(req, res, next) {
return res.status(404).send({
code: -32601,
message: "Not found"
});
});