diff --git a/www/main.tsx b/www/main.tsx index 727da08a..e329074e 100644 --- a/www/main.tsx +++ b/www/main.tsx @@ -5,6 +5,7 @@ import { docsRoute } from "./routes/docs-route.tsx"; import { indexRoute } from "./routes/index-route.tsx"; import { v2docsRoute } from "./routes/v2docs-route.tsx"; import { assetsRoute } from "./routes/assets-route.ts"; +import { proxyRoute } from "./routes/proxy-route.ts"; import { config } from "./tailwind.config.ts"; @@ -17,6 +18,7 @@ import { loadDocs } from "./docs/docs.ts"; import { loadV2Docs } from "./docs/v2-docs.ts"; await main(function* () { + let proxies = proxySites(); let v2docs = yield* loadV2Docs({ fetchEagerly: !!Deno.env.get("V2_DOCS_FETCH_EAGERLY"), revision: Number(Deno.env.get("V2_DOCS_REVISION") ?? 4), @@ -27,6 +29,7 @@ await main(function* () { let revolution = createRevolution({ app: [ route("/", indexRoute()), + route("/contribs(.*)", proxyRoute(proxies.contribs)), route("/docs/:id", docsRoute(docs)), route("/assets(.*)", assetsRoute("assets")), route("/V2(.*)", v2docsRoute(v2docs)), @@ -44,3 +47,14 @@ await main(function* () { yield* suspend(); }); + + +function proxySites() { + return { + contribs: { + prefix: "contribs", + website: Deno.env.get("CONTRIBS_URL") ?? "https://effection-contribs.deno.dev", + } + } as const; +} + diff --git a/www/routes/index-route.tsx b/www/routes/index-route.tsx index 7e5e50d5..c601d3f9 100644 --- a/www/routes/index-route.tsx +++ b/www/routes/index-route.tsx @@ -26,6 +26,7 @@ export function indexRoute(): SitemapRoute { navLinks={[ Guides, API, + Contribs, { + let website = new URL(options.website); + + let target = new URL(request.url); + + let prefix = new RegExp(`^\/${options.prefix}\/?`); + target.pathname = target.pathname.replace(prefix, options.root ?? "/"); + + target.hostname = website.hostname; + target.port = website.port; + target.protocol = website.protocol; + + let base = new URL(`/${options.prefix}`, request.url); + + let headers: Record = { + "X-Base-Url": base.toString(), + }; + for (let [key, value] of request.headers.entries()) { + headers[key] = value; + } + + let response = yield* call(fetch(target, { + redirect: "manual", + headers, + })); + + if (response.status === 301) { + let location = response.headers.get("location"); + if (location?.startsWith(String(website))) { + let headers: Record = {}; + for (let [key, value] of request.headers.entries()) { + headers[key] = value; + } + + let url = new URL(request.url); + headers.location = location.replace(target.origin, url.origin); + + response = new Response(null, { + status: response.status, + statusText: response.statusText, + headers, + }); + } + } + + return response; + }; +}