修复426错误,优化前端数据刷新
This commit is contained in:
1 parent
3f50288454
commit
382f2345f5
8 files changed
+142
-7
No files matched your search
@@ -16,6 +16,11 @@ const directory = mkdtempSync(join(tmpdir(), "nodeflare-agent-runtime-"));
|
||||
const agents = [];
|
||||
const sockets = new Set();
|
||||
const releaseRequests = [];
|
||||
const agentProtocolHeaders = {
|
||||
"x-nodeflare-agent-protocol": "1",
|
||||
"x-nodeflare-agent-capabilities":
|
||||
"metrics-v1,config-v1,remote-exec-v1,task-ack-v1",
|
||||
};
|
||||
const proxy = createHttpServer((_request, response) => {
|
||||
response.writeHead(502);
|
||||
response.end();
|
||||
@@ -70,9 +75,15 @@ try {
|
||||
|
||||
console.log("agent runtime: automatic update during three-second sampling");
|
||||
websocketServer = new WebSocketServer({ noServer: true });
|
||||
websocketServer.on("headers", (headers) => {
|
||||
headers.push("X-NodeFlare-Agent-Protocol: 1");
|
||||
});
|
||||
upgradeServer = createHttpServer();
|
||||
let redirected = false;
|
||||
upgradeServer.on("upgrade", (request, socket, head) => {
|
||||
for (const [name, expected] of Object.entries(agentProtocolHeaders)) {
|
||||
assert.equal(request.headers[name], expected, `Agent must send ${name}`);
|
||||
}
|
||||
if (request.url === "/api/agent/ws") {
|
||||
redirected = true;
|
||||
socket.end("HTTP/1.1 307 Temporary Redirect\r\nLocation: /live\r\nContent-Length: 0\r\nConnection: close\r\n\r\n");
|
||||
|
||||
@@ -356,6 +356,8 @@ if [ -n "${MONITOR_MIGRATION_URL:-}" ]; then
|
||||
[ "$frozen_delete_status" = "503" ]
|
||||
frozen_agent_status=$(monitor_curl --silent --show-error --output /dev/null --write-out '%{http_code}' \
|
||||
-H "Authorization: Bearer $agent_token" \
|
||||
-H 'X-NodeFlare-Agent-Protocol: 1' \
|
||||
-H 'X-NodeFlare-Agent-Capabilities: metrics-v1,config-v1,remote-exec-v1,task-ack-v1' \
|
||||
-H 'Connection: Upgrade' -H 'Upgrade: websocket' -H 'Sec-WebSocket-Version: 13' \
|
||||
-H 'Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==' "$MONITOR_BASE_URL/api/agent/ws")
|
||||
[ "$frozen_agent_status" = "503" ]
|
||||
|
||||
@@ -27,6 +27,11 @@ const serverId = process.env.MONITOR_SERVER_ID;
|
||||
const latencyTaskId = process.env.MONITOR_LATENCY_TASK_ID;
|
||||
const expectTaskAssigned = process.env.MONITOR_EXPECT_TASK_ASSIGNED !== "0";
|
||||
const configOnly = process.env.MONITOR_CONFIG_ONLY === "1";
|
||||
const agentProtocolHeaders = {
|
||||
"X-NodeFlare-Agent-Protocol": "1",
|
||||
"X-NodeFlare-Agent-Capabilities":
|
||||
"metrics-v1,config-v1,remote-exec-v1,task-ack-v1",
|
||||
};
|
||||
|
||||
if (!baseUrl || !adminToken || !agentToken || !serverId || !latencyTaskId) {
|
||||
throw new Error("MONITOR_BASE_URL, MONITOR_ADMIN_TOKEN, MONITOR_AGENT_TOKEN, MONITOR_SERVER_ID and MONITOR_LATENCY_TASK_ID are required");
|
||||
@@ -115,25 +120,35 @@ async function waitForRemoteTask(taskId, expectedStatus) {
|
||||
throw new Error(`Remote task ${taskId} did not reach ${expectedStatus}`);
|
||||
}
|
||||
|
||||
function socketHeaders(token, headers = {}) {
|
||||
function socketHeaders(path, token, headers = {}, includeAgentProtocol = true) {
|
||||
return {
|
||||
Authorization: `Bearer ${token}`,
|
||||
...(includeAgentProtocol && path === "/api/agent/ws" ? agentProtocolHeaders : {}),
|
||||
...headers,
|
||||
};
|
||||
}
|
||||
|
||||
function openSocket(path, token, headers = {}, observeMessage) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let serverProtocol;
|
||||
const socket = new WebSocket(websocketUrl(path), {
|
||||
headers: socketHeaders(token, headers),
|
||||
headers: socketHeaders(path, token, headers),
|
||||
});
|
||||
if (observeMessage) socket.on("message", observeMessage);
|
||||
const timer = setTimeout(() => {
|
||||
socket.terminate();
|
||||
reject(new Error(`${path} WebSocket handshake timed out`));
|
||||
}, 5_000);
|
||||
socket.once("upgrade", (response) => {
|
||||
serverProtocol = response.headers["x-nodeflare-agent-protocol"];
|
||||
});
|
||||
socket.once("open", () => {
|
||||
clearTimeout(timer);
|
||||
if (path === "/api/agent/ws" && serverProtocol !== "1") {
|
||||
socket.terminate();
|
||||
reject(new Error(`Invalid backend Agent protocol: ${serverProtocol}`));
|
||||
return;
|
||||
}
|
||||
resolve(socket);
|
||||
});
|
||||
socket.once("unexpected-response", (_request, response) => {
|
||||
@@ -147,10 +162,10 @@ function openSocket(path, token, headers = {}, observeMessage) {
|
||||
});
|
||||
}
|
||||
|
||||
function expectSocketStatus(path, token, statusCode, headers = {}) {
|
||||
function expectSocketStatus(path, token, statusCode, headers = {}, includeAgentProtocol = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const socket = new WebSocket(websocketUrl(path), {
|
||||
headers: socketHeaders(token, headers),
|
||||
headers: socketHeaders(path, token, headers, includeAgentProtocol),
|
||||
});
|
||||
const timer = setTimeout(() => {
|
||||
socket.terminate();
|
||||
@@ -286,6 +301,22 @@ function waitForSocketClose(socket, expected, timeoutMs = 5_000) {
|
||||
});
|
||||
}
|
||||
|
||||
await expectSocketStatus("/api/agent/ws", "invalid-agent-token", 426, {}, false);
|
||||
await expectSocketStatus(
|
||||
"/api/agent/ws",
|
||||
"invalid-agent-token",
|
||||
426,
|
||||
{ "X-NodeFlare-Agent-Protocol": "0" },
|
||||
);
|
||||
await expectSocketStatus(
|
||||
"/api/agent/ws",
|
||||
"invalid-agent-token",
|
||||
426,
|
||||
{
|
||||
"X-NodeFlare-Agent-Capabilities":
|
||||
"metrics-v1,config-v1,remote-exec-v1",
|
||||
},
|
||||
);
|
||||
await expectSocketStatus("/api/agent/ws", "invalid-agent-token", 401);
|
||||
await expectSocketStatus("/api/agent/ws", "", 401);
|
||||
await expectSocketStatus("/api/agent/ws", "x".repeat(513), 401);
|
||||
|
||||
Reference in new issue
Block a user