-
Notifications
You must be signed in to change notification settings - Fork 7
/
index.js
129 lines (124 loc) · 4.33 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
require('dotenv').config()
const express = require('express')
const bitqueryd = require('fountainhead-core').bitqueryd
const PQueue = require('p-queue')
const ip = require('ip')
const app = express()
const rateLimit = require("express-rate-limit")
const cors = require("cors")
const config = {
"query": {
"v": 3,
"q": { "find": {}, "limit": 10 }
},
"name": process.env.db_name ? process.env.db_name : "bitdb",
"url": process.env.db_url ? process.env.db_url : "mongodb://localhost:27017",
"port": Number.parseInt(process.env.bitserve_port ? process.env.bitserve_port : 3000),
"timeout": Number.parseInt(process.env.bitserve_timeout ? process.env.bitserve_timeout : 30000),
"log": process.env.bitserve_log ? process.env.bitserve_log == 'true' : true
};
const concurrency = ((config.concurrency && config.concurrency.aggregate) ? config.concurrency.aggregate : 3)
const queue = new PQueue({concurrency: concurrency})
var db
app.set('view engine', 'ejs')
app.use(express.static('public'))
// create rate limiter for API endpoint,ß bypass whitelisted IPs
var whitelist = []
if (process.env.whitelist) {
whitelist = process.env.whitelist.split(',')
}
var ratelimit_disabled = false;
if (process.env.ratelimit_disabled) {
ratelimit_disabled = process.env.ratelimit_disabled
}
app.use(cors())
app.enable("trust proxy")
const limiter = rateLimit({
windowMs: 1 * 60 * 1000, // 1 minute window
max: Number.parseInt(process.env.ratelimit_requests ? process.env.ratelimit_requests : 300), // Requests per windowMs
handler: function(req, res, /*next*/) {
res.format({
json: function() {
res.status(500).json({
error: "Too many requests. Limits are 300 requests per minute."
})
}
})
},
skip: function (req, /*res*/) {
if (ratelimit_disabled == true || whitelist.includes(req.ip)) {
return true
} else {
return false
}
}
})
app.get(/^\/q\/(.+)/, cors(), limiter, async function(req, res) {
var encoded = req.params[0];
let r = JSON.parse(new Buffer(encoded, "base64").toString());
if (r.q && r.q.aggregate) {
// add to aggregate queue
console.log("# Aggregate query. Adding to queue", queue.size)
queue.add(async function() {
// regular read
let result = await db.read(r)
if (config.log) {
console.log("query = ", r)
console.log("response = ", result)
}
console.log("Done", queue.size-1)
res.json(result)
})
} else {
// regular read
let result = await db.read(r)
if (config.log) {
console.log("query = ", r)
console.log("response = ", result)
}
res.json(result)
}
})
app.get(/^\/explorer\/(.+)/, function(req, res) {
let encoded = req.params[0]
let decoded = Buffer.from(encoded, 'base64').toString()
res.render('explorer', { code: decoded, sockserve: process.env.same_domain_sockserve })
});
app.get('/explorer', function (req, res) {
res.render('explorer', { code: JSON.stringify(config.query, null, 2), sockserve: process.env.same_domain_sockserve })
});
app.get('/', function(req, res) {
res.redirect('/explorer')
});
app.get(/^\/explorer2\/(.+)/, function(req, res) {
let encoded = req.params[0]
let decoded = Buffer.from(encoded, 'base64').toString()
res.render('explorer2', { code: decoded, sockserve: process.env.same_domain_sockserve })
});
app.get('/explorer2', function (req, res) {
res.render('explorer2', { code: JSON.stringify(config.query, null, 2), sockserve: process.env.same_domain_sockserve })
});
app.get('/', function(req, res) {
res.redirect('/explorer')
});
var run = async function() {
db = await bitqueryd.init({
url: (config.url ? config.url : process.env.url),
timeout: config.timeout,
name: config.name
})
app.listen(config.port, () => {
console.log("######################################################################################");
console.log("#")
console.log("# BITSERVE: BitDB Microservice")
console.log("# Serving Bitcoin through HTTP...")
console.log("#")
console.log(`# Explorer: ${ip.address()}:${config.port}/explorer`);
console.log(`# API Endpoint: ${ip.address()}:${config.port}/q`);
console.log("#")
console.log("# Learn more at https://docs.fountainhead.cash")
console.log("#")
console.log("######################################################################################");
})
}
run()