| 76 | } |
| 77 | |
| 78 | export function serveUIEffect( |
| 79 | request: HttpServerRequest.HttpServerRequest, |
| 80 | services: { fs: FSUtil.Interface; client: HttpClient.HttpClient; disableEmbeddedWebUi: boolean }, |
| 81 | ) { |
| 82 | return Effect.gen(function* () { |
| 83 | const embeddedWebUI = yield* Effect.promise(() => embeddedUI(services.disableEmbeddedWebUi)) |
| 84 | const path = new URL(request.url, "http://localhost").pathname |
| 85 | |
| 86 | if (embeddedWebUI) return yield* serveEmbeddedUIEffect(path, services.fs, embeddedWebUI) |
| 87 | |
| 88 | const response = yield* services.client.execute( |
| 89 | HttpClientRequest.make(request.method)(upstreamURL(path), { |
| 90 | headers: ProxyUtil.headers(request.headers, { host: UI_UPSTREAM.host }), |
| 91 | body: requestBody(request), |
| 92 | }), |
| 93 | ) |
| 94 | const headers = proxyResponseHeaders(response.headers) |
| 95 | |
| 96 | if (response.headers["content-type"]?.includes("text/html")) { |
| 97 | const body = yield* response.text |
| 98 | headers.set("Content-Security-Policy", cspForHtml(body)) |
| 99 | return HttpServerResponse.text(body, { status: response.status, headers }) |
| 100 | } |
| 101 | |
| 102 | headers.set("Content-Security-Policy", csp()) |
| 103 | return HttpServerResponse.stream(response.stream.pipe(Stream.catchCause(() => Stream.empty)), { |
| 104 | status: response.status, |
| 105 | headers, |
| 106 | }) |
| 107 | }) |
| 108 | } |