fix: support Cloud Web internal API port

This commit is contained in:
root
2026-05-22 09:03:44 +00:00
parent 21bec8975a
commit 39435490c5
2 changed files with 50 additions and 14 deletions
+46 -14
View File
@@ -299,6 +299,7 @@ async function resolveServices(serviceIds, catalog) {
function runtimeScriptBase64() {
const source = String.raw`
import { createServer } from "node:http";
import http from "node:http";
import { spawn } from "node:child_process";
import { readFile, stat } from "node:fs/promises";
import path from "node:path";
@@ -364,6 +365,36 @@ function copyHeaders(headers) {
return result;
}
function requestUpstream(target, request, body) {
return new Promise((resolve, reject) => {
const upstream = http.request(
target,
{
method: request.method,
headers: {
accept: request.headers.accept || "application/json",
"content-type": request.headers["content-type"] || "application/json",
"content-length": Buffer.byteLength(body)
}
},
(upstreamResponse) => {
const chunks = [];
upstreamResponse.on("data", (chunk) => chunks.push(chunk));
upstreamResponse.on("end", () => {
resolve({
statusCode: upstreamResponse.statusCode || 502,
headers: upstreamResponse.headers,
body: Buffer.concat(chunks)
});
});
}
);
upstream.on("error", reject);
if (body) upstream.write(body);
upstream.end();
});
}
async function proxyCloudApi(request, response, url) {
if (!cloudApiBaseUrl) {
sendJson(response, 503, {
@@ -401,20 +432,21 @@ async function proxyCloudApi(request, response, url) {
}
const target = new URL(url.pathname + url.search, cloudApiBaseUrl);
const upstream = await fetch(target, {
method: request.method,
headers: {
accept: request.headers.accept || "application/json",
"content-type": request.headers["content-type"] || "application/json"
},
body: request.method === "GET" ? undefined : body
});
const payload = Buffer.from(await upstream.arrayBuffer());
response.writeHead(upstream.status, {
...copyHeaders(Object.fromEntries(upstream.headers.entries())),
"content-length": payload.length
});
response.end(payload);
try {
const upstream = await requestUpstream(target, request, request.method === "GET" ? "" : body);
response.writeHead(upstream.statusCode, {
...copyHeaders(upstream.headers),
"content-length": upstream.body.length
});
response.end(upstream.body);
} catch (error) {
sendJson(response, 502, {
error: "cloud_api_proxy_failed",
serviceId,
target: target.href.replace(/\/\/[^/@]*@/u, "//***@"),
reason: error.message
});
}
}
async function serveCloudWeb() {
+4
View File
@@ -51,11 +51,15 @@ assert.match(app, /callRpc\("audit\.event\.query"/);
assert.match(app, /callRpc\("evidence\.record\.query"/);
assert.match(artifactPublisher, /HWLAB_API_BASE_URL/);
assert.match(artifactPublisher, /readOnlyRpcMethods/);
assert.match(artifactPublisher, /requestUpstream/);
assert.match(artifactPublisher, /from "node:http"/);
assert.doesNotMatch(artifactPublisher, /await fetch\(target/);
assert.match(artifactPublisher, /"system\.health"/);
assert.match(artifactPublisher, /"cloud\.adapter\.describe"/);
assert.match(artifactPublisher, /"audit\.event\.query"/);
assert.match(artifactPublisher, /"evidence\.record\.query"/);
assert.match(artifactPublisher, /readonly_rpc_required/);
assert.match(artifactPublisher, /cloud_api_proxy_failed/);
assert.match(app, /degraded/);
assert.match(app, /runtime\.serviceRoute\.join\(" -> "\)/);
assert.doesNotMatch(app, /callRpc\("hardware\./);