diff --git a/cloud-function/src/app.ts b/cloud-function/src/app.ts index c9cd727af7c5..c85c56531d28 100644 --- a/cloud-function/src/app.ts +++ b/cloud-function/src/app.ts @@ -5,7 +5,10 @@ import { Router } from "express"; import { ANY_ATTACHMENT_EXT } from "./internal/constants/index.js"; import { Origin } from "./env.js"; -import { proxyContent } from "./handlers/proxy-content.js"; +import { + proxyContent, + proxyContentPagefind, +} from "./handlers/proxy-content.js"; import { proxyApi } from "./handlers/proxy-api.js"; import { handleStripePlans } from "./handlers/handle-stripe-plans.js"; import { proxyTelemetry } from "./handlers/proxy-telemetry.js"; @@ -24,7 +27,10 @@ import { notFound } from "./middlewares/not-found.js"; import { stripForwardedHostHeaders } from "./middlewares/stripForwardedHostHeaders.js"; import { proxyPong } from "./handlers/proxy-pong.js"; import { handleRunner } from "./internal/play/index.js"; -import { proxyContentAssets } from "./handlers/proxy-content-assets.js"; +import { + proxyContentAssets, + proxyContentAssetsPagefind, +} from "./handlers/proxy-content-assets.js"; const router = Router(); router.use(cookieParser()); @@ -101,6 +107,22 @@ router.get( resolveIndexHTML, proxyContent ); + +// pagefind test +router.get( + ["/[^/]+/pagefind/$"], + requireOrigin(Origin.main), + redirectLocale, + redirectEnforceTrailingSlash, + resolveIndexHTML, + proxyContentPagefind +); +router.get( + ["/[^/]+/pagefind/*"], + lowercasePathname, + proxyContentAssetsPagefind +); + // MDN Plus, static pages, etc. router.get( "*", diff --git a/cloud-function/src/handlers/proxy-content-assets.ts b/cloud-function/src/handlers/proxy-content-assets.ts index 5ed5c29ba325..aa42886bc9bc 100644 --- a/cloud-function/src/handlers/proxy-content-assets.ts +++ b/cloud-function/src/handlers/proxy-content-assets.ts @@ -48,3 +48,40 @@ export const proxyContentAssets = createProxyMiddleware({ ), }, }); + +export const proxyContentAssetsPagefind = createProxyMiddleware({ + target, + changeOrigin: true, + autoRewrite: true, + proxyTimeout: PROXY_TIMEOUT, + xfwd: true, + selfHandleResponse: true, + on: { + proxyReq: fixRequestBody, + proxyRes: responseInterceptor( + async (responseBuffer, proxyRes, req, res) => { + // withContentResponseHeaders(proxyRes, req, res); + const [, locale] = req.url?.split("/") || []; + if ( + proxyRes.statusCode === 404 && + locale && + locale != "en-US" && + ACTIVE_LOCALES.has(locale.toLowerCase()) + ) { + const enUsAsset = await fetch( + `${target}${req.url?.slice(1).replace(locale, "en-us")}` + ); + if (enUsAsset?.ok) { + res.statusCode = enUsAsset.status; + enUsAsset.headers.forEach((value, key) => + res.setHeader(key, value) + ); + return Buffer.from(await enUsAsset.arrayBuffer()); + } + } + + return responseBuffer; + } + ), + }, +}); diff --git a/cloud-function/src/handlers/proxy-content.ts b/cloud-function/src/handlers/proxy-content.ts index adbfa8d8e9a2..96ea17f590e3 100644 --- a/cloud-function/src/handlers/proxy-content.ts +++ b/cloud-function/src/handlers/proxy-content.ts @@ -23,6 +23,7 @@ export const proxyContent = createProxyMiddleware({ proxyTimeout: PROXY_TIMEOUT, xfwd: true, selfHandleResponse: true, + logger: console, on: { proxyReq: fixRequestBody, proxyRes: responseInterceptor( @@ -49,3 +50,38 @@ export const proxyContent = createProxyMiddleware({ ), }, }); + +export const proxyContentPagefind = createProxyMiddleware({ + target, + changeOrigin: true, + autoRewrite: true, + proxyTimeout: PROXY_TIMEOUT, + xfwd: true, + selfHandleResponse: true, + logger: console, + on: { + proxyReq: fixRequestBody, + proxyRes: responseInterceptor( + async (responseBuffer, proxyRes, req, res) => { + // withContentResponseHeaders(proxyRes, req, res); + if (proxyRes.statusCode === 404 && !isLiveSampleURL(req.url ?? "")) { + const tryHtml = await fetch( + `${target}${req.url?.slice(1)}/index.html` + ); + if (tryHtml.ok) { + res.statusCode = 200; + res.setHeader("Content-Type", "text/html"); + return Buffer.from(await tryHtml.arrayBuffer()); + } else if (!notFoundBuffer) { + const response = await fetch(`${target}${NOT_FOUND_PATH}`); + notFoundBuffer = await response.arrayBuffer(); + } + res.setHeader("Content-Type", "text/html"); + return Buffer.from(notFoundBuffer); + } + + return responseBuffer; + } + ), + }, +});