tileblaster 1.0.7 → 1.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/builtins/check.js +19 -17
- package/builtins/versatiles.js +14 -13
- package/package.json +3 -3
- package/tileblaster.js +17 -0
package/builtins/check.js
CHANGED
|
@@ -3,22 +3,13 @@
|
|
|
3
3
|
const cache = {};
|
|
4
4
|
|
|
5
5
|
module.exports = function({ req, res, opts, data }, next, skip){
|
|
6
|
+
const debug = this.lib.debug;
|
|
6
7
|
|
|
7
8
|
// fill cache for map
|
|
8
9
|
if (!cache.hasOwnProperty(data.map)) {
|
|
9
10
|
|
|
10
11
|
cache[data.map] = {};
|
|
11
12
|
|
|
12
|
-
// skip function
|
|
13
|
-
cache[data.map].abort = function(err){
|
|
14
|
-
if (res.used) return;
|
|
15
|
-
res.statusCode = cache[data.map].status;
|
|
16
|
-
if (cache[data.map].hints && err) res.setHeader("x-tileblaster-hint", err.message || err.toString());
|
|
17
|
-
res.end();
|
|
18
|
-
res.used = true; // mark connection as used
|
|
19
|
-
return skip(); // skip rest of jobs
|
|
20
|
-
};
|
|
21
|
-
|
|
22
13
|
cache[data.map].status = (opts.status && Number.isInteger(opts.status)) ? opts.status : 204;
|
|
23
14
|
|
|
24
15
|
cache[data.map].hints = !!opts.hints;
|
|
@@ -99,29 +90,40 @@ module.exports = function({ req, res, opts, data }, next, skip){
|
|
|
99
90
|
};
|
|
100
91
|
opts = cache[data.map];
|
|
101
92
|
|
|
93
|
+
// skip function
|
|
94
|
+
const abort = function abort (err){
|
|
95
|
+
debug.info("Check: Abort %s/%s/%s/%s: %s", data.map, data.req.params.z, data.req.params.x, data.req.params.y, err.message || err.toString());
|
|
96
|
+
if (res.used) return;
|
|
97
|
+
res.statusCode = cache[data.map].status;
|
|
98
|
+
if (cache[data.map].hints && err) res.setHeader("x-tileblaster-hint", err.message || err.toString());
|
|
99
|
+
res.end();
|
|
100
|
+
res.used = true; // mark connection as used
|
|
101
|
+
return skip(); // skip rest of jobs
|
|
102
|
+
};
|
|
103
|
+
|
|
102
104
|
// check for NaNs
|
|
103
|
-
if (isNaN(data.req.params.z) || isNaN(data.req.params.x) || isNaN(data.req.params.y)) return
|
|
105
|
+
if (isNaN(data.req.params.z) || isNaN(data.req.params.x) || isNaN(data.req.params.y)) return abort(new Error("illegal zxy."));
|
|
104
106
|
|
|
105
107
|
// check zoom
|
|
106
|
-
if (data.req.params.z < opts.minZoom || data.req.params.z > opts.maxZoom) return
|
|
108
|
+
if (data.req.params.z < opts.minZoom || data.req.params.z > opts.maxZoom) return abort(new Error("illegal zoom."));
|
|
107
109
|
|
|
108
110
|
// check bounds
|
|
109
111
|
if (opts.bounds) {
|
|
110
112
|
if (opts.bounds[data.req.params.z][0] < opts.bounds[data.req.params.z][2]) { // check for bounds spanning antimeridian
|
|
111
113
|
// bounds don't span antimeridian
|
|
112
|
-
if (data.req.params.x < opts.bounds[data.req.params.z][0] || data.req.params.x > opts.bounds[data.req.params.z][2]) return
|
|
114
|
+
if (data.req.params.x < opts.bounds[data.req.params.z][0] || data.req.params.x > opts.bounds[data.req.params.z][2]) return abort(new Error("x is out of bounds."));
|
|
113
115
|
} else {
|
|
114
116
|
// bounds span antimeridian
|
|
115
|
-
if (data.req.params.x > opts.bounds[data.req.params.z][0] && data.req.params.x < opts.bounds[data.req.params.z][2]) return
|
|
117
|
+
if (data.req.params.x > opts.bounds[data.req.params.z][0] && data.req.params.x < opts.bounds[data.req.params.z][2]) return abort(new Error("x is out of bounds, bounds span antimeridian"));
|
|
116
118
|
}
|
|
117
|
-
if (data.req.params.y < opts.bounds[data.req.params.z][1] || data.req.params.y > opts.bounds[data.req.params.z][3]) return
|
|
119
|
+
if (data.req.params.y < opts.bounds[data.req.params.z][1] || data.req.params.y > opts.bounds[data.req.params.z][3]) return abort(new Error("y is out of bounds."));
|
|
118
120
|
}
|
|
119
121
|
|
|
120
122
|
// check extension
|
|
121
|
-
if (opts.extensions.length > 0 && !opts.extensions.includes(data.req.params.e) && !opts.extensions.includes(data.req.params.f)) return
|
|
123
|
+
if (opts.extensions.length > 0 && !opts.extensions.includes(data.req.params.e) && !opts.extensions.includes(data.req.params.f)) return abort(new Error("illegal extension."));
|
|
122
124
|
|
|
123
125
|
// check density
|
|
124
|
-
if (opts.density && !opts.density.includes(data.req.params.d) && !opts.density.includes(data.req.params.f)) return
|
|
126
|
+
if (opts.density && !opts.density.includes(data.req.params.d) && !opts.density.includes(data.req.params.f)) return abort(new Error("illegal density marker."));
|
|
125
127
|
|
|
126
128
|
// all passed
|
|
127
129
|
next();
|
package/builtins/versatiles.js
CHANGED
|
@@ -17,22 +17,23 @@ module.exports = function({ req, res, opts, data }, next, skip){
|
|
|
17
17
|
headers: ((opts.hasOwnProperty("headers")) ? opts.headers : {}),
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
// skip function
|
|
21
|
-
cache[data.map].abort = function(err){
|
|
22
|
-
if (res.used) return;
|
|
23
|
-
res.statusCode = 204; // no content
|
|
24
|
-
res.setHeader("x-tileblaster-hint", err.message || err.toString());
|
|
25
|
-
res.end();
|
|
26
|
-
res.used = true; // mark connection as used
|
|
27
|
-
return skip(); // skip rest of jobs
|
|
28
|
-
};
|
|
29
|
-
|
|
30
20
|
};
|
|
31
21
|
const vt = cache[data.map];
|
|
32
22
|
|
|
33
|
-
|
|
23
|
+
// abort function
|
|
24
|
+
const abort = function abort(err){
|
|
25
|
+
debug.info("Versatiles: Abort %s/%s/%s/%s: %s", data.map, data.req.params.z, data.req.params.x, data.req.params.y, err.message || err.toString());
|
|
26
|
+
if (res.used) return;
|
|
27
|
+
res.statusCode = 204; // no content
|
|
28
|
+
res.end();
|
|
29
|
+
res.used = true; // mark connection as used
|
|
30
|
+
return skip(); // skip rest of jobs
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
debug.info("Versatiles: Fetching %s/%s/%s/%s", data.map, data.req.params.z, data.req.params.x, data.req.params.y);
|
|
34
34
|
vt.getTile(data.req.params.z, data.req.params.x, data.req.params.y, function(err, buf){
|
|
35
|
-
if (err) return
|
|
35
|
+
if (err) return abort(err); // fail gracefully
|
|
36
|
+
if (buf.length === 0) return abort(new Error("Tile does not exist")); // fail gracefully
|
|
36
37
|
|
|
37
38
|
// if precompressed, keep in tile stack
|
|
38
39
|
/* TODO evaluate side effects
|
|
@@ -51,7 +52,7 @@ module.exports = function({ req, res, opts, data }, next, skip){
|
|
|
51
52
|
|
|
52
53
|
// decompress tile
|
|
53
54
|
vt.decompress(vt.header.tile_precompression, buf, function(err, buf){
|
|
54
|
-
if (err) return
|
|
55
|
+
if (err) return abort(err); // fail gracefully
|
|
55
56
|
|
|
56
57
|
const tile = {
|
|
57
58
|
buffer: buf,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tileblaster",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "a quick and versatile map tile caching proxy",
|
|
5
5
|
"main": "tileblaster.js",
|
|
6
6
|
"bin": {
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"mbg": "^0.0.2",
|
|
36
36
|
"node-liblzma": "^1.1.9",
|
|
37
37
|
"optipng-js": "^0.1.2",
|
|
38
|
-
"pmtiles": "^2.
|
|
39
|
-
"sharp": "^0.
|
|
38
|
+
"pmtiles": "^2.11.0",
|
|
39
|
+
"sharp": "^0.33.2",
|
|
40
40
|
"versatiles": "^0.3.1",
|
|
41
41
|
"vtt": "^0.0.3"
|
|
42
42
|
},
|
package/tileblaster.js
CHANGED
|
@@ -113,9 +113,26 @@ const tileblaster = module.exports = function tileblaster(config){
|
|
|
113
113
|
|
|
114
114
|
self.queue.push(function(next){ // queue tasks
|
|
115
115
|
|
|
116
|
+
args.start = Date.now();
|
|
117
|
+
args.timeout = setTimeout(function(){
|
|
118
|
+
debug.warn("Task timed out: %s (%d total, %d running)", req.path, self.queue.stack.length, self.queue.running);
|
|
119
|
+
if (res.used) return debug.warn("Connection already used.", req.path);
|
|
120
|
+
res.used = true;
|
|
121
|
+
args.timeout = null;
|
|
122
|
+
res.statusCode = 500;
|
|
123
|
+
res.setHeader("content-type", "text/plain");
|
|
124
|
+
res.end("Error.");
|
|
125
|
+
next();
|
|
126
|
+
},30000);
|
|
127
|
+
|
|
116
128
|
// create tasks from map
|
|
117
129
|
tasks(self.maps[req.map]).run(args, function(err, { res }){
|
|
118
130
|
|
|
131
|
+
// check if timed out
|
|
132
|
+
if (args.timeout === null) return;
|
|
133
|
+
clearTimeout(args.timeout);
|
|
134
|
+
debug.info("Task complete: %s (%ds)", req.path, ((Date.now()-args.start)/1000));
|
|
135
|
+
|
|
119
136
|
next(); // free queue
|
|
120
137
|
|
|
121
138
|
// FIXME provide more context
|