fix(tiles): derive the tile origin from the configured TileJSON (#933)

`createVectorTileSource` took `tileJsonUrl` and `allowedOrigin` as independent
options, and `createOpenFreeMapSource` hardcoded both to the default host. A
caller that repointed only `tileJsonUrl` — the obvious single change — kept the
default `allowedOrigin`, so the TileJSON's absolute upstream `tiles[0]` passed
the origin check and every tile was fetched from the default host instead. No
error, no warning, and nothing reached the configured mirror.

`allowedOrigin` now defaults to the origin of `tileJsonUrl`, so repointing one
option is enough, and a mirror that serves the default host's TileJSON verbatim
fails with the existing `Invalid vector tile origin` instead of silently
bypassing itself. The origin check is unchanged: a TileJSON still cannot point
the client at a host the caller did not configure.

All three existing callers pass `allowedOrigin` explicitly
(`openFreeMap.js`, `alpr/source.js`, `traffic/flowSource.js`), and an explicit
value still overrides the derived one, so behaviour is unchanged for every
current call site.
This commit is contained in:
daikaginza committed 2026-10-05 16:50:30 +07:00
1 parent e1cc7afacf
commit c6b43a365d
4 files changed
+106 -3

No files matched your search

+17 -1
View File
@@ -16,11 +16,27 @@ export function validTileBounds(box) {
);
}
/**
* The origin a configured TileJSON is served from, or undefined when there is
* no absolute URL to read one off. Deriving `allowedOrigin` from it means
* repointing `tileJsonUrl` at a mirror cannot silently keep loading tiles from
* the old host: the origin check below then names the mismatch instead of
* passing it (#933).
*/
function tileJsonOrigin(tileJsonUrl) {
if (typeof tileJsonUrl !== 'string') return undefined;
try {
return new URL(tileJsonUrl).origin;
} catch {
return undefined;
}
}
/** A decoded XYZ cache with bounded workers, reads, retained bytes and request lifetimes. */
export function createVectorTileSource({
tileJsonUrl,
template,
allowedOrigin,
allowedOrigin = tileJsonOrigin(tileJsonUrl),
decode,
fetchImpl = (...args) => globalThis.fetch(...args),
maxTiles = 16,