the worker settings on cloudfare have a route set to christopherpaine.org/private_assets

routes define which HTTP requests should be handled by specific worker script.

clicking a link typically invokes a GET method .

thinking about pdfs

worker downloads file

const ALLOWED_ORIGINS = [
  "https://christopherpaine.org",
  "http://localhost:4000"
];

defines a constant array called ALLOWED_ORIGINS. it lists the origins (protocol + domain + optional port) that are allowed to access.

it is usually used for CORS (Cross-Origin Resource Sharing) to control which websites can make requests to server.

requests from any origin not in this list would be blocked.

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request));
});

this is for the cloudfare worker and listens for incoming http requests (fetch events) everytime a request hits the worker the arrow function => is run.

instead of the default behaviour respond with whatever handleRequest returns.

handleRequest is a function defined elsewhere that takes the request and returns a response

in short the event listener intercepts network requests and allows for a custom response programmatically.

async function handleRequest(request) {

means the function is asynchronous and will always return a Promise , even when you dont explicitly return one.

const origin = request.headers.get("Origin") || "";
const referer = request.headers.get("Referer") || "";

this part retrieves values from an incoming request object.

the first obtains origin (scheme + domain + port ) of the request. the second obtains the referer - which is the url of the page that made the request.

for example

origin could be https://example.com

and

referrer could be https://example.com/page?query=123

// ---- CORS headers ----
const corsHeaders = new Headers();
corsHeaders.set("Access-Control-Allow-Origin", origin || "*");
corsHeaders.set("Vary", "Origin");
corsHeaders.set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS");
corsHeaders.set("Access-Control-Allow-Headers", "Authorization, Content-Type");
corsHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");

sets up a CORS policy. the purpose of a CORS (Cross-Origin Resource Sharing) policy is to control and secure how web browsers allow web pages from one origin to access resources on another origin.

(which to be fair is what i am probably doing with christopherpaine.org accessign resources from backblaze.

// Handle preflight requests
if (request.method === "OPTIONS") {
  return new Response(null, { status: 204, headers: corsHeaders });
}

browsers send an OPTIONS request before certain cross-origin requests to check what methods and headers the server allows. this is called a pre-flight request

: : : : : : : : : :

this is a part of code that i have been advised to fix

// ---- Forward file + headers ----
const headers = new Headers(fileResponse.headers);

to


const range = request.headers.get("Range");

const fileResponse = await fetch(downloadUrl, {
  headers: {
    "Authorization": authData.authorizationToken,
    ...(range ? { "Range": range } : {})
  }
});

to enable partial content fetching if the incoming request has one

also advised to fix the folowing bit at the end:


return new Response(fileResponse.body, { headers });

to


return new Response(fileResponse.body, {
  status: fileResponse.status,
  statusText: fileResponse.statusText,
  headers
});
const ALLOWED_ORIGINS = [
  "https://christopherpaine.org",
  "http://localhost:4000"
];

addEventListener("fetch", event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const origin = request.headers.get("Origin") || "";
  const referer = request.headers.get("Referer") || "";

  // ---- CORS headers ----
  const corsHeaders = new Headers();
  corsHeaders.set("Access-Control-Allow-Origin", origin || "*");
  corsHeaders.set("Vary", "Origin");
  corsHeaders.set("Access-Control-Allow-Methods", "GET, HEAD, OPTIONS");
  corsHeaders.set("Access-Control-Allow-Headers", "Authorization, Content-Type");
  corsHeaders.set("Access-Control-Expose-Headers", "Content-Disposition");

  // Handle preflight requests
  if (request.method === "OPTIONS") {
    return new Response(null, { status: 204, headers: corsHeaders });
  }

  // ---- Resolve asset path ----
  const url = new URL(request.url);
  const assetPath = url.pathname.replace("/private_assets/", "");

  // ---- Origin / Referer gate ----
  // PDFs bypass origin/referer check to allow iframe embedding
  if (!assetPath.endsWith(".pdf")) {
    if (!ALLOWED_ORIGINS.some(o => origin.startsWith(o) || referer.startsWith(o))) {
      return new Response("Forbidden", { status: 403, headers: corsHeaders });
    }
  }

  // ---- Authorize with Backblaze B2 ----
  const authResponse = await fetch(
    "https://api.backblazeb2.com/b2api/v2/b2_authorize_account",
    {
      headers: {
        "Authorization": "Basic " + btoa("003f18b31f77ee90000000004:K003m+xPsN4IVu2o0WCqHXe+wgujA48")
      }
    }
  );

  const authData = await authResponse.json();
  const downloadUrl = `${authData.downloadUrl}/file/cp-private-assets/${assetPath}`;

  // ---- Fetch file ----
  const fileResponse = await fetch(downloadUrl, {
    headers: { "Authorization": authData.authorizationToken }
  });

  if (!fileResponse.ok) {
    const text = await fileResponse.text();
    return new Response(
      `B2 error ${fileResponse.status}:\n${text}`,
      { status: 500, headers: { "Content-Type": "text/plain", ...Object.fromEntries(corsHeaders) } }
    );
  }

  // ---- Forward file + headers ----
  const headers = new Headers(fileResponse.headers);

  // Set caching
  headers.set("Cache-Control", "public, max-age=31536000");

  // Merge CORS
  for (const [k, v] of corsHeaders) {
    headers.set(k, v);
  }

  // ✅ PDF fix for iframes
  if (assetPath.endsWith(".pdf")) {
    headers.set("Content-Type", "application/pdf");
    headers.set("Content-Disposition", "inline");
    headers.delete("X-Frame-Options");
    headers.delete("Content-Security-Policy");
  }

  return new Response(fileResponse.body, { headers });
}


This site uses Just the Docs, a documentation theme for Jekyll.