diff --git a/NEWS.md b/NEWS.md index 9c7e9d99..69257515 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,16 @@ -1.20.3 -- 2014-mm-dd +1.21.1 -- 2014-mm-dd -------------------- +Announcements: + - Upgrades windshaft to 0.32.0 + + +1.21.0 -- 2014-10-24 +-------------------- + +New features: + - Allow a different cache-control max-age for layergroup responses + 1.20.2 -- 2014-10-20 -------------------- diff --git a/config/environments/development.js.example b/config/environments/development.js.example index 376f2a5a..630b7091 100644 --- a/config/environments/development.js.example +++ b/config/environments/development.js.example @@ -144,7 +144,8 @@ var config = { host: 'localhost', port: 6082, secret: 'xxx', - ttl: 86400 + ttl: 86400, + layergroupTtl: 86400 // the max-age for cache-control header in layergroup responses } // If useProfiler is true every response will be served with an // X-Tiler-Profile header containing elapsed timing for various diff --git a/config/environments/production.js.example b/config/environments/production.js.example index 08b96202..8d20f27a 100644 --- a/config/environments/production.js.example +++ b/config/environments/production.js.example @@ -138,7 +138,8 @@ var config = { host: 'localhost', port: 6082, secret: 'xxx', - ttl: 86400 + ttl: 86400, + layergroupTtl: 86400 // the max-age for cache-control header in layergroup responses } // If useProfiler is true every response will be served with an // X-Tiler-Profile header containing elapsed timing for various diff --git a/config/environments/staging.js.example b/config/environments/staging.js.example index c8bcb5b4..8b1ba7a8 100644 --- a/config/environments/staging.js.example +++ b/config/environments/staging.js.example @@ -138,7 +138,8 @@ var config = { host: 'localhost', port: 6082, secret: 'xxx', - ttl: 86400 + ttl: 86400, + layergroupTtl: 86400 // the max-age for cache-control header in layergroup responses } // If useProfiler is true every response will be served with an // X-Tiler-Profile header containing elapsed timing for various diff --git a/config/environments/test.js.example b/config/environments/test.js.example index 9d6fb502..e2882331 100644 --- a/config/environments/test.js.example +++ b/config/environments/test.js.example @@ -140,7 +140,8 @@ var config = { host: '', port: null, secret: 'xxx', - ttl: 86400 + ttl: 86400, + layergroupTtl: 86400 // the max-age for cache-control header in layergroup responses } // If useProfiler is true every response will be served with an // X-Tiler-Profile header containing elapsed timing for various diff --git a/docs/Map-API.md b/docs/Map-API.md index baa1f891..36c9f00c 100644 --- a/docs/Map-API.md +++ b/docs/Map-API.md @@ -97,7 +97,7 @@ Here is an example response: You can use the `layergroupid` to instantiate a URL template for accessing tiles on the client. Here we use the `layergroupid` from the example response above in this URL template: {% highlight bash %} -http://documentation.cartodb.com/tiles/layergroup/c01a54877c62831bb51720263f91fb33:0/{z}/{x}/{y}.png +http://documentation.cartodb.com/api/v1/map/c01a54877c62831bb51720263f91fb33:0/{z}/{x}/{y}.png {% endhighlight %} ## General Concepts @@ -370,7 +370,7 @@ When using templates, be very careful about your selections as they can give bro curl -X POST \ -H 'Content-Type: application/json' \ -d @template.json \ - 'https://docs.cartodb.com/api/v1/map/named?api_key=APIKEY' + 'https://documentation.cartodb.com/api/v1/map/named?api_key=APIKEY' {% endhighlight %}
RESPONSE
@@ -416,7 +416,7 @@ Valid credentials will be needed if required by the template. curl -X POST \ -H 'Content-Type: application/json' \ -d @params.json \ - 'https://docs.cartodb.com/api/v1/template/@template_name?auth_token=AUTH_TOKEN' + 'https://documentation.cartodb.com/api/v1/map/named/@template_name?auth_token=AUTH_TOKEN' {% endhighlight %}
Response
@@ -456,19 +456,19 @@ GET /api/v1/map/named/:template_name/jsonp
REQUEST
{% highlight bash %} -curl 'https://docs.cartodb.com/api/v1/map/named/:template_name/jsonp?auth_token=AUTH_TOKEN&callback=function_name&config=template_params_json' +curl 'https://documentation.cartodb.com/api/v1/map/named/:template_name/jsonp?auth_token=AUTH_TOKEN&callback=callback&config=template_params_json' {% endhighlight %}
RESPONSE
{% highlight javascript %} -callback( +callback({ "layergroupid":"c01a54877c62831bb51720263f91fb33:0", "last_updated":"1970-01-01T00:00:00.000Z" "cdn_url": { "http": "http://cdb.com", "https": "https://cdb.com" } -) +}) {% endhighlight %} This takes the `callback` function (required), `auth_token` if the template needs auth, and `config` which is the variable for the template (in cases where it has variables). @@ -481,7 +481,7 @@ JSON.stringify({ color: 'red' }); The response is in this format: {% highlight javascript %} -jQuery17205720721024554223_1390996319118({ +callback({ layergroupid: "dev@744bd0ed9b047f953fae673d56a47b4d:1390844463021.1401", last_updated: "2014-01-27T17:41:03.021Z" }) @@ -493,7 +493,7 @@ jQuery17205720721024554223_1390996319118({
{% highlight bash %} -PUT /api/v1/map/:map_name +PUT /api/v1/map/named/:template_name {% endhighlight %} #### Params @@ -515,7 +515,7 @@ Updating a named map removes all the named map instances so they need to be init curl -X PUT \ -H 'Content-Type: application/json' \ -d @template.json \ - 'https://docs.cartodb.com/tiles/template/:template_name?api_key=APIKEY' + 'https://documentation.cartodb.com/api/v1/map/named/:template_name?api_key=APIKEY' {% endhighlight %}
RESPONSE
@@ -545,14 +545,14 @@ Delete the specified template map from the server and disables any previously in
{% highlight bash %} -DELETE /template/:template_name +DELETE /api/v1/map/named/:template_name {% endhighlight %} #### Example
REQUEST
{% highlight bash %} -curl -X DELETE 'https://docs.cartodb.com/tiles/template/@template_name?auth_token=AUTH_TOKEN' +curl -X DELETE 'https://documentation.cartodb.com/api/v1/map/named/:template_name?auth_token=AUTH_TOKEN' {% endhighlight %}
RESPONSE
@@ -583,7 +583,7 @@ GET /api/v1/map/named/
REQUEST
{% highlight bash %} -curl -X GET 'https://docs.cartodb.com/tiles/template?api_key=APIKEY' +curl -X GET 'https://documentation.cartodb.com/api/v1/map/named?api_key=APIKEY' {% endhighlight %}
RESPONSE
@@ -619,7 +619,7 @@ GET /api/v1/map/named/:template_name
REQUEST
{% highlight bash %} -curl -X GET 'https://docs.cartodb.com/tiles/template/@template_name?auth_token=AUTH_TOKEN' +curl -X GET 'https://documentation.cartodb.com/api/v1/map/named/:template_name?auth_token=AUTH_TOKEN' {% endhighlight %}
RESPONSE
diff --git a/lib/cartodb/server_options.js b/lib/cartodb/server_options.js index 4ac405dd..adea9a3c 100644 --- a/lib/cartodb/server_options.js +++ b/lib/cartodb/server_options.js @@ -342,7 +342,7 @@ module.exports = function(redisPool) { if ( req.query && req.query.cache_policy == 'persist' ) { res.header('Cache-Control', 'public,max-age=31536000'); // 1 year } else { - var ttl = global.environment.varnish.ttl || 86400; + var ttl = global.environment.varnish.layergroupTtl || 86400; res.header('Cache-Control', 'public,max-age='+ttl+',must-revalidate'); } res.header('Last-Modified', (new Date()).toUTCString()); diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 01e75b8d..0303b8fb 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,6 +1,6 @@ { "name": "windshaft-cartodb", - "version": "1.20.3", + "version": "1.21.1", "dependencies": { "cartodb-psql": { "version": "0.4.0", @@ -52,7 +52,8 @@ }, "nan": { "version": "1.1.2", - "from": "nan@~1.1.0" + "from": "nan@~1.1.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.1.2.tgz" } } } @@ -75,8 +76,9 @@ "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz" }, "readable-stream": { - "version": "1.0.33-1", + "version": "1.0.33", "from": "readable-stream@~1.0.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", "dependencies": { "core-util-is": { "version": "1.0.1", @@ -130,7 +132,8 @@ }, "nan": { "version": "1.1.2", - "from": "nan@~1.1.0" + "from": "nan@~1.1.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.1.2.tgz" } } } @@ -147,7 +150,8 @@ "dependencies": { "node-uuid": { "version": "1.4.1", - "from": "node-uuid@1.4.x" + "from": "node-uuid@1.4.x", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz" }, "lru-cache": { "version": "2.2.4", @@ -169,9 +173,9 @@ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz" }, "windshaft": { - "version": "0.31.1", - "from": "https://github.com/CartoDB/Windshaft/tarball/pgraster", - "resolved": "https://github.com/CartoDB/Windshaft/tarball/pgraster", + "version": "0.32.0", + "from": "https://github.com/CartoDB/Windshaft/tarball/0.32.0", + "resolved": "https://github.com/CartoDB/Windshaft/tarball/0.32.0", "dependencies": { "chronograph": { "version": "0.1.0", @@ -249,15 +253,17 @@ }, "node-uuid": { "version": "1.4.1", - "from": "node-uuid@~1.4.0" + "from": "node-uuid@~1.4.0", + "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.1.tgz" }, "tough-cookie": { "version": "0.12.1", "from": "tough-cookie@>=0.12.0", "dependencies": { "punycode": { - "version": "1.3.1", - "from": "punycode@>=0.2.0" + "version": "1.3.2", + "from": "punycode@>=0.2.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz" } } }, @@ -266,8 +272,9 @@ "from": "form-data@~0.1.0", "dependencies": { "combined-stream": { - "version": "0.0.5", + "version": "0.0.7", "from": "combined-stream@~0.0.4", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz", "dependencies": { "delayed-stream": { "version": "0.0.5", @@ -1064,7 +1071,8 @@ "dependencies": { "nan": { "version": "1.1.2", - "from": "nan@1.1.2" + "from": "nan@1.1.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.1.2.tgz" }, "node-pre-gyp": { "version": "0.5.22", @@ -1442,7 +1450,8 @@ }, "mime": { "version": "1.2.11", - "from": "mime@~1.2.9" + "from": "mime@~1.2.9", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" }, "mkdirp": { "version": "0.3.5", @@ -1534,7 +1543,8 @@ }, "mime": { "version": "1.2.11", - "from": "mime@~1.2.11" + "from": "mime@~1.2.11", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz" }, "sphericalmercator": { "version": "1.0.2", @@ -1553,7 +1563,8 @@ }, "mapnik-vector-tile": { "version": "0.5.5", - "from": "mapnik-vector-tile@0.5.5" + "from": "mapnik-vector-tile@0.5.5", + "resolved": "https://registry.npmjs.org/mapnik-vector-tile/-/mapnik-vector-tile-0.5.5.tgz" }, "node-pre-gyp": { "version": "0.5.25", @@ -1948,7 +1959,8 @@ }, "nan": { "version": "1.1.2", - "from": "nan@~1.1.0" + "from": "nan@~1.1.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-1.1.2.tgz" } } } diff --git a/package.json b/package.json index 1edafb94..ecd7190f 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "name": "windshaft-cartodb", - "version": "1.20.3", + "version": "1.21.1", "description": "A map tile server for CartoDB", "keywords": [ "cartodb" @@ -25,7 +25,7 @@ "node-varnish": "https://github.com/Vizzuality/node-varnish/tarball/0.3.0", "underscore" : "~1.6.0", "dot": "~1.0.2", - "windshaft": "https://github.com/CartoDB/Windshaft/tarball/pgraster", + "windshaft": "https://github.com/CartoDB/Windshaft/tarball/0.32.0", "step": "~0.0.5", "request": "~2.9.203", "cartodb-redis": "https://github.com/CartoDB/node-cartodb-redis/tarball/0.11.0", diff --git a/test/acceptance/multilayer.js b/test/acceptance/multilayer.js index ed1b1f4c..64066a39 100644 --- a/test/acceptance/multilayer.js +++ b/test/acceptance/multilayer.js @@ -1324,6 +1324,49 @@ suite('multilayer:postgres=' + cdbQueryTablesFromPostgresEnabledValue, function( ); }); + var layergroupTtlRequest = { + url: '/tiles/layergroup?config=' + encodeURIComponent(JSON.stringify({ + version: '1.0.0', + layers: [ + { options: { + sql: 'select * from test_table limit 2', + cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }', + cartocss_version: '2.0.1' + } } + ] + })), + method: 'GET', + headers: {host: 'localhost'} + }; + var layergroupTtlResponseExpectation = { + status: 200 + }; + + test("cache control for layergroup default value", function(done) { + global.environment.varnish.layergroupTtl = null; + + assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation, + function(res) { + assert.equal(res.headers['cache-control'], 'public,max-age=86400,must-revalidate'); + + done(); + } + ); + }); + + test("cache control for layergroup uses configuration for max-age", function(done) { + var layergroupTtl = 300; + global.environment.varnish.layergroupTtl = layergroupTtl; + + assert.response(server, layergroupTtlRequest, layergroupTtlResponseExpectation, + function(res) { + assert.equal(res.headers['cache-control'], 'public,max-age=' + layergroupTtl + ',must-revalidate'); + + done(); + } + ); + }); + suiteTeardown(function(done) {