tileblaster 1.0.6 → 1.0.7

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 CHANGED
@@ -11,6 +11,7 @@ module.exports = function({ req, res, opts, data }, next, skip){
11
11
 
12
12
  // skip function
13
13
  cache[data.map].abort = function(err){
14
+ if (res.used) return;
14
15
  res.statusCode = cache[data.map].status;
15
16
  if (cache[data.map].hints && err) res.setHeader("x-tileblaster-hint", err.message || err.toString());
16
17
  res.end();
@@ -39,7 +39,7 @@ module.exports = function({ req, res, opts, data }, next){
39
39
  if (opts.brotli) promises.push(new Promise(function(resolve, reject) {
40
40
  brotli(tile.buffer, opts.brotli).then(function(compressed){
41
41
  if (compressed.length > tile.buffer.length) {
42
- debug.warn("Discarding useless Brotli compression for %s: +%db", data.path.magenta, compressed.length-tile.buffer.length);
42
+ debug.warn("Discarding useless Brotli compression for %s: +%db", tile.path.magenta, compressed.length-tile.buffer.length);
43
43
  return resolve();
44
44
  };
45
45
  data.tiles.push({
@@ -52,7 +52,7 @@ module.exports = function({ req, res, opts, data }, next){
52
52
  });
53
53
  resolve();
54
54
  }).catch(function(err){
55
- debug.error("Brotli failed for %s: %s", data.path.magenta, err);
55
+ debug.error("Brotli failed for %s: %s", tile.path.magenta, err);
56
56
  reject(err);
57
57
  });
58
58
  }));
@@ -60,7 +60,7 @@ module.exports = function({ req, res, opts, data }, next){
60
60
  if (opts.gzip) promises.push(new Promise(function(resolve, reject) {
61
61
  gzip(tile.buffer, opts.gzip).then(function(compressed){
62
62
  if (compressed.length > tile.buffer.length) {
63
- debug.warn("Discarding useless Gzip compression for %s: +%db", data.path.magenta, compressed.length-tile.buffer.length);
63
+ debug.warn("Discarding useless Gzip compression for %s: +%db", tile.path.magenta, compressed.length-tile.buffer.length);
64
64
  return resolve();
65
65
  }
66
66
  data.tiles.push({
@@ -73,7 +73,7 @@ module.exports = function({ req, res, opts, data }, next){
73
73
  });
74
74
  resolve();
75
75
  }).catch(function(err){
76
- debug.error("Gzip failed for %s: %s", data.path.magenta, err);
76
+ debug.error("Gzip failed for %s: %s", tile.path.magenta, err);
77
77
  reject(err);
78
78
  });
79
79
  }));
package/builtins/cors.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // send cors headers.
2
2
 
3
- module.exports = function({ req, res, opts, data }, next){
3
+ module.exports = function({ req, res, opts, data }, next, skip){
4
4
 
5
5
  // only if origin header is set
6
6
  if (!req.headers.hasOwnProperty("origin") || !req.headers.origin) return next();
@@ -15,6 +15,7 @@ module.exports = function({ req, res, opts, data }, next){
15
15
  if (!opts.origins.includes("*") && opts.origins.includes(req.headers.origin)) return next();
16
16
 
17
17
  // send common headers
18
+ res.setHeader("Vary", "Origin"); // important for caching
18
19
  res.setHeader("Access-Control-Allow-Origin", req.headers.origin||"*");
19
20
  res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
20
21
  res.setHeader("Access-Control-Allow-Headers", "DNT,If-None-Match,If-Modified-Since,Cache-Control,Content-Type,Range,Accept-Encoding");
@@ -27,6 +28,8 @@ module.exports = function({ req, res, opts, data }, next){
27
28
  res.setHeader("Content-Length", 0);
28
29
  res.statusCode = 204;
29
30
  res.end();
31
+ res.used = true;
32
+ return skip();
30
33
  };
31
34
 
32
35
  next();
@@ -10,6 +10,7 @@ module.exports = function({ res, opts, data }, next){
10
10
  if (data.tile.buffer.length === 0) {
11
11
  res.statusCode = 204;
12
12
  res.end();
13
+ res.used = true;
13
14
  return next();
14
15
  }
15
16
 
package/builtins/dump.js CHANGED
@@ -12,7 +12,6 @@ module.exports = function({ res, data }, next, skip){
12
12
  res.statusCode = 200;
13
13
  res.setHeader("content-type", "text/plain");
14
14
  res.end(dump);
15
-
16
15
  res.used = true;
17
16
  skip();
18
17
 
package/builtins/edit.js CHANGED
@@ -19,7 +19,7 @@ module.exports = function({ req, res, opts, data }, next){
19
19
  return tile.type === "pbf";
20
20
  }).forEach(function(tile){
21
21
  try {
22
- tile.buffer = vtt.pack(opts.edit(vtt.unpack(tile.buffer)));
22
+ tile.buffer = Buffer.from(vtt.pack(opts.edit(vtt.unpack(tile.buffer))));
23
23
  } catch (err) {
24
24
  debug.error("Editing vector tile failed:", err);
25
25
  }
@@ -4,7 +4,7 @@ const versatiles = load("versatiles");
4
4
  const cache = {};
5
5
 
6
6
  // versatiles backend
7
- module.exports = function({ req, res, opts, data }, next){
7
+ module.exports = function({ req, res, opts, data }, next, skip){
8
8
  const mime = this.lib.mime;
9
9
  const debug = this.lib.debug;
10
10
 
@@ -16,12 +16,23 @@ module.exports = function({ req, res, opts, data }, next){
16
16
  tms: (!!opts.tms),
17
17
  headers: ((opts.hasOwnProperty("headers")) ? opts.headers : {}),
18
18
  });
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
+
19
30
  };
20
31
  const vt = cache[data.map];
21
32
 
22
33
  debug.info("Fetching %s/%s/%s", data.req.params.z, data.req.params.x, data.req.params.y);
23
34
  vt.getTile(data.req.params.z, data.req.params.x, data.req.params.y, function(err, buf){
24
- if (err) return next(err);
35
+ if (err) return cache[data.map].abort(err); // fail gracefully
25
36
 
26
37
  // if precompressed, keep in tile stack
27
38
  /* TODO evaluate side effects
@@ -40,7 +51,7 @@ module.exports = function({ req, res, opts, data }, next){
40
51
 
41
52
  // decompress tile
42
53
  vt.decompress(vt.header.tile_precompression, buf, function(err, buf){
43
- if (err) return next(err);
54
+ if (err) return cache[data.map].abort(err); // fail gracefully
44
55
 
45
56
  const tile = {
46
57
  buffer: buf,
package/lib/purge.js CHANGED
@@ -87,7 +87,7 @@ if (worker.isMainThread) {
87
87
  let deletable = [];
88
88
 
89
89
  klaw(cache.dir).on("data", function(file){
90
- if (file.stats.mtimeMs < cache.expires) deletable.push(file.path);
90
+ if (file.stats.mtimeMs > cache.expires) deletable.push(file.path);
91
91
  }).on("end", function(){
92
92
  Promise.allSettled(deletable.map(function(file){
93
93
  return new Promise(function(resolve,reject){
package/lib/router.js CHANGED
@@ -14,7 +14,7 @@ const router = module.exports = function router({ mountpoint }) {
14
14
 
15
15
  // default default route, very bare bones
16
16
  self.routes[""] = function(req, res){
17
- res.statusCode = 404, res.end();
17
+ res.statusCode = 404, res.end(), res.used = true;
18
18
  };
19
19
 
20
20
  return self;
package/lib/store.js CHANGED
@@ -80,7 +80,7 @@ store.prototype.put = function(tile, fn){
80
80
  const self = this;
81
81
 
82
82
  const destfile = path.join(self.root, tile.path);
83
- const tmpfile = destfile+self.ext;
83
+ const tmpfile = destfile+"."+Date.now()+self.ext;
84
84
 
85
85
  // check if exists and still valid?
86
86
  self.check(destfile, function(err, isValid){
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tileblaster",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "a quick and versatile map tile caching proxy",
5
5
  "main": "tileblaster.js",
6
6
  "bin": {