1
0

Federation URL handling

This commit is contained in:
Zef Hemel 2023-11-16 13:55:02 +01:00
parent 1af5e022a0
commit 6336190c20
3 changed files with 54 additions and 40 deletions

View File

@ -4,7 +4,7 @@ import { loadPageObject, replaceTemplateVars } from "../template/template.ts";
import { PageMeta } from "$sb/types.ts"; import { PageMeta } from "$sb/types.ts";
import { renderTemplate } from "../template/plug_api.ts"; import { renderTemplate } from "../template/plug_api.ts";
import { renderToText } from "$sb/lib/tree.ts"; import { renderToText } from "$sb/lib/tree.ts";
import { rewritePageRefs } from "$sb/lib/resolve.ts"; import { rewritePageRefs, rewritePageRefsInString } from "$sb/lib/resolve.ts";
type TemplateConfig = { type TemplateConfig = {
// Pull the template from a page // Pull the template from a page
@ -28,6 +28,8 @@ export async function widget(
let templateText = config.template || ""; let templateText = config.template || "";
let templatePage = config.page; let templatePage = config.page;
if (templatePage) { if (templatePage) {
// Rewrite federation page references
templatePage = rewritePageRefsInString(templatePage, pageName);
if (templatePage.startsWith("[[")) { if (templatePage.startsWith("[[")) {
templatePage = templatePage.slice(2, -2); templatePage = templatePage.slice(2, -2);
} }

View File

@ -388,6 +388,7 @@ export class HttpServer {
// Handle federated links through a simple redirect, only used for attachments loads with service workers disabled // Handle federated links through a simple redirect, only used for attachments loads with service workers disabled
if (name.startsWith("!")) { if (name.startsWith("!")) {
let url = name.slice(1); let url = name.slice(1);
console.log("Handling this as a federated link", url);
if (url.startsWith("localhost")) { if (url.startsWith("localhost")) {
url = `http://${url}`; url = `http://${url}`;
} else { } else {
@ -489,48 +490,56 @@ export class HttpServer {
}) })
.options(filePathRegex, corsMiddleware); .options(filePathRegex, corsMiddleware);
// Federation proxy
const proxyPathRegex = "\/!(.+)"; const proxyPathRegex = "\/!(.+)";
fsRouter.all(proxyPathRegex, async ({ params, response, request }) => { fsRouter.all(
let url = params[0]; proxyPathRegex,
console.log("Requested path to proxy", url, request.method); async ({ params, response, request }, next) => {
if (url.startsWith("localhost")) { let url = params[0];
url = `http://${url}`; if (!request.headers.has("X-Proxy-Request")) {
} else { // Direct browser request, not explicity fetch proxy request
url = `https://${url}`; if (!/\.[a-zA-Z0-9]+$/.test(url)) {
} console.log("Directly loading federation page via URL:", url);
try { // This is not a direct file reference so LIKELY a page request, fall through and load the SB UI
const safeRequestHeaders = new Headers(); return next();
for (const headerName of ["Authorization", "Accept", "Content-Type"]) {
if (request.headers.has(headerName)) {
safeRequestHeaders.set(
headerName,
request.headers.get(headerName)!,
);
} }
} }
const req = await fetch(url, { console.log("Requested path to proxy", url, request.method);
method: request.method, if (url.startsWith("localhost")) {
headers: safeRequestHeaders, url = `http://${url}`;
body: request.hasBody } else {
? request.body({ type: "stream" }).value url = `https://${url}`;
: undefined, }
}); try {
response.status = req.status; const safeRequestHeaders = new Headers();
// // Override X-Permssion header to always be "ro" for (
// const newHeaders = new Headers(); const headerName of ["Authorization", "Accept", "Content-Type"]
// for (const [key, value] of req.headers.entries()) { ) {
// newHeaders.set(key, value); if (request.headers.has(headerName)) {
// } safeRequestHeaders.set(
// newHeaders.set("X-Permission", "ro"); headerName,
response.headers = req.headers; request.headers.get(headerName)!,
response.body = req.body; );
} catch (e: any) { }
console.error("Error fetching federated link", e); }
response.status = 500; const req = await fetch(url, {
response.body = e.message; method: request.method,
} headers: safeRequestHeaders,
return; body: request.hasBody
}); ? request.body({ type: "stream" }).value
: undefined,
});
response.status = req.status;
response.headers = req.headers;
response.body = req.body;
} catch (e: any) {
console.error("Error fetching federated link", e);
response.status = 500;
response.body = e.message;
}
return;
},
);
return fsRouter; return fsRouter;
} }

View File

@ -32,6 +32,9 @@ export function sandboxFetchSyscalls(
// No SB server to proxy the fetch available so let's execute the request directly // No SB server to proxy the fetch available so let's execute the request directly
return performLocalFetch(url, fetchOptions); return performLocalFetch(url, fetchOptions);
} }
fetchOptions.headers = fetchOptions.headers
? { ...fetchOptions.headers, "X-Proxy-Request": "true" }
: { "X-Proxy-Request": "true" };
const resp = await client.remoteSpacePrimitives.authenticatedFetch( const resp = await client.remoteSpacePrimitives.authenticatedFetch(
`${client.remoteSpacePrimitives.url}/!${url}`, `${client.remoteSpacePrimitives.url}/!${url}`,
fetchOptions, fetchOptions,