From 51e1eaf817e2680b8ac0832fd0c3c8a7002da6db Mon Sep 17 00:00:00 2001 From: Zef Hemel Date: Mon, 6 Oct 2025 14:38:00 +0200 Subject: [PATCH] /.proxy enhancements Now cleanly separates request and response headers for the request and response of the http request from the ones that SB needs/serves itself. --- client/plugos/syscalls/fetch.ts | 37 ++++++++++++++++++++++++--------- client/space_lua/eval.ts | 9 ++++++-- deno.lock | 5 +++++ server/proxy.go | 13 +++--------- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/client/plugos/syscalls/fetch.ts b/client/plugos/syscalls/fetch.ts index b701362e..42c78b52 100644 --- a/client/plugos/syscalls/fetch.ts +++ b/client/plugos/syscalls/fetch.ts @@ -32,17 +32,11 @@ export function sandboxFetchSyscalls( const fetchOptions = options ? { method: options.method, - headers: options.headers, + headers: {} as Record, body: options.body, } : {}; - fetchOptions.headers = { "X-Proxy-Request": "true" }; - // Copy the headers from the options prefixed with X-Proxy-Header - if (options.headers) { - for (const [k, v] of Object.entries(options.headers)) { - fetchOptions.headers[`X-Proxy-Header-${k}`] = v; - } - } + fetchOptions.headers = buildProxyHeaders(options.headers); const resp = await client.httpSpacePrimitives.authenticatedFetch( buildProxyUrl(client, url), fetchOptions, @@ -62,7 +56,7 @@ export function sandboxFetchSyscalls( return { ok: resp.ok, status: resp.status, - headers: Object.fromEntries(resp.headers.entries()), + headers: extractProxyHeaders(resp.headers), body: body, }; }, @@ -89,7 +83,7 @@ export function sandboxFetchSyscalls( return { ok: resp.ok, status: resp.status, - headers: Object.fromEntries(resp.headers.entries()), + headers: extractProxyHeaders(resp.headers), base64Body: base64Encode(new Uint8Array(body)), }; }, @@ -102,3 +96,26 @@ function buildProxyUrl(client: Client, url: string) { return client.httpSpacePrimitives.url.slice(0, -fsEndpoint.length) + "/.proxy/" + url; } + +function buildProxyHeaders(headers?: Record): Record { + const newHeaders: Record = { "X-Proxy-Request": "true" }; + if (!headers) { + return newHeaders; + } + for (const [key, value] of Object.entries(headers)) { + newHeaders[`X-Proxy-Header-${key}`] = value; + } + return newHeaders; +} + +function extractProxyHeaders( + headers: Headers, +): Record { + const newHeaders: Record = {}; + for (const [key, value] of headers.entries()) { + if (key.toLowerCase().startsWith("x-proxy-header-")) { + newHeaders[key.slice("x-proxy-header-".length)] = value; + } + } + return newHeaders; +} diff --git a/client/space_lua/eval.ts b/client/space_lua/eval.ts index 46d7ea96..da94849d 100644 --- a/client/space_lua/eval.ts +++ b/client/space_lua/eval.ts @@ -154,7 +154,10 @@ export function evalExpression( return value.then((value) => { switch (e.operator) { case "-": - if (e.argument.type === "Number" && e.argument.numericType === "int") { + if ( + e.argument.type === "Number" && + e.argument.numericType === "int" + ) { if (e.argument.value === 0) { return 0; } @@ -177,7 +180,9 @@ export function evalExpression( } else { switch (e.operator) { case "-": - if (e.argument.type === "Number" && e.argument.numericType === "int") { + if ( + e.argument.type === "Number" && e.argument.numericType === "int" + ) { if (e.argument.value === 0) { return 0; } diff --git a/deno.lock b/deno.lock index 73b9a5d0..bd7f66c0 100644 --- a/deno.lock +++ b/deno.lock @@ -626,6 +626,11 @@ "https://deno.land/x/silverbullet@2.1.6/client/plugos/proxy_fetch.ts": "22b5ea81928adba33bda9891e415d98cac24c03204b4037543a25f507f8dc17d", "https://deno.land/x/silverbullet@2.1.6/client/plugos/worker_runtime.ts": "0237c0c2d689bb47fc7561f835d081d8cc582b047b5867bea6e8c0b073b4ed55", "https://deno.land/x/silverbullet@2.1.6/plug-api/lib/crypto.ts": "b7485dfcc231cf03af0e5271b89970ba1f7ab6cb43ebfe555de0c48996313250", + "https://deno.land/x/silverbullet@2.1.7/client/lib/logger.ts": "09e3b6eabdb29203573da50950c9a08e75d7ca4f05bb56258413a758dda6201b", + "https://deno.land/x/silverbullet@2.1.7/client/plugos/protocol.ts": "1eca91d1fc2ef66ee5ed25f7b44c04f518b2d275a9f3d2a7b31c32d4437dd547", + "https://deno.land/x/silverbullet@2.1.7/client/plugos/proxy_fetch.ts": "22b5ea81928adba33bda9891e415d98cac24c03204b4037543a25f507f8dc17d", + "https://deno.land/x/silverbullet@2.1.7/client/plugos/worker_runtime.ts": "0237c0c2d689bb47fc7561f835d081d8cc582b047b5867bea6e8c0b073b4ed55", + "https://deno.land/x/silverbullet@2.1.7/plug-api/lib/crypto.ts": "b7485dfcc231cf03af0e5271b89970ba1f7ab6cb43ebfe555de0c48996313250", "https://esm.sh/lodash@4.17.21": "c2f90ffd948b7a30f054986888bdc2667824115fa48ad583ca8b3a579ca4a5a8", "https://esm.sh/lodash@4.17.21/denonext/lodash.mjs": "9d2a44e584d91008f61f974c6d0a32bf9afb1563761e60c366af0a293e8c759b", "https://esm.sh/moment@2.30.1": "61eef31d73508961f2cf25fc2cb507832f7158cf8638e86d933534c9adfac753", diff --git a/server/proxy.go b/server/proxy.go index 2d1fcdc3..1c4593bf 100644 --- a/server/proxy.go +++ b/server/proxy.go @@ -1,6 +1,7 @@ package server import ( + "fmt" "io" "log" "net/http" @@ -52,14 +53,6 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { return } - // Copy safe headers - safeHeaders := []string{"Authorization", "Accept", "Content-Type"} - for _, header := range safeHeaders { - if value := r.Header.Get(header); value != "" { - req.Header.Set(header, value) - } - } - // Copy headers starting with X-Proxy-Header-, removing the prefix for key, values := range r.Header { if strings.HasPrefix(strings.ToLower(key), "x-proxy-header-") { @@ -81,10 +74,10 @@ func proxyHandler(w http.ResponseWriter, r *http.Request) { } defer resp.Body.Close() - // Copy response headers + // Copy response response header with x-proxy-header prefix to keep things clean for key, values := range resp.Header { for _, value := range values { - w.Header().Set(key, value) + w.Header().Set(fmt.Sprintf("x-proxy-header-%s", key), value) } }