From 31bb442b0cc4a57277f925d96173439ce91403d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0=20Sonic?= Date: Mon, 26 Oct 2026 18:17:04 +0000 Subject: [PATCH] fix(worker): name the published script version in the browser check (#72) The dashboard editor shows a saved draft while requests are served by the last deployed version. A user with the new text in the editor was running the pre-beta.15 script, which writes Blob frames into the socket on current compatibility dates (Cloudflare warns "This TransformStream is being used as a byte stream ...") and drops every tunnel (#53). Reproduced on local workerd: the old script logs exactly that warning, the current one does not. GET /apiws now answers "TGLock Worker " and X-TGLock-Worker, and the docs say a missing line means an old script is still deployed. Co-authored-by: babin Co-authored-by: Claude Opus 5.5 --- docs/CLOUDFLARE_WORKER.md | 4 +++- worker/tglock-worker.js | 11 ++++++++++- worker/tglock-worker.test.js | 6 +++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/docs/CLOUDFLARE_WORKER.md b/docs/CLOUDFLARE_WORKER.md index 9cbacba..b01a069 100644 --- a/docs/CLOUDFLARE_WORKER.md +++ b/docs/CLOUDFLARE_WORKER.md @@ -37,7 +37,9 @@ ### Проверка, что воркер жив -Открой в браузере `https://tglock.имя.workers.dev/apiws`. Должно вернуться `expected a websocket upgrade` (HTTP 426). Это проверяет только публикацию скрипта. Соединение Worker → Telegram обычный GET **не проверяет**. +Открой в браузере `https://tglock.имя.workers.dev/apiws`. Должно вернуться `expected a websocket upgrade` (HTTP 426) и строка `TGLock Worker 2026-10-26` с датой версии скрипта. Это проверяет только публикацию скрипта. Соединение Worker → Telegram обычный GET **не проверяет**. + +**Строки с версией нет — работает старый скрипт**, даже если в редакторе Cloudflare открыт новый текст. Редактор показывает черновик, а запросы обслуживает последняя *опубликованная* версия: после правки нужно нажать **Deploy**. Старый скрипт на новых compatibility date рвёт каждый туннель; в журнале Worker'а это предупреждение `This TransformStream is being used as a byte stream, but received an object of non-ArrayBuffer/ArrayBufferView type`, в журнале TGLock — `WebSocket закрыт без ответа Telegram`. Если вернулось `not found` — проверь, что путь именно `/apiws`. Если ошибка про `cloudflare:sockets` — у воркера слишком старая дата совместимости, поставь в **Settings → Compatibility date** сегодняшнюю. diff --git a/worker/tglock-worker.js b/worker/tglock-worker.js index 2365d18..c6fd77e 100644 --- a/worker/tglock-worker.js +++ b/worker/tglock-worker.js @@ -34,6 +34,12 @@ const CONNECT_TIMEOUT_MS = 3000; const MAX_PENDING_BYTES = 1024 * 1024; const MAX_PENDING_MESSAGES = 256; +// Видна в ответе на проверку из браузера (/apiws без WebSocket). Редактор +// Cloudflare показывает сохранённый черновик, а работает опубликованная +// версия: без этой строки старый скрипт за новым текстом в редакторе было не +// отличить (by-sonic/tglock#53). Меняется при каждом изменении скрипта. +const WORKER_VERSION = "2026-10-26"; + // Размер бинарного кадра и способ достать его байты; null — текстовый кадр. // // С compatibility date 2026-03-17 бинарные кадры приходят как Blob, если @@ -68,7 +74,10 @@ export default { return new Response("not found", { status: 404 }); } if (request.headers.get("Upgrade")?.toLowerCase() !== "websocket") { - return new Response("expected a websocket upgrade", { status: 426 }); + return new Response(`expected a websocket upgrade\nTGLock Worker ${WORKER_VERSION}\n`, { + status: 426, + headers: { "X-TGLock-Worker": WORKER_VERSION }, + }); } // Необязательный общий секрет: задай переменную TGLOCK_TOKEN в настройках // воркера, и посторонние подключиться не смогут. diff --git a/worker/tglock-worker.test.js b/worker/tglock-worker.test.js index 0bbdb1a..71c523a 100644 --- a/worker/tglock-worker.test.js +++ b/worker/tglock-worker.test.js @@ -77,7 +77,11 @@ async function fixture({ opened = Promise.resolve(), write, timeout = false } = test("HTTP deployment check does not claim Telegram connectivity", async () => { const f = await fixture(); - assert.equal((await f.fetch("/apiws", { Upgrade: "" })).status, 426); + const check = await f.fetch("/apiws", { Upgrade: "" }); + assert.equal(check.status, 426); + // The browser check names the published version (#53). + assert.match(check.body, /^expected a websocket upgrade\nTGLock Worker \d{4}-\d{2}-\d{2}\n$/); + assert.match(check.headers["X-TGLock-Worker"], /^\d{4}-\d{2}-\d{2}$/); assert.equal(f.state.connects, 0); });