diff --git a/server/client.js b/server/client.js index 31f995f38..909c3e25b 100644 --- a/server/client.js +++ b/server/client.js @@ -9,6 +9,7 @@ const io = server.io; const { setting } = require("./util-server"); const checkVersion = require("./check-version"); const Database = require("./database"); +const Heartbeat = require("./model/heartbeat"); /** * Send list of notification providers to client @@ -54,7 +55,16 @@ async function sendHeartbeatList(socket, monitorID, toUser = false, overwrite = [monitorID] ); - let result = list.reverse(); + let result = list.reverse().map((row) => { + if (row.response) { + return { + ...row, + response: Heartbeat.decodeResponseValue(row.response), + }; + } + + return row; + }); if (toUser) { io.to(socket.userID).emit("heartbeatList", monitorID, result, overwrite); @@ -87,10 +97,12 @@ async function sendImportantHeartbeatList(socket, monitorID, toUser = false, ove timeLogger.print(`[Monitor: ${monitorID}] sendImportantHeartbeatList`); + const result = list.map((bean) => bean.toJSON()); + if (toUser) { - io.to(socket.userID).emit("importantHeartbeatList", monitorID, list, overwrite); + io.to(socket.userID).emit("importantHeartbeatList", monitorID, result, overwrite); } else { - socket.emit("importantHeartbeatList", monitorID, list, overwrite); + socket.emit("importantHeartbeatList", monitorID, result, overwrite); } } diff --git a/server/model/heartbeat.js b/server/model/heartbeat.js index d023571db..f7c036a2d 100644 --- a/server/model/heartbeat.js +++ b/server/model/heartbeat.js @@ -1,4 +1,5 @@ const { BeanModel } = require("redbean-node/dist/bean-model"); +const zlib = require("node:zlib"); /** * status: @@ -36,9 +37,26 @@ class Heartbeat extends BeanModel { important: this._important, duration: this._duration, retries: this._retries, - response: this._response, + response: Heartbeat.decodeResponseValue(this._response), }; } + + /** + * Decode compressed response payload stored in database. + * @param {string|null} response Encoded response payload. + * @returns {string|null} Decoded response payload. + */ + static decodeResponseValue(response) { + if (!response) { + return response; + } + + try { + return zlib.gunzipSync(Buffer.from(response, "base64")).toString("utf8"); + } catch (error) { + return response; + } + } } module.exports = Heartbeat; diff --git a/server/model/monitor.js b/server/model/monitor.js index 1eaf5997e..5404a47b5 100644 --- a/server/model/monitor.js +++ b/server/model/monitor.js @@ -56,6 +56,7 @@ const { CookieJar } = require("tough-cookie"); const { HttpsCookieAgent } = require("http-cookie-agent/http"); const https = require("https"); const http = require("http"); +const zlib = require("node:zlib"); const DomainExpiry = require("./domain_expiry"); const rootCertificates = rootCertificatesFingerprints(); @@ -1149,7 +1150,7 @@ class Monitor extends BeanModel { responseData = responseData.substring(0, maxSize) + "... (truncated)"; } - bean.response = responseData; + bean.response = zlib.gzipSync(Buffer.from(responseData, "utf8")).toString("base64"); } /** diff --git a/test/backend-test/test-monitor-response.js b/test/backend-test/test-monitor-response.js index 4e7dbb018..01a35e27b 100644 --- a/test/backend-test/test-monitor-response.js +++ b/test/backend-test/test-monitor-response.js @@ -1,6 +1,7 @@ const { describe, test } = require("node:test"); const assert = require("node:assert"); const Monitor = require("../../server/model/monitor"); +const Heartbeat = require("../../server/model/heartbeat"); describe("Monitor response saving", () => { test("getSaveResponse and getSaveErrorResponse parse booleans", () => { @@ -19,7 +20,7 @@ describe("Monitor response saving", () => { const bean = {}; monitor.saveResponseData(bean, "abcdef"); - assert.strictEqual(bean.response, "abcde... (truncated)"); + assert.strictEqual(Heartbeat.decodeResponseValue(bean.response), "abcde... (truncated)"); }); test("saveResponseData stringifies objects", () => { @@ -29,6 +30,6 @@ describe("Monitor response saving", () => { const bean = {}; monitor.saveResponseData(bean, { ok: true }); - assert.strictEqual(bean.response, JSON.stringify({ ok: true })); + assert.strictEqual(Heartbeat.decodeResponseValue(bean.response), JSON.stringify({ ok: true })); }); });