From a438252e1e790ccb63a0c9f315030da18bc14004 Mon Sep 17 00:00:00 2001 From: Johan Gyllenspetz Date: Thu, 28 Jul 2016 17:20:52 -0700 Subject: [PATCH] Allow user to set headers for XHR vector tile get In some cases I would like to set a header to authenticate a user for getting a vector tile. It needs to be set per source. * Added the following format to the source style headers: [["HEADER-NAME", "HEADER-VALUE"]] * Added headers to ajax getArrayBuffer call --- bench/benchmarks/buffer.js | 2 +- js/source/vector_tile_source.js | 5 +++-- js/source/vector_tile_worker_source.js | 2 +- js/symbol/glyph_source.js | 2 +- js/util/ajax.js | 2 +- js/util/browser/ajax.js | 11 +++++++++-- 6 files changed, 16 insertions(+), 8 deletions(-) diff --git a/bench/benchmarks/buffer.js b/bench/benchmarks/buffer.js index 61d0b13ce9c..b7f36a38dce 100644 --- a/bench/benchmarks/buffer.js +++ b/bench/benchmarks/buffer.js @@ -105,7 +105,7 @@ function preloadAssets(stylesheet, callback) { } function getTile(url, callback) { - ajax.getArrayBuffer(url, function(err, response) { + ajax.getArrayBuffer(url, null, function(err, response) { assets.tiles[url] = response; callback(err, response); }); diff --git a/js/source/vector_tile_source.js b/js/source/vector_tile_source.js index 05bd1206f5e..dce1659e5cb 100644 --- a/js/source/vector_tile_source.js +++ b/js/source/vector_tile_source.js @@ -10,7 +10,7 @@ module.exports = VectorTileSource; function VectorTileSource(id, options, dispatcher) { this.id = id; this.dispatcher = dispatcher; - util.extend(this, util.pick(options, ['url', 'scheme', 'tileSize'])); + util.extend(this, util.pick(options, ['headers', 'url', 'scheme', 'tileSize'])); this._options = util.extend({ type: 'vector' }, options); if (this.tileSize !== 512) { @@ -55,7 +55,8 @@ VectorTileSource.prototype = util.inherit(Evented, { overscaling: overscaling, angle: this.map.transform.angle, pitch: this.map.transform.pitch, - showCollisionBoxes: this.map.showCollisionBoxes + showCollisionBoxes: this.map.showCollisionBoxes, + headers: this.headers }; if (tile.workerID) { diff --git a/js/source/vector_tile_worker_source.js b/js/source/vector_tile_worker_source.js index b3e23ca2492..c5669cdcb44 100644 --- a/js/source/vector_tile_worker_source.js +++ b/js/source/vector_tile_worker_source.js @@ -117,7 +117,7 @@ VectorTileWorkerSource.prototype = { * @param {string} params.url The URL of the tile PBF to load. */ loadVectorData: function (params, callback) { - var xhr = ajax.getArrayBuffer(params.url, done.bind(this)); + var xhr = ajax.getArrayBuffer(params.url, params.headers, done.bind(this)); return function abort () { xhr.abort(); }; function done(err, data) { if (err) { return callback(err); } diff --git a/js/symbol/glyph_source.js b/js/symbol/glyph_source.js index 6224c1cc532..4d18a2ba402 100644 --- a/js/symbol/glyph_source.js +++ b/js/symbol/glyph_source.js @@ -105,7 +105,7 @@ GlyphSource.prototype.loadRange = function(fontstack, range, callback) { var rangeName = (range * 256) + '-' + (range * 256 + 255); var url = glyphUrl(fontstack, rangeName, this.url); - getArrayBuffer(url, function(err, data) { + getArrayBuffer(url, null, function(err, data) { var glyphs = !err && new Glyphs(new Protobuf(new Uint8Array(data))); for (var i = 0; i < loading[range].length; i++) { loading[range][i](err, range, glyphs); diff --git a/js/util/ajax.js b/js/util/ajax.js index af0286f4778..a98e9517d3f 100644 --- a/js/util/ajax.js +++ b/js/util/ajax.js @@ -46,7 +46,7 @@ exports.getJSON = function(url, callback) { }); }; -exports.getArrayBuffer = function(url, callback) { +exports.getArrayBuffer = function(url, headers, callback) { if (cache[url]) return cached(cache[url], callback); return request({url: url, encoding: null}, function(error, response, body) { if (!error && response.statusCode >= 200 && response.statusCode < 300) { diff --git a/js/util/browser/ajax.js b/js/util/browser/ajax.js index 3d61e62dfed..1c9b4c870b7 100644 --- a/js/util/browser/ajax.js +++ b/js/util/browser/ajax.js @@ -24,13 +24,20 @@ exports.getJSON = function(url, callback) { return xhr; }; -exports.getArrayBuffer = function(url, callback) { +exports.getArrayBuffer = function(url, headers, callback) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, true); xhr.responseType = 'arraybuffer'; xhr.onerror = function(e) { callback(e); }; + + if (headers !== undefined && headers !== null) { + for (var i = 0; i < headers.length; i++) { + xhr.setRequestHeader(headers[i][0], headers[i][1]); + } + } + xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 300 && xhr.response) { callback(null, xhr.response); @@ -49,7 +56,7 @@ function sameOrigin(url) { } exports.getImage = function(url, callback) { - return exports.getArrayBuffer(url, function(err, imgData) { + return exports.getArrayBuffer(url, null, function(err, imgData) { if (err) return callback(err); var img = new Image(); img.onload = function() {