Кабинет: страницы собирает ядро, на хостинге — ретранслятор (Go и PHP)

- modules/lk: конверт запроса/ответа (PageRequest/PageResponse), ServeEnvelope — тот же
  обработчик страниц внутри ядра; клиент к API внутри процесса (Config.Local/LocalKey);
  режим ретранслятора (Config.Relay, BJ_RENDER=core, выбор в установщике и lk.json)
- ядро: встроенный кабинет (lkcabinet.go), POST /api/lk/render для прямого режима,
  цикл режима ожидания выполняет конверты страниц; API через ретранслятор недостижимо
- PHP-ретранслятор для обычного хостинга (modules/lk/relay-php: index.php, .htaccess,
  README): установщик в браузере, прямой режим через curl, режим ожидания через очередь
  в SQLite (BEGIN IMMEDIATE, busy_timeout), конфиг в bj-lk-data рядом с сайтом или в
  data под .htaccess; архив со страницы настроек (/admin/setup/lk/relay-php.zip)
- настройки: карточка НПР/УДС перенесена из раздела «Лицензия» в «Экспорт QUIK»;
  кнопка «Обновить с сервера лицензий» видна при любом ключе
- инструкция /admin/help/lk: два варианта размещения, шаги для PHP-хостинга
- тесты: TestLKRelayRendersInCore (оба режима), TestLKPHPRelayAgentMode (настоящий PHP
  против цикла ядра, PHP_BIN), проверка безопасности через PHP-ретранслятор 34/34

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Q4YVo4UMopqT5DzicqpPjL
This commit is contained in:
zuevav
2026-09-18 11:15:29 +03:00
parent f51414269d
commit 054222d154
19 changed files with 1403 additions and 97 deletions
+26
View File
@@ -9,6 +9,7 @@ package lkgateway
import (
"archive/tar"
"archive/zip"
"compress/gzip"
"crypto/rand"
"encoding/hex"
@@ -17,6 +18,8 @@ import (
"os"
"strings"
"time"
"git.zetit.ru/zuevav/Bridge-and-Join-s/modules/lk"
)
// lkDistBinary — где лежит исполняемый файл кабинета на этом сервере (переменная — для тестов).
@@ -332,3 +335,26 @@ func cabinetHint(s Settings) string {
}
return "https://lk.example.ru"
}
// lkPHPRelayDownload — GET /admin/setup/lk/relay-php.zip: ретранслятор для обычного
// PHP-хостинга. Ключа в архиве нет — его спрашивает установщик в браузере.
func (h *setupHandlers) lkPHPRelayDownload(w http.ResponseWriter, r *http.Request) {
files := lk.PHPRelayFiles()
if len(files) == 0 {
setupFlash(w, r, "Ретранслятор PHP не собран в эту версию ядра")
return
}
w.Header().Set("Content-Type", "application/zip")
w.Header().Set("Content-Disposition", `attachment; filename="bj-lk-php-`+time.Now().Format("2006-01-02")+`.zip"`)
zw := zip.NewWriter(w)
defer zw.Close()
for _, name := range []string{"index.php", ".htaccess", "README.txt"} {
fw, err := zw.CreateHeader(&zip.FileHeader{Name: "bj-lk-php/" + name, Method: zip.Deflate, Modified: time.Now()})
if err != nil {
return
}
if _, err := fw.Write(files[name]); err != nil {
return
}
}
}