Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/islands/maps/MapExplorer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,22 @@ export default function MapExplorer({ lang = 'en' }: { lang?: Lang }) {
// never needs its own TileJSON fetch (avoids stale CDN edge responses).
const styleInput = await fetchResolvedStyle(initialUrl);
if (cancelled || !containerRef.current) return;

// Diagnostic: probe one vector tile to verify the proxy returns valid PBF.
// Valid gzip-PBF starts with bytes 1f 8b; raw PBF starts with a protobuf tag.
// HTML/JSON/text responses (corrupted edge cache) start with ASCII bytes.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const omtTiles = (styleInput as any)?.sources?.openmaptiles?.tiles;
if (Array.isArray(omtTiles) && omtTiles[0]) {
const probeUrl = (omtTiles[0] as string).replace('{z}', '5').replace('{x}', '26').replace('{y}', '16');
fetch(probeUrl).then(async r => {
const buf = await r.arrayBuffer();
const b = new Uint8Array(buf.slice(0, 8));
const hex = Array.from(b).map(n => n.toString(16).padStart(2, '0')).join(' ');
console.log('[map] tile probe', probeUrl, '→ status:', r.status, 'ct:', r.headers.get('content-type'), 'size:', buf.byteLength, 'bytes:', hex);
}).catch(e => console.error('[map] tile probe error:', e));
}

// Rewrite every OpenFreeMap URL that MapLibre would fetch on its own
// (TileJSON, vector/raster tiles, glyphs, sprites) through our /ofm/ proxy.
// This is the definitive safety net: even if fetchResolvedStyle leaves a
Expand Down
8 changes: 7 additions & 1 deletion worker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,15 @@ export default {
return new Response('Method not allowed', { status: 405 });
}
const upstream = 'https://tiles.openfreemap.org/' + url.pathname.slice('/ofm/'.length) + url.search;
// Fetch WITHOUT cf.cacheEverything so we bypass Cloudflare's edge cache.
// The Singapore edge had corrupted cached responses for OFM PBF tile URLs
// (HTTP 200 with wrong body), which were being served by the edge cache
// when cacheEverything:true was set. Going directly to OFM's origin via
// CF backbone avoids those stale entries. The browser's own HTTP cache
// (driven by the cache-control header we set below) handles client-side
// caching without touching the broken edge entries.
const res = await fetch(upstream, {
headers: { 'user-agent': 'goodwebtools-ofm-proxy' },
cf: { cacheEverything: true, cacheTtl: 86400 },
});
if (!res.ok) {
return new Response('Upstream OFM fetch failed', { status: res.status || 502 });
Expand Down
Loading