Add index.js

This commit is contained in:
lsemenenko 2025-03-01 01:40:12 +00:00
parent 8bf1693cc0
commit 9228c5ee4e

136
index.js Normal file
View File

@ -0,0 +1,136 @@
/**
* Cloudflare Worker to cache a URL on all US Edge servers
*
* This worker:
* 1. Accepts a target URL via query parameter or POST body
* 2. Fetches the URL using Cloudflare's fetch API
* 3. Forces caching by setting appropriate cache headers
* 4. Can be configured to cache on specific US regions or all of them
*/
// Define US Cloudflare regions (These are the major US colo locations)
const US_REGIONS = [
"IAD", // Washington DC (Northern Virginia)
"EWR", // Newark, NJ
"ATL", // Atlanta, GA
"MIA", // Miami, FL
"ORD", // Chicago, IL
"DFW", // Dallas, TX
"DEN", // Denver, CO
"SEA", // Seattle, WA
"LAX", // Los Angeles, CA
"SJC", // San Jose, CA
"PHX" // Phoenix, AZ
];
export default {
async fetch(request, env, ctx) {
// Create the response headers with CORS support
const headers = new Headers({
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
"Content-Type": "application/json"
});
// Handle OPTIONS requests (pre-flight for CORS)
if (request.method === "OPTIONS") {
return new Response(null, { headers });
}
// Get the target URL from query params or POST body
let targetUrl;
if (request.method === "POST") {
try {
const body = await request.json();
targetUrl = body.url;
} catch (error) {
return new Response(
JSON.stringify({ error: "Invalid JSON body" }),
{ headers, status: 400 }
);
}
} else {
const url = new URL(request.url);
targetUrl = url.searchParams.get("url");
}
// Validate the target URL
if (!targetUrl) {
return new Response(
JSON.stringify({ error: "Missing 'url' parameter" }),
{ headers, status: 400 }
);
}
try {
new URL(targetUrl); // Validate URL format
} catch (error) {
return new Response(
JSON.stringify({ error: "Invalid URL format" }),
{ headers, status: 400 }
);
}
// Process all regions in parallel
const results = await Promise.allSettled(US_REGIONS.map(async (region) => {
return await cacheInRegion(targetUrl, region);
}));
// Compile results
const response = {
url: targetUrl,
cached: true,
regionResults: results.map((result, index) => ({
region: US_REGIONS[index],
success: result.status === "fulfilled",
status: result.status === "fulfilled" ? result.value.status : null,
error: result.status === "rejected" ? result.reason.message : null
}))
};
return new Response(JSON.stringify(response, null, 2), { headers });
}
};
/**
* Attempts to cache the URL in a specific Cloudflare region
*
* @param {string} url - The URL to cache
* @param {string} region - The Cloudflare region code
* @returns {Promise<Object>} - The fetch response details
*/
async function cacheInRegion(url, region) {
// Create fetch request with cache control headers
const cacheRequest = new Request(url, {
headers: {
// CF-specific header to route to a specific region
"CF-Worker-Request-Region": region,
// Headers to encourage caching
"Cache-Control": "public, max-age=86400",
// Tell Cloudflare that we're a cache warmer
"User-Agent": "Cloudflare-Cache-Warmer/1.0"
},
cf: {
// Force caching even if origin has no-store
cacheEverything: true,
// Cache for 1 day
cacheTtl: 86400,
// Attempt to resolve through the specified region
resolveOverride: region
}
});
// Perform the fetch
const response = await fetch(cacheRequest);
return {
status: response.status,
cached: response.headers.get("CF-Cache-Status") === "HIT" ||
response.headers.get("CF-Cache-Status") === "MISS", // MISS on first cache, but still stored
headers: {
"CF-Cache-Status": response.headers.get("CF-Cache-Status"),
"CF-Ray": response.headers.get("CF-Ray")
}
};
}