Кабинет: страницы собирает ядро, на хостинге — ретранслятор (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:
+17
-5
@@ -29,10 +29,11 @@ const configFileName = "lk.json"
|
||||
|
||||
// fileConfig — что лежит в lk.json. Ключ — секрет, поэтому файл 0600.
|
||||
type fileConfig struct {
|
||||
Mode string `json:"mode"` // direct | agent
|
||||
BJURL string `json:"bj_url,omitempty"`
|
||||
BJKey string `json:"bj_key"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Mode string `json:"mode"` // direct | agent — как связываемся с ядром
|
||||
Render string `json:"render,omitempty"` // core | local — где собираются страницы
|
||||
BJURL string `json:"bj_url,omitempty"`
|
||||
BJKey string `json:"bj_key"`
|
||||
Title string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
// DefaultDataDir — каталог данных по умолчанию: data рядом с программой.
|
||||
@@ -73,6 +74,9 @@ func LoadConfigFile(dataDir string, cfg Config) (Config, error) {
|
||||
if !cfg.Agent && os.Getenv("BJ_MODE") == "" {
|
||||
cfg.Agent = f.Mode == "agent"
|
||||
}
|
||||
if !cfg.Relay && os.Getenv("BJ_RENDER") == "" {
|
||||
cfg.Relay = f.Render == "core"
|
||||
}
|
||||
return cfg, nil
|
||||
}
|
||||
|
||||
@@ -81,10 +85,13 @@ func saveConfigFile(dataDir string, cfg Config) error {
|
||||
if err := os.MkdirAll(dataDir, 0o700); err != nil {
|
||||
return fmt.Errorf("каталог данных %s: %v", dataDir, err)
|
||||
}
|
||||
f := fileConfig{Mode: "direct", BJURL: cfg.BJURL, BJKey: cfg.BJKey, Title: cfg.Title}
|
||||
f := fileConfig{Mode: "direct", Render: "local", BJURL: cfg.BJURL, BJKey: cfg.BJKey, Title: cfg.Title}
|
||||
if cfg.Agent {
|
||||
f.Mode, f.BJURL = "agent", ""
|
||||
}
|
||||
if cfg.Relay {
|
||||
f.Render = "core"
|
||||
}
|
||||
raw, _ := json.MarshalIndent(f, "", " ")
|
||||
tmp := filepath.Join(dataDir, configFileName+".tmp")
|
||||
if err := os.WriteFile(tmp, raw, 0o600); err != nil {
|
||||
@@ -155,6 +162,10 @@ type installData struct {
|
||||
// registerInstall — страницы установщика.
|
||||
func (s *Server) registerInstall(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/install", func(w http.ResponseWriter, r *http.Request) {
|
||||
if s.conf().Local != nil {
|
||||
http.NotFound(w, r) // внутри ядра установщика нет
|
||||
return
|
||||
}
|
||||
// Уже настроено: повторный вход в установщик — только удалением файла настроек.
|
||||
// Исключение — шаг «администратор», он идёт сразу после сохранения связи.
|
||||
if s.Configured() && !(r.Method == http.MethodPost && r.FormValue("step") == "admin") {
|
||||
@@ -199,6 +210,7 @@ func (s *Server) renderInstall(w http.ResponseWriter, r *http.Request, d install
|
||||
func (s *Server) installConnect(w http.ResponseWriter, r *http.Request, d installData) {
|
||||
cfg := d.Cfg
|
||||
cfg.Agent = r.FormValue("mode") == "agent"
|
||||
cfg.Relay = r.FormValue("render") == "core"
|
||||
cfg.BJURL = strings.TrimRight(strings.TrimSpace(r.FormValue("bj_url")), "/")
|
||||
cfg.BJKey = strings.TrimSpace(r.FormValue("bj_key"))
|
||||
cfg.Title = strings.TrimSpace(r.FormValue("title"))
|
||||
|
||||
Reference in New Issue
Block a user