-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
127 lines (114 loc) · 4.57 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
const express = require("express");
const app = express();
app.use(express.json({ extended: false }));
const path = require("path");
const port = process.env.PORT || 5000;
const engine = require("consolidate");
const request = require('request').defaults({ encoding: null });
const compression = require('compression');
app.use(compression());
const month = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
const formatDate = ((d) => `${(d.getDate() < 10) ? ("0"+d.getDate()) : d.getDate()} ${month[d.getMonth()]} ${d.getFullYear()}, ${(d.getHours() < 10) ? ("0"+d.getHours()) : d.getHours()}:${(d.getMinutes() < 10) ? ("0"+d.getMinutes()) : d.getMinutes()}`);
// set up router
const router = express.Router();
router.use(express.json()); // for parsing application/json
router.use(express.urlencoded({ extended: false })) // for disabling parsing application/x-www-form-urlencoded
router.use((req, res, next) => {
// console.log('Time:', formatDate(new Date(Date.now())));
// console.log('Request Type:', req.method);
res.header('Access-Control-Allow-Origin', process.env.ORIGIN || "*");
next();
});
// REGISTER ALL ROUTES -------------------------------
app.use("/api", router); // all of the routes will be prefixed with /api
// Base64 to Uint8Array
const convertB64ToBitArr = (b64Str) => ( Uint8Array.from(atob( (b64Str.includes(';base64,') ? (b64Str.split(','))[1] : b64Str) ), (v) => v.charCodeAt(0)) );
const emptyImageUrl='data:image/png;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
const emptyBinaryArray=convertB64ToBitArr(emptyImageUrl);
console.log(emptyBinaryArray);
const https = require('https');
const MapCache = require('map-cache');
const mapCache = new MapCache();
router.get('/map_tile/:urlPrefix/:z/:x/:y.:ext', async (req, res) => {
let prevHeader="";
let rawHeaders=req["rawHeaders"];
// console.log(rawHeaders);
let headersObj={};
for(let i=0;i<rawHeaders.length;i++) {
let rawHeader=rawHeaders[i].toLowerCase();
if(i==0 || i%2==0) {
headersObj[rawHeader]="";
prevHeader=rawHeader;
} else if(i%2!=0) {
headersObj[prevHeader]=rawHeader;
}
}
// console.log(['headersObj',headersObj]);
const dest = headersObj["sec-fetch-dest"];
const accept = headersObj["accept"];
const isImage = dest ? dest === "image" : !/text\/html/.test(accept);
let urlPrefix=req.params.urlPrefix;
urlPrefix=atob(urlPrefix); // decoded
urlPrefix=urlPrefix.replace('{s}','c');
let ext=req.params.ext;
urlPrefix=urlPrefix.replace(`/{z}/{x}/{y}.${ext}`,'');
let z=(req.params.z);
let x=(req.params.x);
let y=(req.params.y);
z=parseInt(z);
x=parseInt(x);
y=parseInt(y);
let srcUrl=`${urlPrefix}/${z}/${x}/${y}.${ext}`;
srcUrl= (!srcUrl.startsWith('https') && srcUrl.startsWith('http')) ? srcUrl.replace('http','https') : srcUrl;
// if(isImage) {
// if is image, end reponse here
const _req = https.request(srcUrl, (_res) => {
let allChunks = [];
_res.on('data', (chunk) => {
allChunks=allChunks.concat(chunk);
});
_res.on('end', async() => {
let chunkData=allChunks[0];
mapCache.set(srcUrl, chunkData);
await new Promise((resolve, reject) => setTimeout(resolve, 1));
res.status(200).send(chunkData);
// res.end();
});
});
_req.on('error', async(_err) => {
console.error('error', _err);
if(mapCache.has(srcUrl)) {
let binaryArray=mapCache.get(srcUrl);
await new Promise((resolve, reject) => setTimeout(resolve, 1));
res.status(200).send(binaryArray);
}
// res.status(200).send(emptyBinaryArray);
// res.end();
});
_req.end();
// }
// else {
// let docData=`<html style="height: 100%">
// <head>
// <meta name="viewport" content="width=device-width, minimum-scale=0.1">
// <title>${srcUrl} (256×256)</title>
// </head>
// <body style="display: flex;margin: 0px;height: 100%;background-color: rgb(14, 14, 14);">
// <img
// style="display: block;-webkit-user-select: none;margin: calc(50vh - 178px) auto;background-color: hsl(0, 0%, 90%);transition: background-color 300ms;"
// src="${srcUrl}">
// </body>
// </html>`;
// res.set("Content-Type", "text/html");
// res.status(200).send(docData);
// res.end();
// }
});
app.use(express.static(path.join(__dirname, "public")))
.set("views", path.join(__dirname, "views"))
.engine("html", engine.mustache)
.set("view engine", "html")
.get("/", (req, res) => res.render("index.html"))
.listen(port, () => {
console.log(`Tableau Data Utility app is listening on port ${port}!`)
});