diff --git a/agent/app/dto/response/nginx.go b/agent/app/dto/response/nginx.go
index 73468c339..649259eb3 100644
--- a/agent/app/dto/response/nginx.go
+++ b/agent/app/dto/response/nginx.go
@@ -20,11 +20,15 @@ type NginxParam struct {
// NginxBrotliRes carries the brotli settings together with where they live.
// ManagedExternally is true when the user defined brotli by hand, in which
// case the panel only reports the values and must not write its own copy.
-// ManagedUnavailable is true when the panel could not wire the managed
+// ManagedPending is true when nginx does not load the managed configuration
+// yet but saving will wire it in, so the reported values are not in effect
+// until then.
+// ManagedUnavailable is true when the panel cannot wire the managed
// configuration into nginx.conf at all, so the reported values are inert.
type NginxBrotliRes struct {
Params []NginxParam `json:"params"`
ManagedExternally bool `json:"managedExternally"`
+ ManagedPending bool `json:"managedPending"`
ManagedUnavailable bool `json:"managedUnavailable"`
}
diff --git a/agent/app/service/nginx_http_config.go b/agent/app/service/nginx_http_config.go
index f6474f9f7..6413bbc1a 100644
--- a/agent/app/service/nginx_http_config.go
+++ b/agent/app/service/nginx_http_config.go
@@ -45,6 +45,10 @@ var (
// nginxHTTPBlockStartRe locates the http block opening, the fallback
// insertion point, and captures its indentation.
nginxHTTPBlockStartRe = regexp.MustCompile(`(?m)^([ \t]*)http[ \t]*\{[ \t]*\r?$`)
+
+ // errNginxHTTPIncludeNoInsertionPoint tells a config the panel cannot edit
+ // safely apart from an I/O failure while editing it.
+ errNginxHTTPIncludeNoInsertionPoint = errors.New("no insertion point for the http.d include in nginx.conf")
)
// nginxHTTPIncludePresent reports whether nginx.conf already loads http.d.
@@ -96,7 +100,19 @@ func insertNginxHTTPInclude(content string) (string, error) {
indent := content[m[2]:m[3]] + " "
return content[:m[1]] + eol + indent + nginxHTTPIncludeDirective + content[m[1]:], nil
}
- return "", errors.New("no insertion point for the http.d include in nginx.conf")
+ return "", errNginxHTTPIncludeNoInsertionPoint
+}
+
+// nginxHTTPIncludeInsertable reports whether nginx.conf already loads http.d
+// or the include can be added automatically. Nothing is written: the
+// insertion is computed in memory and discarded.
+func nginxHTTPIncludeInsertable(install model.AppInstall) bool {
+ content, err := os.ReadFile(nginxMainConfigPath(install))
+ if err != nil {
+ return false
+ }
+ _, err = insertNginxHTTPInclude(string(content))
+ return err == nil
}
// ensureNginxHTTPIncludeActive makes nginx.conf load http.d, inserting the
diff --git a/agent/app/service/nginx_http_config_test.go b/agent/app/service/nginx_http_config_test.go
index 1071b4dfc..5726048cd 100644
--- a/agent/app/service/nginx_http_config_test.go
+++ b/agent/app/service/nginx_http_config_test.go
@@ -1,6 +1,7 @@
package service
import (
+ "errors"
"strings"
"testing"
)
@@ -83,9 +84,15 @@ func TestInsertNginxHTTPIncludeFallsBackToHTTPBlock(t *testing.T) {
}
func TestInsertNginxHTTPIncludeRejectsConfigWithoutHTTPBlock(t *testing.T) {
- if _, err := insertNginxHTTPInclude("events {}\n"); err == nil {
+ _, err := insertNginxHTTPInclude("events {}\n")
+ if err == nil {
t.Fatal("a config without an http block must be rejected so callers can degrade")
}
+ // The save path maps this error to an actionable message and must be able
+ // to tell it apart from an I/O failure.
+ if !errors.Is(err, errNginxHTTPIncludeNoInsertionPoint) {
+ t.Fatalf("unexpected error: %v", err)
+ }
}
func TestInsertNginxHTTPIncludeIgnoresCommentedIncludes(t *testing.T) {
diff --git a/agent/app/service/nginx_module_runtime.go b/agent/app/service/nginx_module_runtime.go
index ad4ff6957..c001ba4f9 100644
--- a/agent/app/service/nginx_module_runtime.go
+++ b/agent/app/service/nginx_module_runtime.go
@@ -224,12 +224,9 @@ func getNginxBrotliParams() (*response.NginxBrotliRes, error) {
fileName := nginxHTTPConfigFileName(nginxModuleRuntimeOrder(nginxBrotliModuleName), nginxBrotliModuleName)
current = readNginxHTTPDirectives(path.Join(nginxHTTPConfigDir(install), fileName))
}
- res := &response.NginxBrotliRes{
- ManagedExternally: managedExternally,
- // Without the include, values the panel would write would never reach
- // nginx, so they are reported as unavailable rather than shown as if
- // they were in effect.
- ManagedUnavailable: !managedExternally && !nginxHTTPIncludePresent(install),
+ res := &response.NginxBrotliRes{ManagedExternally: managedExternally}
+ if !managedExternally {
+ res.ManagedPending, res.ManagedUnavailable = nginxBrotliManagedState(install)
}
for _, directive := range mergeNginxRuntimeDirectives(nginxModuleRuntimeDefaults[nginxBrotliModuleName], current) {
res.Params = append(res.Params, response.NginxParam{Name: directive.Name, Params: directive.Params})
@@ -237,6 +234,28 @@ func getNginxBrotliParams() (*response.NginxBrotliRes, error) {
return res, nil
}
+// nginxBrotliManagedState reports whether the managed brotli file is missing
+// from what nginx loads, and if so whether saving from the settings page can
+// fix that. Either way the reported values are not in effect, so they must
+// not be presented as if they were.
+//
+// A missing include is the common case for installs that enabled brotli
+// before the panel managed its directives, and the save path inserts it. Only
+// a config without a safe insertion point is reported as unavailable.
+func nginxBrotliManagedState(install model.AppInstall) (pending, unavailable bool) {
+ if !nginxHTTPIncludePresent(install) {
+ if nginxHTTPIncludeInsertable(install) {
+ return true, false
+ }
+ return false, true
+ }
+ fileName := nginxHTTPConfigFileName(nginxModuleRuntimeOrder(nginxBrotliModuleName), nginxBrotliModuleName)
+ if _, err := os.Stat(path.Join(nginxHTTPConfigDir(install), fileName)); os.IsNotExist(err) {
+ return true, false
+ }
+ return false, false
+}
+
// readNginxUserBrotliDirectives collects the brotli directives the user wrote
// in any of the files nginx loads them from.
func readNginxUserBrotliDirectives(install model.AppInstall) map[string][]string {
@@ -313,26 +332,19 @@ func updateNginxBrotliParams(params []dto.NginxParam) error {
return updateUserNginxBrotliParams(install, values)
}
// A managed write needs the include. Installations missing it are
- // upgraded in place here; when nginx.conf cannot be edited safely the
- // write is refused with an actionable error instead of writing values
- // nginx would never load.
- if !nginxHTTPIncludePresent(install) {
- configPath := nginxMainConfigPath(install)
- content, readErr := os.ReadFile(configPath)
- if readErr != nil {
- return readErr
- }
- updated, insErr := insertNginxHTTPInclude(string(content))
- if insErr != nil {
+ // upgraded in place here, through the same path that enabling the
+ // module takes; when nginx.conf cannot be edited safely the write is
+ // refused with an actionable error instead of writing values nginx
+ // would never load.
+ _, confSnapshot, includeErr := ensureNginxHTTPIncludeActive(install)
+ if includeErr != nil {
+ if errors.Is(includeErr, errNginxHTTPIncludeNoInsertionPoint) {
return buserr.New("ErrBrotliUnsupported")
}
- if err = writeNginxFileAtomic(configPath, []byte(updated)); err != nil {
- return err
- }
- if err = os.MkdirAll(nginxHTTPConfigDir(install), constant.DirPerm); err != nil {
- return err
- }
- if err = nginxCheckAndReload(string(content), configPath, install.ContainerName); err != nil {
+ return includeErr
+ }
+ if confSnapshot != nil {
+ if err = nginxCheckAndReload(string(confSnapshot), nginxMainConfigPath(install), install.ContainerName); err != nil {
return err
}
}
diff --git a/agent/app/service/nginx_module_runtime_test.go b/agent/app/service/nginx_module_runtime_test.go
index 8be49c973..94614ee01 100644
--- a/agent/app/service/nginx_module_runtime_test.go
+++ b/agent/app/service/nginx_module_runtime_test.go
@@ -229,3 +229,85 @@ func TestValidateNginxBrotliValues(t *testing.T) {
}
}
}
+
+// newBrotliStateInstall lays out an OpenResty install whose nginx.conf holds
+// conf, or that has no nginx.conf at all when conf is empty.
+func newBrotliStateInstall(t *testing.T, conf string) model.AppInstall {
+ t.Helper()
+ installRoot := t.TempDir()
+ confDir := path.Join(installRoot, "openresty", "openresty", "conf")
+ if err := os.MkdirAll(confDir, 0o755); err != nil {
+ t.Fatal(err)
+ }
+ if conf != "" {
+ if err := os.WriteFile(path.Join(confDir, "nginx.conf"), []byte(conf), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ }
+ previous := global.Dir.AppInstallDir
+ global.Dir.AppInstallDir = installRoot
+ t.Cleanup(func() { global.Dir.AppInstallDir = previous })
+ install := model.AppInstall{Name: "openresty"}
+ install.App.Key = constant.AppOpenresty
+ return install
+}
+
+// Installs that enabled brotli before the panel managed its directives have
+// no http.d include. Saving inserts it, so the settings page must report the
+// values as pending rather than as something the panel can never apply.
+func TestNginxBrotliManagedState(t *testing.T) {
+ withInclude, err := insertNginxHTTPInclude(plainNginxConf)
+ if err != nil {
+ t.Fatal(err)
+ }
+ managedFile := nginxHTTPConfigFileName(nginxModuleRuntimeOrder(nginxBrotliModuleName), nginxBrotliModuleName)
+ cases := []struct {
+ name string
+ conf string
+ managedFile bool
+ wantPending bool
+ wantUnavailable bool
+ }{
+ {"include missing but insertable", plainNginxConf, false, true, false},
+ {"no insertion point", "events {}\n", false, false, true},
+ {"nginx.conf unreadable", "", false, false, true},
+ {"include present, managed file missing", withInclude, false, true, false},
+ {"include present and managed file written", withInclude, true, false, false},
+ }
+ for _, tc := range cases {
+ t.Run(tc.name, func(t *testing.T) {
+ install := newBrotliStateInstall(t, tc.conf)
+ if tc.managedFile {
+ configDir := nginxHTTPConfigDir(install)
+ if err := os.MkdirAll(configDir, 0o755); err != nil {
+ t.Fatal(err)
+ }
+ if err := os.WriteFile(path.Join(configDir, managedFile), []byte("brotli on;\n"), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ }
+ pending, unavailable := nginxBrotliManagedState(install)
+ if pending != tc.wantPending || unavailable != tc.wantUnavailable {
+ t.Fatalf("expected pending=%v unavailable=%v, got pending=%v unavailable=%v",
+ tc.wantPending, tc.wantUnavailable, pending, unavailable)
+ }
+ })
+ }
+}
+
+// The state is computed on every visit to the settings page; only an explicit
+// save may change the configuration.
+func TestNginxBrotliManagedStateDoesNotWrite(t *testing.T) {
+ install := newBrotliStateInstall(t, plainNginxConf)
+ nginxBrotliManagedState(install)
+ content, err := os.ReadFile(nginxMainConfigPath(install))
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(content) != plainNginxConf {
+ t.Fatal("checking the state must not edit nginx.conf")
+ }
+ if _, err := os.Stat(nginxHTTPConfigDir(install)); !os.IsNotExist(err) {
+ t.Fatal("checking the state must not create the http.d directory")
+ }
+}
diff --git a/frontend/src/api/interface/nginx.ts b/frontend/src/api/interface/nginx.ts
index c2d08b967..f02a6f35a 100644
--- a/frontend/src/api/interface/nginx.ts
+++ b/frontend/src/api/interface/nginx.ts
@@ -10,6 +10,7 @@ export namespace Nginx {
export interface NginxBrotliRes {
params: NginxParam[];
managedExternally: boolean;
+ managedPending: boolean;
managedUnavailable: boolean;
}
diff --git a/frontend/src/lang/modules/en.ts b/frontend/src/lang/modules/en.ts
index c88f78a2f..9ed13b34e 100644
--- a/frontend/src/lang/modules/en.ts
+++ b/frontend/src/lang/modules/en.ts
@@ -4591,6 +4591,7 @@ const message = {
brotliCompLevelHelper: 'Brotli compression rate, 0 to 11',
brotliManagedExternallyHelper:
'Brotli is configured manually in nginx.conf; the panel shows the values in effect and will not overwrite them.',
+ brotliManagedPendingHelper: 'Brotli settings are not in effect yet; they take effect after you save.',
brotliManagedUnavailableHelper:
'The panel could not add the managed brotli configuration to nginx.conf automatically; the values below will not take effect.',
brotliMinLengthHelper: 'Minimum response size to brotli-compress',
diff --git a/frontend/src/lang/modules/es-es.ts b/frontend/src/lang/modules/es-es.ts
index 736bca55e..790ead4a3 100644
--- a/frontend/src/lang/modules/es-es.ts
+++ b/frontend/src/lang/modules/es-es.ts
@@ -4650,6 +4650,7 @@ const message = {
brotliCompLevelHelper: 'Tasa de compresión brotli, de 0 a 11',
brotliManagedExternallyHelper:
'Brotli está configurado manualmente en nginx.conf; el panel muestra los valores en vigor y no los sobrescribe.',
+ brotliManagedPendingHelper: 'La configuración de brotli aún no está en vigor; se aplicará al guardar.',
brotliManagedUnavailableHelper:
'El panel no pudo añadir automáticamente la configuración brotli gestionada a nginx.conf; los valores siguientes no tendrán efecto.',
brotliMinLengthHelper: 'Tamaño mínimo de respuesta para comprimir con brotli',
diff --git a/frontend/src/lang/modules/fa.ts b/frontend/src/lang/modules/fa.ts
index 4e24d7856..031552165 100644
--- a/frontend/src/lang/modules/fa.ts
+++ b/frontend/src/lang/modules/fa.ts
@@ -4553,6 +4553,7 @@ const message = {
brotliCompLevelHelper: 'نرخ فشردهسازی brotli، از 0 تا 11',
brotliManagedExternallyHelper:
'brotli بهصورت دستی در nginx.conf پیکربندی شده است؛ پنل فقط مقادیر در حال اجرا را نشان میدهد و آنها را بازنویسی نمیکند.',
+ brotliManagedPendingHelper: 'تنظیمات brotli هنوز اعمال نشده است؛ پس از ذخیره اعمال میشود.',
brotliManagedUnavailableHelper:
'پنل نتوانست پیکربندی مدیریتشده brotli را بهصورت خودکار به nginx.conf اضافه کند؛ مقادیر زیر اعمال نخواهند شد.',
brotliMinLengthHelper: 'حداقل اندازه پاسخ برای فشردهسازی با brotli',
diff --git a/frontend/src/lang/modules/ja.ts b/frontend/src/lang/modules/ja.ts
index 3eb926db3..41c347494 100644
--- a/frontend/src/lang/modules/ja.ts
+++ b/frontend/src/lang/modules/ja.ts
@@ -4574,6 +4574,7 @@ const message = {
brotliCompLevelHelper: 'brotli 圧縮率、0 から 11',
brotliManagedExternallyHelper:
'brotli は nginx.conf で手動設定されています。パネルは現在の有効な値を表示するだけで、上書きしません。',
+ brotliManagedPendingHelper: 'brotli 設定はまだ有効になっていません。保存すると有効になります。',
brotliManagedUnavailableHelper:
'パネルは管理対象の brotli 設定を nginx.conf に自動で追加できませんでした。以下の設定は有効になりません。',
brotliMinLengthHelper: 'brotli で圧縮する最小レスポンスサイズ',
diff --git a/frontend/src/lang/modules/ko.ts b/frontend/src/lang/modules/ko.ts
index c3ecd596d..cd2d2b190 100644
--- a/frontend/src/lang/modules/ko.ts
+++ b/frontend/src/lang/modules/ko.ts
@@ -4492,6 +4492,7 @@ const message = {
brotliCompLevelHelper: 'brotli 압축률, 0에서 11까지',
brotliManagedExternallyHelper:
'brotli가 nginx.conf에 수동으로 구성되어 있습니다. 패널은 적용 중인 값만 표시하며 덮어쓰지 않습니다.',
+ brotliManagedPendingHelper: 'brotli 설정이 아직 적용되지 않았습니다. 저장하면 적용됩니다.',
brotliManagedUnavailableHelper:
'패널이 관리되는 brotli 구성을 nginx.conf에 자동으로 추가할 수 없습니다. 아래 설정은 적용되지 않습니다.',
brotliMinLengthHelper: 'brotli로 압축할 최소 응답 크기',
diff --git a/frontend/src/lang/modules/lo.ts b/frontend/src/lang/modules/lo.ts
index ba6d05677..40915108d 100644
--- a/frontend/src/lang/modules/lo.ts
+++ b/frontend/src/lang/modules/lo.ts
@@ -4465,6 +4465,7 @@ const message = {
brotliCompLevelHelper: 'ອັດຕາການບີບອັດ brotli, 0 ຫາ 11',
brotliManagedExternallyHelper:
'brotli ຖືກຕັ້ງຄ່າດ້ວຍມືໃນ nginx.conf; ແຜງຄວບຄຸມຈະສະແດງຄ່າທີ່ກຳລັງໃຊ້ຢູ່ ແລະ ຈະບໍ່ຂຽບທັບ.',
+ brotliManagedPendingHelper: 'ການຕັ້ງຄ່າ brotli ຍັງບໍ່ມີຜົນ; ຈະມີຜົນຫຼັງຈາກບັນທຶກ.',
brotliManagedUnavailableHelper:
'ແຜງຄວບຄຸມບໍ່ສາມາດເພີ່ມການຕັ້ງຄ່າ brotli ທີ່ຈັດການໄປຍັງ nginx.conf ໂດຍອັດຕະໂນມັດໄດ້; ຄ່າຂ້າງລຸ່ມນີ້ຈະບໍ່ມີຜົນ.',
brotliMinLengthHelper: 'ຂະໜາດຕອບສະໜອງຂັ້ນຕ່ຳທີ່ຈະບີບອັດດ້ວຍ brotli',
diff --git a/frontend/src/lang/modules/ms.ts b/frontend/src/lang/modules/ms.ts
index 17bb7cd39..1bd6de626 100644
--- a/frontend/src/lang/modules/ms.ts
+++ b/frontend/src/lang/modules/ms.ts
@@ -4659,6 +4659,7 @@ const message = {
brotliCompLevelHelper: 'Kadar pemampatan brotli, 0 hingga 11',
brotliManagedExternallyHelper:
'Brotli dikonfigurasikan secara manual dalam nginx.conf; panel memaparkan nilai yang berkuat kuasa dan tidak akan menimpanya.',
+ brotliManagedPendingHelper: 'Tetapan brotli belum berkuat kuasa; ia akan berkuat kuasa selepas disimpan.',
brotliManagedUnavailableHelper:
'Panel tidak dapat menambahkan konfigurasi brotli terurus ke nginx.conf secara automatik; nilai di bawah tidak akan berkuat kuasa.',
brotliMinLengthHelper: 'Saiz respons minimum untuk dimampatkan dengan brotli',
diff --git a/frontend/src/lang/modules/pt-br.ts b/frontend/src/lang/modules/pt-br.ts
index 7b421c348..38da9dd51 100644
--- a/frontend/src/lang/modules/pt-br.ts
+++ b/frontend/src/lang/modules/pt-br.ts
@@ -4678,6 +4678,7 @@ const message = {
brotliCompLevelHelper: 'Taxa de compressão brotli, de 0 a 11',
brotliManagedExternallyHelper:
'O brotli está configurado manualmente no nginx.conf; o painel mostra os valores em vigor e não os sobrescreve.',
+ brotliManagedPendingHelper: 'As configurações brotli ainda não estão em vigor; serão aplicadas ao salvar.',
brotliManagedUnavailableHelper:
'O painel não conseguiu adicionar automaticamente a configuração brotli gerenciada ao nginx.conf; os valores abaixo não terão efeito.',
brotliMinLengthHelper: 'Tamanho mínimo da resposta para compressão brotli',
diff --git a/frontend/src/lang/modules/ru.ts b/frontend/src/lang/modules/ru.ts
index af750ce03..a204355f9 100644
--- a/frontend/src/lang/modules/ru.ts
+++ b/frontend/src/lang/modules/ru.ts
@@ -4649,6 +4649,7 @@ const message = {
brotliCompLevelHelper: 'Степень сжатия brotli, от 0 до 11',
brotliManagedExternallyHelper:
'Brotli настроен вручную в nginx.conf; панель показывает действующие значения и не перезаписывает их.',
+ brotliManagedPendingHelper: 'Настройки brotli ещё не действуют; они вступят в силу после сохранения.',
brotliManagedUnavailableHelper:
'Панель не смогла автоматически добавить управляемую конфигурацию brotli в nginx.conf; значения ниже не вступят в силу.',
brotliMinLengthHelper: 'Минимальный размер ответа для сжатия brotli',
diff --git a/frontend/src/lang/modules/tr.ts b/frontend/src/lang/modules/tr.ts
index 0980d1d2f..9c261cb86 100644
--- a/frontend/src/lang/modules/tr.ts
+++ b/frontend/src/lang/modules/tr.ts
@@ -4664,6 +4664,7 @@ const message = {
brotliCompLevelHelper: 'Brotli sıkıştırma oranı, 0 ile 11 arası',
brotliManagedExternallyHelper:
'Brotli, nginx.conf dosyasında elle yapılandırıldı; panel yalnızca geçerli değerleri gösterir ve üzerine yazmaz.',
+ brotliManagedPendingHelper: 'Brotli ayarları henüz etkin değil; kaydettikten sonra etkinleşir.',
brotliManagedUnavailableHelper:
'Panel, yönetilen brotli yapılandırmasını nginx.conf dosyasına otomatik olarak ekleyemedi; aşağıdaki değerler etkin olmayacak.',
brotliMinLengthHelper: 'brotli ile sıkıştırılacak minimum yanıt boyutu',
diff --git a/frontend/src/lang/modules/zh-Hant.ts b/frontend/src/lang/modules/zh-Hant.ts
index 2534135db..1da913a9b 100644
--- a/frontend/src/lang/modules/zh-Hant.ts
+++ b/frontend/src/lang/modules/zh-Hant.ts
@@ -4292,6 +4292,7 @@ const message = {
brotliHelper: '開啟 brotli 壓縮,通常比 gzip 體積更小',
brotliCompLevelHelper: 'brotli 壓縮率,取值 0 到 11',
brotliManagedExternallyHelper: 'brotli 已在 nginx.conf 中手動設定,面板僅顯示目前生效值,不會覆寫。',
+ brotliManagedPendingHelper: 'brotli 設定尚未生效,點擊儲存後生效。',
brotliManagedUnavailableHelper: '面板無法自動向 nginx.conf 寫入託管的 brotli 設定,以下設定不會生效。',
brotliMinLengthHelper: 'brotli 壓縮的最小回應大小',
brotliSaveFailed: 'brotli 設定儲存失敗,上方的 gzip 設定已套用',
diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts
index eb3686edd..cfc4729d9 100644
--- a/frontend/src/lang/modules/zh.ts
+++ b/frontend/src/lang/modules/zh.ts
@@ -4332,6 +4332,7 @@ const message = {
brotliHelper: '开启 brotli 压缩,通常比 gzip 体积更小',
brotliCompLevelHelper: 'brotli 压缩率,取值 0 到 11',
brotliManagedExternallyHelper: 'brotli 已在 nginx.conf 中手动配置,面板仅显示当前生效值,不会覆盖。',
+ brotliManagedPendingHelper: 'brotli 配置尚未生效,点击保存后生效。',
brotliManagedUnavailableHelper: '面板无法自动向 nginx.conf 写入托管的 brotli 配置,以下设置不会生效。',
brotliMinLengthHelper: 'brotli 压缩的最小响应大小',
brotliSaveFailed: 'brotli 设置保存失败,上方的 gzip 设置已应用',
diff --git a/frontend/src/views/website/website/nginx/performance/index.vue b/frontend/src/views/website/website/nginx/performance/index.vue
index 98a0074d8..cabeaf45b 100644
--- a/frontend/src/views/website/website/nginx/performance/index.vue
+++ b/frontend/src/views/website/website/nginx/performance/index.vue
@@ -54,6 +54,11 @@
{{ $t('nginx.brotliManagedExternallyHelper') }}
+
+
+ {{ $t('nginx.brotliManagedPendingHelper') }}
+
+
{{ $t('nginx.brotliManagedUnavailableHelper') }}
@@ -127,6 +132,8 @@ let loading = ref(false);
// disappear together with the module.
const brotliAvailable = ref(false);
const brotliManagedExternally = ref(false);
+// Pending: nginx does not load the managed file yet, and saving wires it in.
+const brotliManagedPending = ref(false);
const brotliManagedUnavailable = ref(false);
const variablesRules = reactive({
@@ -201,6 +208,7 @@ const getBrotliParams = async () => {
}
const res = await getNginxConfigByScope({ scope: 'brotli' });
brotliManagedExternally.value = !!res.data?.managedExternally;
+ brotliManagedPending.value = !!res.data?.managedPending;
brotliManagedUnavailable.value = !!res.data?.managedUnavailable;
for (const param of res.data?.params ?? []) {
if (param.params.length === 0) {