@@ -8,6 +8,8 @@ export interface Env {
88 ASSETS : AssetsBinding ;
99 /** Cloudflare Browser Rendering binding (wrangler.jsonc: browser.binding) */
1010 BROWSER ?: unknown ;
11+ /** KV store for ISO links (global replication). Create with: wrangler kv namespace create "MS_ISO_LINKS" */
12+ MS_ISO_LINKS ?: { get ( key : string ) : Promise < string | null > ; put ( key : string , value : string , options ?: { expirationTtl ?: number } ) : Promise < void > } ;
1113}
1214
1315const MS_CONNECTOR_BASE = 'https://www.microsoft.com/software-download-connector/api' ;
@@ -275,24 +277,21 @@ export default {
275277 const skuId = url . searchParams . get ( 'skuId' ) ?? '' ;
276278 if ( ! skuId ) return errorResponse ( 'Missing skuId parameter.' ) ;
277279
278- // Cache key is arch+skuId only so all clients reuse the same link (sessionId is irrelevant for links).
279- const cacheKey = new URL ( url . pathname , url . origin ) ;
280- cacheKey . searchParams . set ( 'arch' , arch ) ;
281- cacheKey . searchParams . set ( 'skuId' , skuId ) ;
282- const cacheRequest = new Request ( cacheKey . toString ( ) , { method : 'GET' } ) ;
283-
284- // Reuse a recently generated link for the same arch+skuId to avoid spawning extra browsers.
285- const cached = await caches . default . match ( cacheRequest ) ;
286- if ( cached ) {
287- const body = await cached . clone ( ) . text ( ) ;
288- return new Response ( body , {
289- status : 200 ,
290- headers : {
291- 'Content-Type' : 'application/json' ,
292- 'Cache-Control' : 'no-store' ,
293- ...CORS_HEADERS ,
294- } ,
295- } ) ;
280+ // KV is globally replicated; Cache API is per–data center, so same locale in another region would spawn a new browser.
281+ const kv = env . MS_ISO_LINKS ;
282+ const kvKey = `ms-iso:${ arch } :${ skuId } ` ;
283+ if ( kv ) {
284+ const cached = await kv . get ( kvKey ) ;
285+ if ( cached ) {
286+ return new Response ( cached , {
287+ status : 200 ,
288+ headers : {
289+ 'Content-Type' : 'application/json' ,
290+ 'Cache-Control' : 'no-store' ,
291+ ...CORS_HEADERS ,
292+ } ,
293+ } ) ;
294+ }
296295 }
297296
298297 const viaBrowser = await getIsoLinkViaBrowser ( env , arch , skuId ) ;
@@ -312,14 +311,9 @@ export default {
312311 ] ,
313312 } ;
314313 const body = JSON . stringify ( payload ) ;
315- const cacheResponse = new Response ( body , {
316- headers : {
317- 'Content-Type' : 'application/json' ,
318- 'Cache-Control' : `private, max-age=${ LINK_CACHE_MAX_AGE_SEC } ` ,
319- ...CORS_HEADERS ,
320- } ,
321- } ) ;
322- await caches . default . put ( cacheRequest , cacheResponse ) ;
314+ if ( kv ) {
315+ await kv . put ( kvKey , body , { expirationTtl : LINK_CACHE_MAX_AGE_SEC } ) ;
316+ }
323317
324318 return new Response ( body , {
325319 status : 200 ,
0 commit comments