express-tile-cache
Advanced tools
Comparing version 1.3.2 to 1.3.5
@@ -5,3 +5,3 @@ 'use strict'; | ||
var express = require('express'); | ||
var url = require('url'); | ||
// var url = require('url'); | ||
var request = require('request'); | ||
@@ -17,3 +17,3 @@ var path = require('path'); | ||
function TileCache(options){ | ||
function TileCache(options) { | ||
if (!(this instanceof TileCache)) { | ||
@@ -26,8 +26,12 @@ return new TileCache(options); | ||
if(!options) { | ||
throw new Error("express-tile-cache needs a simple object setup"); | ||
throw new Error('express-tile-cache needs a simple object setup'); | ||
} | ||
if( !options.storage && !options.cachepath ) { | ||
throw new Error("You must configure a cachepath option or storage module in your tile source setup"); | ||
throw new Error('You must configure a cachepath option or storage module in your tile source setup'); | ||
} | ||
this.hashString = function (str) { | ||
return crypto.createHash('md5').update(str).digest('hex'); | ||
} | ||
this.TileStorage = options.storage || new CacheStorage(options.cachepath); | ||
@@ -37,2 +41,3 @@ this.TileSource = options.tilesource ? new TileSource(options.tilesource) : new TileSource(options); | ||
if(options.ttl) { | ||
@@ -46,8 +51,13 @@ this.Cache.setTtl(options.ttl); | ||
if(options.clearRoute && _this.Cache.clear && typeof(_this.Cache.clear) == "function") { | ||
//info route | ||
if(options.enableInfo) { | ||
router.use('/',require('./info')(this)); | ||
} | ||
if(options.clearRoute && _this.Cache.clear && typeof _this.Cache.clear === 'function') { | ||
//conditional route only if it is safe to call | ||
var clearRoute = typeof(options.clearRoute) == "string" ? options.clearRoute : "/clearcache"; | ||
if(0 !== clearRoute.indexOf("/")) { | ||
throw new Error("clearRoute should be a string beggining with a '/' or simply true (defaults to '/clearcache')"); | ||
var clearRoute = typeof options.clearRoute === 'string' ? options.clearRoute : '/clearcache'; | ||
if(clearRoute.indexOf('/') !== 0) { | ||
throw new Error('clearRoute should be a string beggining with a "/" or simply true (defaults to "/clearcache")'); | ||
} | ||
@@ -61,3 +71,3 @@ router.get(clearRoute, function(req, res, next){ | ||
} | ||
res.status(200).send({result:"Cache index cleared"}); | ||
res.status(200).send({result: 'Cache index cleared'}); | ||
}); | ||
@@ -70,4 +80,4 @@ }); | ||
[ | ||
"/tms/1.0.0/:layer/:z/:x/:y.:format", | ||
"/tms/:layer/:z/:x/:y.:format" | ||
'/tms/1.0.0/:layer/:z/:x/:y.:format', | ||
'/tms/:layer/:z/:x/:y.:format' | ||
], | ||
@@ -77,3 +87,3 @@ function(req, res, next) { | ||
var tilepath = _this.TileSource.getTilePath(req.params); | ||
var tileHash = _hash(tilepath); | ||
var tileHash = _this.hashString(tilepath); | ||
@@ -89,10 +99,11 @@ _this.Cache.get(tileHash, function(err, cached){ | ||
var url = _this.TileSource.getTileUrl() + "/" + tilepath; | ||
var url = _this.TileSource.getTileUrl() + '/' + tilepath; | ||
debug('Tile: %s', url); | ||
request(url) | ||
.on("error", /* istanbul ignore next */ function(er){ | ||
debug("Server error"); | ||
request | ||
.get(url) | ||
.on('error', /* istanbul ignore next */ function(er){ | ||
debug('Server error'); | ||
debug(er); | ||
res.status(500).send("TMS refused connection"); | ||
res.status(500).send('TMS refused connection'); | ||
}) | ||
@@ -103,12 +114,12 @@ .on('response', function(resp){ | ||
if(parseInt(resp.statusCode, 10) >= 300) { | ||
debug('Response status code beyond 300 (%s), skipping cache abilities',resp.statusCode); | ||
debug('Response status code beyond 300 (%s), skipping cache abilities', resp.statusCode); | ||
return; | ||
} | ||
_this.TileStorage.save(resp, tileHash, function(err, details){ | ||
debug('Saving file to storage'); | ||
_this.TileStorage.save(resp, tileHash, function(err2, details){ | ||
/* istanbul ignore if */ | ||
if(err) { | ||
if(err2) { | ||
debug('Error saving tile'); | ||
debug(err); | ||
return next(err); | ||
debug(err2); | ||
return next(err2); | ||
} | ||
@@ -137,5 +148,2 @@ _this.Cache.set(path.basename(tileHash), details); | ||
function _hash (str) { | ||
return crypto.createHash('md5').update(str).digest('hex'); | ||
}; | ||
@@ -12,5 +12,6 @@ 'use strict'; | ||
//max miliseconds to be a valid cache entry | ||
//max seconds to be a valid cache entry | ||
//default is 1.000.000 days | ||
this.ttl = 1000 * 60 * 60 * 24 * 1000000; | ||
//using seconds as it is the usual unit in TTL | ||
this.ttl = 60 * 60 * 24 * 1000000; | ||
} | ||
@@ -23,3 +24,3 @@ | ||
toReturn = JSON.parse(this.cache[hash]); | ||
if(new Date() - new Date(toReturn.created) > this.ttl) { | ||
if(new Date() - new Date(toReturn.created) > this.ttl * 1000) { | ||
toReturn = null; | ||
@@ -60,5 +61,5 @@ } | ||
MemoryCache.prototype.setTtl = function(minutes) { | ||
//convert to miliseconds, as needed to Date operations | ||
this.ttl = 1000 * 60 * minutes; | ||
MemoryCache.prototype.setTtl = function(seconds) { | ||
//convert to seconds | ||
this.ttl = seconds; | ||
} |
{ | ||
"name": "express-tile-cache", | ||
"version": "1.3.2", | ||
"version": "1.3.5", | ||
"description": "Express middleware tile cache for tms services", | ||
@@ -13,2 +13,3 @@ "main": "lib", | ||
"fs.extra": "^1.3.2", | ||
"moment": "^2.10.2", | ||
"request": "^2.54.0" | ||
@@ -15,0 +16,0 @@ }, |
@@ -9,6 +9,8 @@ # express-tile-cache | ||
The builtin default `Cache` and `TileStorage` are meant for debugging and test purposes, not for production. | ||
## Overview | ||
**express-tile-cache** returns a express.Router() with two TMS specification standard routes adjusted to work with [Geoserver TMS service](http://docs.geoserver.org/stable/en/user/webadmin/tilecache/defaults.html). | ||
**express-tile-cache** returns a express.Router() with two TMS specification standard routes adjusted to work with [Geoserver TMS service](http://docs.geoserver.org/stable/en/user/webadmin/tilecache/defaults.html). | ||
@@ -62,5 +64,6 @@ | ||
* `store` *{Store class instance}*: optional - if you want to provide a different class of memory cache you can pass it here. Read the **express-tile-cache.Cache** section on how to extend the store module. | ||
* `ttl` *{Number}*: optional since v1.3.0 - **minutes** to keep cache valid for *each* tile. When you set this value **MemoryCache.setTtl** is called internally upon instantiation, but won't be able to change on the fly. | ||
* `clearRoute` *{String}*: optional - if true it will enable a default */clearcache* route to clear the cache index. Use a string starting with a `/` to enable and set custom clear route. | ||
* `tilesource` *{Object}*: optional - if the source of the tiles you need to retrieve is not TMS 1.0.0 compliant, you can provide a custom object to retrieve the tiles properly. Setting this option will override/invalidate `urlTemplate`, `subdomains`, `forceEpsg` and `forceNamespace` providing its own. | ||
* `ttl` *{Number}*: optional, since v1.3.0 - **seconds** to keep cache valid for *each* tile. When you set this value **MemoryCache.setTtl** is called internally upon instantiation, but you won't be able to change it on the fly. | ||
* `enableInfo` *{Boolean}*: sets up the same default `GET` routes with the */info* suffix to check on the tile cache data. Result is JSON. Ex: `/tms/1.0.0/layer/4/5/6.png/info` | ||
* `clearRoute` *{String}*: optional - if true it will enable a default */clearcache* route to clear the cache index. Use a string starting with a `/` to enable and set custom clear route. **Heads up!**: the route is configured without any security and responds to a simple *GET* request. Also, the *store* being used has to implement a `clear()` method. | ||
* `tilesource` *{Object}*: optional - if the source of the tiles you need to retrieve is not TMS 1.0.0 compliant, you can provide a custom object to retrieve the tiles properly. Setting this option will override/invalidate `urlTemplate`, `subdomains`, `forceEpsg` and `forceNamespace` with its own. | ||
* `urlTemplate` *{String|Array}*: same as above, but in this case you can provide an array of urls. This option would override `subdomains`. | ||
@@ -90,2 +93,4 @@ * `subdomains` *{String|Array}*: same as above. | ||
##### save(stream, filename, callback); | ||
`save` will receive three arguments and will manage its output via callback: | ||
@@ -103,2 +108,4 @@ | ||
##### get(filepath|url) | ||
`get` receives only one argument and returns a [readable stream](https://nodejs.org/api/stream.html#stream_class_stream_readable) which is piped to the response | ||
@@ -142,7 +149,7 @@ | ||
`delete` simply looks for the hash and deletes the member. You should implement this functionality as it will be used for route `../clear` | ||
`delete` simply looks for the hash and deletes the member. You should implement this functionality as it will be used for route `*/clear` | ||
##### setTtl(minutes) | ||
##### setTtl(seconds) | ||
As of 1.3.0 the cache can handle expiration for every member, this is as simple as taking the creation date of the member an compare it with some stored miliseconds variable (ttl). | ||
As of 1.3.0 the cache can handle expiration for every indexed tile, this is as simple as taking the creation date of the member an compare it with some stored seconds variable (ttl). | ||
@@ -153,9 +160,14 @@ `setTtl` can be called anytime, but it is not exposed as part of the *express-tile-cache* API, so, provided value is used upon instantiation via `ttl` option. | ||
```javascript | ||
var memoryCache = require("path-to-express-tile-cachelib/memorycache")(); | ||
var express = require('express'); | ||
//instance the builtin memorycache | ||
var memoryCache = require("path-to-express-tile-cache/lib/memorycache")(); | ||
var tileCache = require("express-tile-cache"); | ||
var ignArTiles = tileCache({ | ||
urlTemplate: "http://wms.ign.gob.ar/geoserver/gwc/service/tms/1.0.0", | ||
cachepath: "cache", | ||
ttl: 60, //remember these are minutes | ||
store: memoryCache() | ||
ttl: 60 | ||
store: memoryCache //use the instance of the default memorycache | ||
}); | ||
@@ -167,3 +179,6 @@ | ||
memoryCache.setTtl(1 / 60); //remember, minutes, so this sets expiring to 1 second | ||
//change the ttl | ||
memoryCache.setTtl(10); // sets expiring to 10 seconds | ||
app.listen(process.env.PORT || 3000); | ||
``` | ||
@@ -189,3 +204,3 @@ | ||
[OpenStreetMaps handles tiles](http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) in a non standard way. It accomodates to the grid in the same way that [Google Maps do](https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/): the Y tile grid is inverted. So, a TileSource for OSM would look like: | ||
[OpenStreetMaps handles tiles](http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames) in a non (TMS) standard way. It accomodates to the grid in the same way that [Google Maps do](https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/): the Y tile grid is inverted. So, a TileSource for OSM would look like: | ||
@@ -207,3 +222,3 @@ ```javascript | ||
``` | ||
With this configuration you can have your own OSM tile cache. Whether you should or not, is up to you. | ||
With this configuration you can have your own OSM tile cache. | ||
@@ -226,2 +241,15 @@ Check the provided links to see what I'm talking about. | ||
## 1.3.5 | ||
* Added `enableInfo` option to be able to check individual tile cache status | ||
* Enhanced docs and added an example | ||
* Changed `ttl` and MemoryCache.`setTtl` to use seconds as it is the standard | ||
## 1.3.4 | ||
* Added `ttl` support on *MemoryCache* | ||
* Performed some linting | ||
* Removed unused dependencies | ||
* More testing, implemented Istanbul | ||
## 1.3.2 | ||
@@ -228,0 +256,0 @@ |
@@ -48,3 +48,4 @@ var assert = require("assert"); | ||
it("should handle TileSource override properly", function(done){ | ||
//sometimes osm takes too long | ||
this.timeout(5000); | ||
var app = express(); | ||
@@ -126,7 +127,7 @@ var osm = { | ||
cachepath: "cache", | ||
ttl: 1, | ||
ttl: 2, | ||
store: require("../lib/memorycache")() | ||
} | ||
var b = TileCache(sampleTileSource); | ||
done(assert.equal(sampleTileSource.store.ttl, 1 * 60 * 1000)); | ||
done(assert.equal(sampleTileSource.store.ttl, 2 * 60)); | ||
}); | ||
@@ -157,3 +158,4 @@ | ||
describe("TMS service", function(){ | ||
describe("Routes", function(){ | ||
after(function(done){ | ||
@@ -166,8 +168,35 @@ if(fs.existsSync(sampleCacheDir)){ | ||
context("Standard TMS request", function(){ | ||
context("Tile info", function(){ | ||
var app = express(); | ||
var sampleTileSource = { | ||
urlTemplate: tmsServiceUrl, | ||
cachepath: sampleCacheDir, | ||
enableInfo: true | ||
} | ||
var b = TileCache(sampleTileSource); | ||
app.use(b); | ||
it('should be able to implement */info route to get cached tile data', function(done){ | ||
request(app) | ||
.get("/tms/capabaseargenmap/4/5/6.png") | ||
.end(function(err){ | ||
if(err) { | ||
return done(err); | ||
} | ||
request(app) | ||
.get('/tms/capabaseargenmap/4/5/6.png/info') | ||
.expect('Content-Type', /json/) | ||
.end(done); | ||
}); | ||
}); | ||
}); | ||
context("TMS requests", function(){ | ||
var app = express(); | ||
var sampleTileSource = { | ||
urlTemplate: tmsServiceUrl, | ||
cachepath: "cache" | ||
cachepath: sampleCacheDir | ||
} | ||
@@ -174,0 +203,0 @@ var b = TileCache(sampleTileSource); |
Sorry, the diff of this file is not supported yet
46956
17
949
290
5
8
+ Addedmoment@^2.10.2
+ Addedmoment@2.30.1(transitive)