diff --git a/frontend/package.json b/frontend/package.json
index 7c56f877..7d8be299 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,7 +1,7 @@
{
"name": "nginx-ui-frontend-next",
"private": true,
- "version": "1.7.3",
+ "version": "1.7.4",
"type": "commonjs",
"scripts": {
"dev": "vite",
diff --git a/frontend/src/api/ngx.ts b/frontend/src/api/ngx.ts
index 1d80b610..5a2e32e2 100644
--- a/frontend/src/api/ngx.ts
+++ b/frontend/src/api/ngx.ts
@@ -15,6 +15,10 @@ const ngx = {
reload() {
return http.post('/nginx/reload')
+ },
+
+ test() {
+ return http.post('/nginx/test')
}
}
diff --git a/frontend/src/language/en/app.po b/frontend/src/language/en/app.po
index 292dcf17..d9c0506c 100644
--- a/frontend/src/language/en/app.po
+++ b/frontend/src/language/en/app.po
@@ -105,9 +105,9 @@ msgstr "Auto-renewal disabled for %{name}"
msgid "Auto-renewal enabled for %{name}"
msgstr "Auto-renewal enabled for %{name}"
-#: src/views/config/Config.vue:16 src/views/config/Config.vue:17
-#: src/views/config/Config.vue:27 src/views/config/Config.vue:5
-#: src/views/config/ConfigEdit.vue:64 src/views/domain/DomainEdit.vue:222
+#: src/views/config/Config.vue:18 src/views/config/Config.vue:19
+#: src/views/config/Config.vue:29 src/views/config/Config.vue:7
+#: src/views/config/ConfigEdit.vue:72 src/views/domain/DomainEdit.vue:222
#: src/views/nginx_log/NginxLog.vue:173
msgid "Back"
msgstr "Back"
@@ -185,11 +185,15 @@ msgstr "Comments"
msgid "Config Templates"
msgstr "Configurations"
+#: src/views/config/InspectConfig.vue:3
+msgid "Configuration file is test successful"
+msgstr ""
+
#: src/views/domain/DomainAdd.vue:11
msgid "Configuration Name"
msgstr "Configuration Name"
-#: src/views/config/Config.vue:2
+#: src/views/config/Config.vue:4
msgid "Configurations"
msgstr "Configurations"
@@ -338,7 +342,7 @@ msgstr ""
msgid "Edit %{n}"
msgstr "Edit %{n}"
-#: src/routes/index.ts:81 src/views/config/ConfigEdit.vue:2
+#: src/routes/index.ts:81 src/views/config/ConfigEdit.vue:4
msgid "Edit Configuration"
msgstr "Edit Configuration"
@@ -379,6 +383,10 @@ msgstr "Enabled successfully"
msgid "Encrypt website with Let's Encrypt"
msgstr "Encrypt website with Let's Encrypt"
+#: src/views/config/InspectConfig.vue:17
+msgid "Error"
+msgstr ""
+
#: src/routes/index.ts:115 src/views/domain/ngx_conf/LogEntry.vue:68
msgid "Error Logs"
msgstr ""
@@ -431,16 +439,16 @@ msgstr ""
msgid "Finished"
msgstr "Finished"
-#: src/views/config/ConfigEdit.vue:67
+#: src/views/config/ConfigEdit.vue:75
msgid "Format Code"
msgstr ""
-#: src/views/config/ConfigEdit.vue:52
+#: src/views/config/ConfigEdit.vue:57
#, fuzzy
msgid "Format error %{msg}"
msgstr "Save error %{msg}"
-#: src/views/config/ConfigEdit.vue:50
+#: src/views/config/ConfigEdit.vue:55
#, fuzzy
msgid "Format successfully"
msgstr "Saved successfully"
@@ -477,6 +485,11 @@ msgstr ""
msgid "Initialing core upgrader"
msgstr ""
+#: src/views/config/InspectConfig.vue:2
+#, fuzzy
+msgid "Inspect Configurations"
+msgstr "Edit Configuration"
+
#: src/routes/index.ts:155 src/views/other/Install.vue:128
msgid "Install"
msgstr "Install"
@@ -778,7 +791,7 @@ msgstr ""
msgid "Run Mode"
msgstr "Advance Mode"
-#: src/views/config/ConfigEdit.vue:70 src/views/domain/DomainEdit.vue:225
+#: src/views/config/ConfigEdit.vue:78 src/views/domain/DomainEdit.vue:225
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
@@ -794,7 +807,7 @@ msgstr "Save"
msgid "Save Directive"
msgstr "Save Directive"
-#: src/views/config/ConfigEdit.vue:43 src/views/domain/DomainAdd.vue:55
+#: src/views/config/ConfigEdit.vue:46 src/views/domain/DomainAdd.vue:55
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37
msgid "Save error %{msg}"
msgstr "Save error %{msg}"
@@ -810,7 +823,7 @@ msgstr "Saved successfully"
msgid "Save Successfully"
msgstr "Saved successfully"
-#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainAdd.vue:44
+#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:44
#: src/views/domain/DomainEdit.vue:125
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35
msgid "Saved successfully"
@@ -828,7 +841,7 @@ msgstr "Send"
#: src/components/StdDataDisplay/StdTable.vue:168
#: src/components/StdDataDisplay/StdTable.vue:343
#: src/components/StdDataDisplay/StdTable.vue:463
-#: src/layouts/HeaderLayout.vue:26 src/views/config/ConfigEdit.vue:29
+#: src/layouts/HeaderLayout.vue:26 src/views/config/ConfigEdit.vue:32
#: src/views/domain/DomainEdit.vue:87 src/views/domain/DomainList.vue:83
#: src/views/other/Install.vue:71 src/views/preference/Preference.vue:41
msgid "Server error"
@@ -995,7 +1008,8 @@ msgstr ""
msgid "View"
msgstr ""
-#: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:22
+#: src/views/config/InspectConfig.vue:6 src/views/domain/cert/IssueCert.vue:26
+#: src/views/domain/DomainAdd.vue:22
msgid "Warning"
msgstr "Warning"
diff --git a/frontend/src/language/messages.pot b/frontend/src/language/messages.pot
index aa0f0e80..1aa258c0 100644
--- a/frontend/src/language/messages.pot
+++ b/frontend/src/language/messages.pot
@@ -104,11 +104,11 @@ msgstr ""
msgid "Auto-renewal enabled for %{name}"
msgstr ""
-#: src/views/config/Config.vue:16
-#: src/views/config/Config.vue:17
-#: src/views/config/Config.vue:27
-#: src/views/config/Config.vue:5
-#: src/views/config/ConfigEdit.vue:64
+#: src/views/config/Config.vue:18
+#: src/views/config/Config.vue:19
+#: src/views/config/Config.vue:29
+#: src/views/config/Config.vue:7
+#: src/views/config/ConfigEdit.vue:72
#: src/views/domain/DomainEdit.vue:222
#: src/views/nginx_log/NginxLog.vue:173
msgid "Back"
@@ -187,11 +187,15 @@ msgstr ""
msgid "Config Templates"
msgstr ""
+#: src/views/config/InspectConfig.vue:3
+msgid "Configuration file is test successful"
+msgstr ""
+
#: src/views/domain/DomainAdd.vue:11
msgid "Configuration Name"
msgstr ""
-#: src/views/config/Config.vue:2
+#: src/views/config/Config.vue:4
msgid "Configurations"
msgstr ""
@@ -350,7 +354,7 @@ msgid "Edit %{n}"
msgstr ""
#: src/routes/index.ts:81
-#: src/views/config/ConfigEdit.vue:2
+#: src/views/config/ConfigEdit.vue:4
msgid "Edit Configuration"
msgstr ""
@@ -397,6 +401,10 @@ msgstr ""
msgid "Encrypt website with Let's Encrypt"
msgstr ""
+#: src/views/config/InspectConfig.vue:17
+msgid "Error"
+msgstr ""
+
#: src/routes/index.ts:115
#: src/views/domain/ngx_conf/LogEntry.vue:68
msgid "Error Logs"
@@ -456,15 +464,15 @@ msgstr ""
msgid "Finished"
msgstr ""
-#: src/views/config/ConfigEdit.vue:67
+#: src/views/config/ConfigEdit.vue:75
msgid "Format Code"
msgstr ""
-#: src/views/config/ConfigEdit.vue:52
+#: src/views/config/ConfigEdit.vue:57
msgid "Format error %{msg}"
msgstr ""
-#: src/views/config/ConfigEdit.vue:50
+#: src/views/config/ConfigEdit.vue:55
msgid "Format successfully"
msgstr ""
@@ -500,6 +508,10 @@ msgstr ""
msgid "Initialing core upgrader"
msgstr ""
+#: src/views/config/InspectConfig.vue:2
+msgid "Inspect Configurations"
+msgstr ""
+
#: src/routes/index.ts:155
#: src/views/other/Install.vue:128
msgid "Install"
@@ -812,7 +824,7 @@ msgstr ""
msgid "Run Mode"
msgstr ""
-#: src/views/config/ConfigEdit.vue:70
+#: src/views/config/ConfigEdit.vue:78
#: src/views/domain/DomainEdit.vue:225
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34
@@ -829,7 +841,7 @@ msgstr ""
msgid "Save Directive"
msgstr ""
-#: src/views/config/ConfigEdit.vue:43
+#: src/views/config/ConfigEdit.vue:46
#: src/views/domain/DomainAdd.vue:55
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37
msgid "Save error %{msg}"
@@ -844,7 +856,7 @@ msgstr ""
msgid "Save Successfully"
msgstr ""
-#: src/views/config/ConfigEdit.vue:41
+#: src/views/config/ConfigEdit.vue:44
#: src/views/domain/DomainAdd.vue:44
#: src/views/domain/DomainEdit.vue:125
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35
@@ -865,7 +877,7 @@ msgstr ""
#: src/components/StdDataDisplay/StdTable.vue:343
#: src/components/StdDataDisplay/StdTable.vue:463
#: src/layouts/HeaderLayout.vue:26
-#: src/views/config/ConfigEdit.vue:29
+#: src/views/config/ConfigEdit.vue:32
#: src/views/domain/DomainEdit.vue:87
#: src/views/domain/DomainList.vue:83
#: src/views/other/Install.vue:71
@@ -1026,6 +1038,7 @@ msgstr ""
msgid "View"
msgstr ""
+#: src/views/config/InspectConfig.vue:6
#: src/views/domain/cert/IssueCert.vue:26
#: src/views/domain/DomainAdd.vue:22
msgid "Warning"
diff --git a/frontend/src/language/translations.json b/frontend/src/language/translations.json
index 6fd5fea0..10f50aca 100644
--- a/frontend/src/language/translations.json
+++ b/frontend/src/language/translations.json
@@ -1 +1 @@
-{"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Arch":"架搆","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Author":"作者","Auto":"自動","Auto Cert":"自動更新","Auto cert is enabled, please do not modify this certification.":"自動證書已啟用,請不要修改此證書。","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Certification":"證照","Change Certificate":"更改證書","Check again":"再次檢查","Comments":"註釋","Config Templates":"配置模板","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","Core Upgrade":"核心升級","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Current Version":"當前版本","Custom":"自訂","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Description":"敘述","Development Mode":"開發模式","Dir":"目錄","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Do you want to reload Nginx?":"你想重載 Nginx 嗎?","Domain":"網域","Domain Config Created Successfully":"域名配置文件創建成功","Download latest release error":"下載最新版本錯誤","Downloading latest release":"正在下載最新版本","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error Logs":"錯誤日志","Executable Path":"可執行檔路徑","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","Failed to save, syntax error(s) was detected in the configuration.":"保存失敗,在配置中檢測到語法錯誤。","File":"文件","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Format Code":"格式化代碼","Format error %{msg}":"格式錯誤 %{msg}","Format successfully":"格式化成功","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","HTTP Challenge Port":"HTTP 挑戰端口","HTTP Port":"HTTP 監聽埠","Initial core upgrader error":"初始核心升級程序錯誤","Initialing core upgrader":"正在初始化核心升級程序","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Jwt Secret":"Jwt Secret","Last checked at":"上次檢查時間","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Multi-line Directive":"多行指令","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","New version released":"新版本發布","Next":"下一步","Nginx Access Log Path":"Nginx 訪問日誌路徑","Nginx Configuration Parse Error":"Nginx 配置解析錯誤","Nginx Error Log Path":"Nginx 錯誤日誌路徑","Nginx Log":"Nginx 日誌","Nginx reloaded successfully":"Nginx 重載成功","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note":"備註","Obtaining certificate":"正在獲取證書","OK":"確定","OS":"作業系統","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Perform core upgrade error":"執行核心升級錯誤","Performing core upgrade":"正在執行核心升級","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reinstall":"安裝","Release Note":"發行公告","Reloading nginx":"重载 Nginx","Reset":"重設","Run Mode":"高階模式","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","SSL Certificate Key Path":"SSL 證書密鑰路徑","SSL Certificate Path":"SSL證書路徑","SSL Certification Content":"SSL認證內容","SSL Certification Key Content":"SSL 證書密鑰內容","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","System":"系統","Table":"表格","Terminal":"終端","Terminal Start Command":"終端啟動命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Type":"類型","Updated at":"修改時間","Updated successfully":"已成功更新","Upgrade":"升級","Upgraded successfully":"升級成功","Upgrading Nginx UI, please wait...":"正在升級 Nginx UI,請稍候...","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","View":"查看","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","You are using the latest version":"您使用的是最新版本","You can check Nginx UI upgrade at this page.":"您可以在此頁面查看 Nginx UI 升級。","License":{"Project":"開源軟體授權條款"}},"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Arch":"架构","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Author":"作者","Auto":"自动","Auto Cert":"自动更新","Auto cert is enabled, please do not modify this certification.":"自动更新已启用,请勿修改此证书配置。","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Change Certificate":"更改证书","Check again":"重新检查","Comments":"注释","Config Templates":"配置","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","Core Upgrade":"核心升级","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Current Version":"当前版本","Custom":"自定义","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Description":"描述","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Do you want to reload Nginx?":"你需要重载 Nginx 吗?","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Download latest release error":"下载最新版本错误","Downloading latest release":"下载最新版本","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error Logs":"错误日志","Executable Path":"可执行文件路径","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","Failed to save, syntax error(s) was detected in the configuration.":"保存失败,在配置中检测到语法错误。","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Format Code":"代码格式化","Format error %{msg}":"保存错误 %{msg}","Format successfully":"保存成功","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Initial core upgrader error":"初始化核心升级程序错误","Initialing core upgrader":"初始化核心升级器","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Last checked at":"最后检查时间","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Multi-line Directive":"单行指令","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","New version released":"新版本发布","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Configuration Parse Error":"Nginx 配置解析错误","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","Nginx reloaded successfully":"Nginx 重载成功","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note":"注意","Obtaining certificate":"正在获取证书","OK":"确定","OS":"OS","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Perform core upgrade error":"执行核心升级错误","Performing core upgrade":"正在进行核心升级","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reinstall":"重新安装","Release Note":"发行日志","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","SSL Certification Content":"SSL证书内容","SSL Certification Key Content":"SSL证书密钥内容","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","System":"系统","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The server_name in the current configuration must be the domain name you need to get the certificate.":"当前配置中的 server_name 必须为需要申请证书的域名。","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Upgrade":"升级","Upgraded successfully":"升级成功","Upgrading Nginx UI, please wait...":"正在升级Nginx UI,请等待...","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","View":"查看","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","You are using the latest version":"您使用的是最新版本","You can check Nginx UI upgrade at this page.":"你可以在这个页面检查Nginx UI的升级。","License":{"Project":"开源许可"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}}}
\ No newline at end of file
+{"zh_CN":{"About":"关于","Access Logs":"访问日志","Action":"操作","Add":"添加","Add Directive Below":"在下面添加指令","Add Location":"添加 Location","Add Site":"添加站点","Advance Mode":"高级模式","Arch":"架构","Are you sure you want to delete?":"您确定要删除吗?","Are you sure you want to remove this directive?":"您确定要删除这条指令?","Are you sure you want to remove this location?":"您确定要删除这个 Location?","Author":"作者","Auto":"自动","Auto Cert":"自动更新","Auto cert is enabled, please do not modify this certification.":"自动更新已启用,请勿修改此证书配置。","Auto Refresh":"自动刷新","Auto-renewal disabled for %{name}":"成功关闭 %{name} 自动续签","Auto-renewal enabled for %{name}":"成功启用 %{name} 自动续签","Back":"返回","Back Home":"返回首页","Base information":"基本信息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"构建基于","Cancel":"取消","Certificate has expired":"此证书已过期","Certificate is valid":"此证书有效","Certificate Status":"证书状态","Certification":"证书","Change Certificate":"更改证书","Check again":"重新检查","Comments":"注释","Config Templates":"配置","Configuration file is test successful":"配置文件测试成功","Configuration Name":"配置名称","Configurations":"配置","Configure SSL":"配置 SSL","Content":"内容","Core Upgrade":"核心升级","CPU Status":"CPU 状态","CPU:":"CPU:","Create Another":"再创建一个","Created at":"创建时间","Creating client facilitates communication with the CA server":"正在创建客户端用于与 CA 服务器通信","Current Version":"当前版本","Custom":"自定义","Dark":"深色","Dashboard":"仪表盘","Database (Optional, default: database)":"数据库 (可选,默认: database)","Delete":"删除","Delete ID: %{id}":"删除 ID: %{id}","Delete site: %{site_name}":"删除站点: %{site_name}","Description":"描述","Development Mode":"开发模式","Dir":"目录","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"关闭 %{name} 自动续签失败","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁盘 IO","Do you want to reload Nginx?":"你需要重载 Nginx 吗?","Domain":"域名","Domain Config Created Successfully":"域名配置文件创建成功","Download latest release error":"下载最新版本错误","Downloading latest release":"下载最新版本","Edit %{n}":"编辑 %{n}","Edit Configuration":"编辑配置","Edit Site":"编辑站点","Email (*)":"邮箱 (*)","Enable auto-renewal failed for %{name}":"启用 %{name} 自动续签失败","Enable failed":"启用失败","Enable TLS":"启用 TLS","Enabled":"启用","Enabled successfully":"启用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 对网站进行加密","Error":"错误","Error Logs":"错误日志","Executable Path":"可执行文件路径","Expiration Date: %{date}":"过期时间: %{date}","Export":"导出","Failed to disable %{msg}":"禁用失败 %{msg}","Failed to enable %{msg}":"启用失败 %{msg}","Failed to get certificate information":"获取证书信息失败","Failed to save, syntax error(s) was detected in the configuration.":"保存失败,在配置中检测到语法错误。","File":"文件","File Not Found":"未找到文件","Filter":"过滤","Finished":"完成","Format Code":"代码格式化","Format error %{msg}":"保存错误 %{msg}","Format successfully":"格式化成功","Generate":"生成","Generating private key for registering account":"正在生成私钥用于注册账户","Getting the certificate, please wait...":"正在获取证书,请稍等...","Home":"首页","HTTP Challenge Port":"HTTP Challenge 监听端口","HTTP Port":"HTTP 监听端口","Initial core upgrader error":"初始化核心升级程序错误","Initialing core upgrader":"初始化核心升级器","Inspect Configurations":"检查配置","Install":"安装","Install successfully":"安装成功","Intermediate Certification Authorities: %{issuer}":"中级证书颁发机构: %{issuer}","Issued certificate successfully":"证书申请成功","Jwt Secret":"Jwt 密钥","Last checked at":"最后检查时间","Leave blank for no change":"留空表示不修改","Light":"浅色","Load Averages:":"系统负载:","Location":"Location","Locations":"Locations","Login":"登录","Login successful":"登录成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在获取签发证书前,请确保配置文件中已将 .well-known 目录反向代理到 HTTPChallengePort (默认: 9180)","Manage Configs":"配置管理","Manage Sites":"网站管理","Manage Users":"用户管理","Memory":"内存","Memory and Storage":"内存与存储","Modify":"修改","Modify Config":"修改配置文件","Multi-line Directive":"单行指令","Name":"名称","Network":"网络","Network Statistics":"流量统计","Network Total Receive":"下载流量","Network Total Send":"上传流量","New version released":"新版本发布","Next":"下一步","Nginx Access Log Path":"Nginx 访问日志路径","Nginx Configuration Parse Error":"Nginx 配置解析错误","Nginx Error Log Path":"Nginx 错误日志路径","Nginx Log":"Nginx 日志","Nginx reloaded successfully":"Nginx 重载成功","No":"取消","Not Found":"找不到页面","Not Valid Before: %{date}":"此前无效: %{date}","Note":"注意","Obtaining certificate":"正在获取证书","OK":"确定","OS":"OS","OS:":"OS:","Params":"参数","Password":"密码","Password (*)":"密码 (*)","Path":"路径","Perform core upgrade error":"执行核心升级错误","Performing core upgrade":"正在进行核心升级","Please input your E-mail!":"请输入您的邮箱!","Please input your password!":"请输入您的密码!","Please input your username!":"请输入您的用户名!","Preference":"偏好设置","Preparing lego configurations":"正在准备 Lego 的配置","Prohibit changing root password in demo":"禁止在演示模式下修改 root 账户的密码","Prohibit deleting the default user":"禁止删除默认用户","Project Team":"项目团队","Reads":"读","Receive":"下载","Registering user":"正在注册用户","Reinstall":"重新安装","Release Note":"发行日志","Reloading nginx":"正在重载 Nginx","Reset":"重置","Run Mode":"运行模式","Save":"保存","Save Directive":"保存指令","Save error %{msg}":"保存错误 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"保存成功","Selector":"选择器","Send":"上传","Server error":"服务器错误","Server Info":"服务器信息","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必须为 server_name 指令指明参数","Single Directive":"单行指令","Site Logs":"站点列表","Sites List":"站点列表","SSL Certificate Key Path":"SSL证书密钥路径","SSL Certificate Path":"SSL证书路径","SSL Certification Content":"SSL证书内容","SSL Certification Key Content":"SSL证书密钥内容","Status":"状态","Storage":"存储","Subject Name: %{name}":"主体名称: %{name}","Swap":"Swap","System":"系统","Table":"列表","Terminal":"终端","Terminal Start Command":"终端启动命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系统将会每小时检测一次该域名证书,若距离上次签发已超过1个月,则将自动续签。","The filename cannot contain the following characters: %{c}":"文件名不能包含以下字符: %{c}","The server_name in the current configuration must be the domain name you need to get the certificate.":"当前配置中的 server_name 必须为需要申请证书的域名。","The username or password is incorrect":"用户名或密码错误","Theme":"主题","Type":"类型","Updated at":"修改时间","Updated successfully":"更新成功","Upgrade":"升级","Upgraded successfully":"升级成功","Upgrading Nginx UI, please wait...":"正在升级Nginx UI,请等待...","Uptime:":"运行时间:","Username":"用户名","Username (*)":"用户名 (*)","Using HTTP01 challenge provider":"使用 HTTP01 challenge provider","View":"查看","Warning":"警告","Writes":"写","Writing certificate private key to disk":"正在将证书私钥写入磁盘","Writing certificate to disk":"正在将证书写入磁盘","Yes":"是的","You are using the latest version":"您使用的是最新版本","You can check Nginx UI upgrade at this page.":"你可以在这个页面检查Nginx UI的升级。","License":{"Project":"开源许可"}},"zh_TW":{"About":"關於","Access Logs":"訪問日誌","Action":"操作","Add":"新增","Add Directive Below":"在下面新增指令","Add Location":"新增 Location","Add Site":"新增站點","Advance Mode":"高階模式","Arch":"架搆","Are you sure you want to delete?":"你確定你要刪除?","Are you sure you want to remove this directive?":"您確定要刪除這條指令?","Are you sure you want to remove this location?":"您確定要刪除此 Location 嗎?","Author":"作者","Auto":"自動","Auto Cert":"自動更新","Auto cert is enabled, please do not modify this certification.":"自動證書已啟用,請不要修改此證書。","Auto Refresh":"自動刷新","Auto-renewal disabled for %{name}":"已關閉 %{name} 自動續簽","Auto-renewal enabled for %{name}":"已啟用 %{name} 自動續簽","Back":"返回","Back Home":"回到首頁","Base information":"基本訊息","Basic Mode":"基本模式","Batch Modify":"批量修改","Build with":"構建基於","Cancel":"取消","Certificate has expired":"此憑證已過期","Certificate is valid":"此憑證有效","Certificate Status":"憑證狀態","Certification":"證照","Change Certificate":"更改證書","Check again":"再次檢查","Comments":"註釋","Config Templates":"配置模板","Configuration file is test successful":"配置文件測試成功","Configuration Name":"配置名稱","Configurations":"配置","Configure SSL":"配置 SSL","Content":"內容","Core Upgrade":"核心升級","CPU Status":"中央處理器狀態","CPU:":"中央處理器:","Create Another":"再創建一個","Created at":"建立時間","Creating client facilitates communication with the CA server":"創建客戶端方便與CA服務器通信","Current Version":"當前版本","Custom":"自訂","Dark":"深色","Dashboard":"儀表盤","Database (Optional, default: database)":"資料庫 (可選,預設: database)","Delete":"刪除","Delete ID: %{id}":"刪除 ID: %{id}","Delete site: %{site_name}":"刪除站點:%{site_name}","Description":"敘述","Development Mode":"開發模式","Dir":"目錄","Directive":"指令","Directives":"指令","Disable auto-renewal failed for %{name}":"關閉 %{name} 自動續簽失敗","Disabled":"禁用","Disabled successfully":"禁用成功","Disk IO":"磁碟 IO","Do you want to reload Nginx?":"你想重載 Nginx 嗎?","Domain":"網域","Domain Config Created Successfully":"域名配置文件創建成功","Download latest release error":"下載最新版本錯誤","Downloading latest release":"正在下載最新版本","Edit %{n}":"編輯 %{n}","Edit Configuration":"編輯配置","Edit Site":"編輯站點","Email (*)":"郵箱 (*)","Enable auto-renewal failed for %{name}":"啟用 %{name} 自動續簽失敗","Enable failed":"啟用失敗","Enable TLS":"啟用 TLS","Enabled":"啟用","Enabled successfully":"啟用成功","Encrypt website with Let's Encrypt":"用 Let's Encrypt 對網站進行加密","Error":"錯誤","Error Logs":"錯誤日志","Executable Path":"可執行檔路徑","Expiration Date: %{date}":"過期時間: %{date}","Export":"導出","Failed to disable %{msg}":"禁用失敗 %{msg}","Failed to enable %{msg}":"啟用失敗 %{msg}","Failed to get certificate information":"獲取證書信息失敗","Failed to save, syntax error(s) was detected in the configuration.":"保存失敗,在配置中檢測到語法錯誤。","File":"文件","File Not Found":"未找到檔案","Filter":"篩選","Finished":"完成","Format Code":"格式化代碼","Format error %{msg}":"格式錯誤 %{msg}","Format successfully":"格式化成功","Generate":"生成","Generating private key for registering account":"生成註冊賬號私鑰","Getting the certificate, please wait...":"正在獲取憑證,請稍等...","Home":"首頁","HTTP Challenge Port":"HTTP 挑戰端口","HTTP Port":"HTTP 監聽埠","Initial core upgrader error":"初始核心升級程序錯誤","Initialing core upgrader":"正在初始化核心升級程序","Inspect Configurations":"檢查配置","Install":"安裝","Install successfully":"安裝成功","Intermediate Certification Authorities: %{issuer}":"中級憑證頒發機構: %{issuer}","Issued certificate successfully":"頒發證書成功","Jwt Secret":"Jwt Secret","Last checked at":"上次檢查時間","Leave blank for no change":"留空表示不修改","Light":"淺色","Load Averages:":"系統負載:","Location":"Location","Locations":"Locations","Login":"登入","Login successful":"登入成功","Logout successful":"登出成功","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"在獲取證書前,請確保配置檔案中已將 .well-known 目錄反向代理到 HTTPChallengePort (預設: 9180)","Manage Configs":"配置管理","Manage Sites":"網站管理","Manage Users":"使用者管理","Memory":"記憶體","Memory and Storage":"記憶體和存儲","Modify":"修改","Modify Config":"修改配置","Multi-line Directive":"多行指令","Name":"名稱","Network":"網路","Network Statistics":"網路統計","Network Total Receive":"下載流量","Network Total Send":"上傳流量","New version released":"新版本發布","Next":"下一步","Nginx Access Log Path":"Nginx 訪問日誌路徑","Nginx Configuration Parse Error":"Nginx 配置解析錯誤","Nginx Error Log Path":"Nginx 錯誤日誌路徑","Nginx Log":"Nginx 日誌","Nginx reloaded successfully":"Nginx 重載成功","No":"取消","Not Found":"找不到頁面","Not Valid Before: %{date}":"此前無效: %{date}","Note":"備註","Obtaining certificate":"正在獲取證書","OK":"確定","OS":"作業系統","OS:":"作業系統:","Params":"參數","Password":"密碼","Password (*)":"密碼 (*)","Path":"路徑","Perform core upgrade error":"執行核心升級錯誤","Performing core upgrade":"正在執行核心升級","Please input your E-mail!":"請輸入您的郵箱!","Please input your password!":"請輸入您的密碼!","Please input your username!":"請輸入您的使用者名稱!","Preference":"設定","Preparing lego configurations":"準備 Lego 配置","Prohibit changing root password in demo":"禁止在demo中修改root密碼","Prohibit deleting the default user":"禁止刪除默認用戶","Project Team":"專案團隊","Reads":"讀","Receive":"下載","Registering user":"註冊用戶","Reinstall":"安裝","Release Note":"發行公告","Reloading nginx":"重载 Nginx","Reset":"重設","Run Mode":"高階模式","Save":"儲存","Save Directive":"儲存指令","Save error %{msg}":"儲存錯誤 %{msg}","Save successfully":"保存成功","Save Successfully":"保存成功","Saved successfully":"儲存成功","Selector":"選擇器","Send":"上傳","Server error":"伺服器錯誤","Server Info":"伺服器資訊","server_name not found in directives":"未在指令集合中找到 server_name","server_name parameter is required":"必須為 server_name 指令指明參數","Single Directive":"單行指令","Site Logs":"網站日誌","Sites List":"站點列表","SSL Certificate Key Path":"SSL 證書密鑰路徑","SSL Certificate Path":"SSL證書路徑","SSL Certification Content":"SSL認證內容","SSL Certification Key Content":"SSL 證書密鑰內容","Status":"狀態","Storage":"儲存","Subject Name: %{name}":"主體名稱: %{name}","Swap":"交換空間","System":"系統","Table":"表格","Terminal":"終端","Terminal Start Command":"終端啟動命令","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"系統將會每小時檢測一次該域名證書,若距離上次簽發已超過1個月,則將自動續簽。
如果您之前沒有證書,請先點選「從 Let's Encrypt 獲取證書」。","The filename cannot contain the following characters: %{c}":"檔名不能包含以下字元: %{c}","The server_name in the current configuration must be the domain name you need to get the certificate.":"注意:當前配置中的 server_name 必須為需要申請證書的域名。","The username or password is incorrect":"用戶名或密碼不正確","Theme":"外觀樣式","Type":"類型","Updated at":"修改時間","Updated successfully":"已成功更新","Upgrade":"升級","Upgraded successfully":"升級成功","Upgrading Nginx UI, please wait...":"正在升級 Nginx UI,請稍候...","Uptime:":"執行時間:","Username":"使用者名稱","Username (*)":"使用者名稱 (*)","Using HTTP01 challenge provider":"使用 HTTP01 挑戰提供者","View":"查看","Warning":"警告","Writes":"寫","Writing certificate private key to disk":"將證書私鑰寫入磁盤","Writing certificate to disk":"將證書寫入磁盤","Yes":"是的","You are using the latest version":"您使用的是最新版本","You can check Nginx UI upgrade at this page.":"您可以在此頁面查看 Nginx UI 升級。","License":{"Project":"開源軟體授權條款"}},"en":{"About":"About","Action":"Action","Add Directive Below":"Add Directive Below","Add Location":"Add Location","Add Site":"Add Site","Advance Mode":"Advance Mode","Are you sure you want to remove this directive?":"Are you sure you want to remove this directive?","Auto-renewal disabled for %{name}":"Auto-renewal disabled for %{name}","Auto-renewal enabled for %{name}":"Auto-renewal enabled for %{name}","Back":"Back","Base information":"Base information","Basic Mode":"Basic Mode","Build with":"Build with","Cancel":"Cancel","Certificate has expired":"Certificate has expired","Certificate is valid":"Certificate is valid","Certificate Status":"Certificate Status","Comments":"Comments","Configuration Name":"Configuration Name","Configurations":"Configurations","Configure SSL":"Configure SSL","Content":"Content","CPU Status":"CPU Status","CPU:":"CPU:","Create Another":"Create Another","Created at":"Created at","Dashboard":"Dashboard","Database (Optional, default: database)":"Database (Optional, default: database)","Development Mode":"Development Mode","Directive":"Directive","Directives":"Directives","Disable auto-renewal failed for %{name}":"Disable auto-renewal failed for %{name}","Disabled":"Disabled","Disabled successfully":"Disabled successfully","Disk IO":"Disk IO","Domain Config Created Successfully":"Domain Config Created Successfully","Edit %{n}":"Edit %{n}","Edit Configuration":"Edit Configuration","Edit Site":"Edit Site","Email (*)":"Email (*)","Enable auto-renewal failed for %{name}":"Enable auto-renewal failed for %{name}","Enable failed":"Enable failed","Enable TLS":"Enable TLS","Enabled":"Enabled","Enabled successfully":"Enabled successfully","Encrypt website with Let's Encrypt":"Encrypt website with Let's Encrypt","Expiration Date: %{date}":"Expiration Date: %{date}","Failed to disable %{msg}":"Failed to disable %{msg}","Failed to enable %{msg}":"Failed to enable %{msg}","File Not Found":"File Not Found","Finished":"Finished","Getting the certificate, please wait...":"Getting the certificate, please wait...","Home":"Home","Install":"Install","Intermediate Certification Authorities: %{issuer}":"Intermediate Certification Authorities: %{issuer}","Leave blank for no change":"Leave blank for no change","Load Averages:":"Load Averages:","Location":"Location","Locations":"Locations","Login":"Login","Login successful":"Login successful","Logout successful":"Logout successful","Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.":"Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.","Manage Configs":"Manage Configs","Manage Sites":"Manage Sites","Manage Users":"Manage Users","Memory":"Memory","Memory and Storage":"Memory and Storage","Modify Config":"Modify Config","Name":"Name","Network":"Network","Network Statistics":"Network Statistics","Network Total Receive":"Network Total Receive","Network Total Send":"Network Total Send","Next":"Next","No":"No","Not Found":"Not Found","Not Valid Before: %{date}":"Not Valid Before: %{date}","OS:":"OS:","Params":"Params","Password":"Password","Password (*)":"Password (*)","Path":"Path","Please input your E-mail!":"Please input your E-mail!","Please input your password!":"Please input your password!","Please input your username!":"Please input your username!","Project Team":"Project Team","Reads":"Reads","Receive":"Receive","Save":"Save","Save Directive":"Save Directive","Save error %{msg}":"Save error %{msg}","Saved successfully":"Saved successfully","Send":"Send","Server error":"Server error","Server Info":"Server Info","server_name not found in directives":"server_name not found in directives","server_name parameter is required":"server_name parameter is required","Single Directive":"Single Directive","Sites List":"Sites List","Status":"Status","Storage":"Storage","Subject Name: %{name}":"Subject Name: %{name}","Swap":"Swap","Terminal":"Terminal","The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.":"The certificate for the domain will be checked every hour, and will be renewed if it has been more than 1 month since it was last issued.","The filename cannot contain the following characters: %{c}":"The filename cannot contain the following characters: %{c}","Updated at":"Updated at","Uptime:":"Uptime:","Username":"Username","Username (*)":"Username (*)","Warning":"Warning","Writes":"Writes","Yes":"Yes","License":{"Project":"License"}}}
\ No newline at end of file
diff --git a/frontend/src/language/zh_CN/app.mo b/frontend/src/language/zh_CN/app.mo
index bb0a0e18..d79c0bbf 100644
Binary files a/frontend/src/language/zh_CN/app.mo and b/frontend/src/language/zh_CN/app.mo differ
diff --git a/frontend/src/language/zh_CN/app.po b/frontend/src/language/zh_CN/app.po
index c02cbc05..768286af 100644
--- a/frontend/src/language/zh_CN/app.po
+++ b/frontend/src/language/zh_CN/app.po
@@ -106,9 +106,9 @@ msgstr "成功关闭 %{name} 自动续签"
msgid "Auto-renewal enabled for %{name}"
msgstr "成功启用 %{name} 自动续签"
-#: src/views/config/Config.vue:16 src/views/config/Config.vue:17
-#: src/views/config/Config.vue:27 src/views/config/Config.vue:5
-#: src/views/config/ConfigEdit.vue:64 src/views/domain/DomainEdit.vue:222
+#: src/views/config/Config.vue:18 src/views/config/Config.vue:19
+#: src/views/config/Config.vue:29 src/views/config/Config.vue:7
+#: src/views/config/ConfigEdit.vue:72 src/views/domain/DomainEdit.vue:222
#: src/views/nginx_log/NginxLog.vue:173
msgid "Back"
msgstr "返回"
@@ -181,11 +181,15 @@ msgstr "注释"
msgid "Config Templates"
msgstr "配置"
+#: src/views/config/InspectConfig.vue:3
+msgid "Configuration file is test successful"
+msgstr "配置文件测试成功"
+
#: src/views/domain/DomainAdd.vue:11
msgid "Configuration Name"
msgstr "配置名称"
-#: src/views/config/Config.vue:2
+#: src/views/config/Config.vue:4
msgid "Configurations"
msgstr "配置"
@@ -334,7 +338,7 @@ msgstr "下载最新版本"
msgid "Edit %{n}"
msgstr "编辑 %{n}"
-#: src/routes/index.ts:81 src/views/config/ConfigEdit.vue:2
+#: src/routes/index.ts:81 src/views/config/ConfigEdit.vue:4
msgid "Edit Configuration"
msgstr "编辑配置"
@@ -375,6 +379,10 @@ msgstr "启用成功"
msgid "Encrypt website with Let's Encrypt"
msgstr "用 Let's Encrypt 对网站进行加密"
+#: src/views/config/InspectConfig.vue:17
+msgid "Error"
+msgstr "错误"
+
#: src/routes/index.ts:115 src/views/domain/ngx_conf/LogEntry.vue:68
msgid "Error Logs"
msgstr "错误日志"
@@ -427,17 +435,17 @@ msgstr "过滤"
msgid "Finished"
msgstr "完成"
-#: src/views/config/ConfigEdit.vue:67
+#: src/views/config/ConfigEdit.vue:75
msgid "Format Code"
msgstr "代码格式化"
-#: src/views/config/ConfigEdit.vue:52
+#: src/views/config/ConfigEdit.vue:57
msgid "Format error %{msg}"
msgstr "保存错误 %{msg}"
-#: src/views/config/ConfigEdit.vue:50
+#: src/views/config/ConfigEdit.vue:55
msgid "Format successfully"
-msgstr "保存成功"
+msgstr "格式化成功"
#: src/components/StdDataEntry/components/StdPassword.vue:42
msgid "Generate"
@@ -471,6 +479,10 @@ msgstr "初始化核心升级程序错误"
msgid "Initialing core upgrader"
msgstr "初始化核心升级器"
+#: src/views/config/InspectConfig.vue:2
+msgid "Inspect Configurations"
+msgstr "检查配置"
+
#: src/routes/index.ts:155 src/views/other/Install.vue:128
msgid "Install"
msgstr "安装"
@@ -762,7 +774,7 @@ msgstr "重置"
msgid "Run Mode"
msgstr "运行模式"
-#: src/views/config/ConfigEdit.vue:70 src/views/domain/DomainEdit.vue:225
+#: src/views/config/ConfigEdit.vue:78 src/views/domain/DomainEdit.vue:225
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
@@ -778,7 +790,7 @@ msgstr "保存"
msgid "Save Directive"
msgstr "保存指令"
-#: src/views/config/ConfigEdit.vue:43 src/views/domain/DomainAdd.vue:55
+#: src/views/config/ConfigEdit.vue:46 src/views/domain/DomainAdd.vue:55
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37
msgid "Save error %{msg}"
msgstr "保存错误 %{msg}"
@@ -792,7 +804,7 @@ msgstr "保存成功"
msgid "Save Successfully"
msgstr "保存成功"
-#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainAdd.vue:44
+#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:44
#: src/views/domain/DomainEdit.vue:125
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35
msgid "Saved successfully"
@@ -810,7 +822,7 @@ msgstr "上传"
#: src/components/StdDataDisplay/StdTable.vue:168
#: src/components/StdDataDisplay/StdTable.vue:343
#: src/components/StdDataDisplay/StdTable.vue:463
-#: src/layouts/HeaderLayout.vue:26 src/views/config/ConfigEdit.vue:29
+#: src/layouts/HeaderLayout.vue:26 src/views/config/ConfigEdit.vue:32
#: src/views/domain/DomainEdit.vue:87 src/views/domain/DomainList.vue:83
#: src/views/other/Install.vue:71 src/views/preference/Preference.vue:41
msgid "Server error"
@@ -965,7 +977,8 @@ msgstr "使用 HTTP01 challenge provider"
msgid "View"
msgstr "查看"
-#: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:22
+#: src/views/config/InspectConfig.vue:6 src/views/domain/cert/IssueCert.vue:26
+#: src/views/domain/DomainAdd.vue:22
msgid "Warning"
msgstr "警告"
diff --git a/frontend/src/language/zh_TW/app.mo b/frontend/src/language/zh_TW/app.mo
index f904e0d9..c3950f08 100644
Binary files a/frontend/src/language/zh_TW/app.mo and b/frontend/src/language/zh_TW/app.mo differ
diff --git a/frontend/src/language/zh_TW/app.po b/frontend/src/language/zh_TW/app.po
index 06489b89..8353f509 100644
--- a/frontend/src/language/zh_TW/app.po
+++ b/frontend/src/language/zh_TW/app.po
@@ -107,9 +107,9 @@ msgstr "已關閉 %{name} 自動續簽"
msgid "Auto-renewal enabled for %{name}"
msgstr "已啟用 %{name} 自動續簽"
-#: src/views/config/Config.vue:16 src/views/config/Config.vue:17
-#: src/views/config/Config.vue:27 src/views/config/Config.vue:5
-#: src/views/config/ConfigEdit.vue:64 src/views/domain/DomainEdit.vue:222
+#: src/views/config/Config.vue:18 src/views/config/Config.vue:19
+#: src/views/config/Config.vue:29 src/views/config/Config.vue:7
+#: src/views/config/ConfigEdit.vue:72 src/views/domain/DomainEdit.vue:222
#: src/views/nginx_log/NginxLog.vue:173
msgid "Back"
msgstr "返回"
@@ -182,11 +182,15 @@ msgstr "註釋"
msgid "Config Templates"
msgstr "配置模板"
+#: src/views/config/InspectConfig.vue:3
+msgid "Configuration file is test successful"
+msgstr "配置文件測試成功"
+
#: src/views/domain/DomainAdd.vue:11
msgid "Configuration Name"
msgstr "配置名稱"
-#: src/views/config/Config.vue:2
+#: src/views/config/Config.vue:4
msgid "Configurations"
msgstr "配置"
@@ -335,7 +339,7 @@ msgstr "正在下載最新版本"
msgid "Edit %{n}"
msgstr "編輯 %{n}"
-#: src/routes/index.ts:81 src/views/config/ConfigEdit.vue:2
+#: src/routes/index.ts:81 src/views/config/ConfigEdit.vue:4
msgid "Edit Configuration"
msgstr "編輯配置"
@@ -376,6 +380,10 @@ msgstr "啟用成功"
msgid "Encrypt website with Let's Encrypt"
msgstr "用 Let's Encrypt 對網站進行加密"
+#: src/views/config/InspectConfig.vue:17
+msgid "Error"
+msgstr "錯誤"
+
#: src/routes/index.ts:115 src/views/domain/ngx_conf/LogEntry.vue:68
msgid "Error Logs"
msgstr "錯誤日志"
@@ -428,15 +436,15 @@ msgstr "篩選"
msgid "Finished"
msgstr "完成"
-#: src/views/config/ConfigEdit.vue:67
+#: src/views/config/ConfigEdit.vue:75
msgid "Format Code"
msgstr "格式化代碼"
-#: src/views/config/ConfigEdit.vue:52
+#: src/views/config/ConfigEdit.vue:57
msgid "Format error %{msg}"
msgstr "格式錯誤 %{msg}"
-#: src/views/config/ConfigEdit.vue:50
+#: src/views/config/ConfigEdit.vue:55
msgid "Format successfully"
msgstr "格式化成功"
@@ -472,6 +480,10 @@ msgstr "初始核心升級程序錯誤"
msgid "Initialing core upgrader"
msgstr "正在初始化核心升級程序"
+#: src/views/config/InspectConfig.vue:2
+msgid "Inspect Configurations"
+msgstr "檢查配置"
+
#: src/routes/index.ts:155 src/views/other/Install.vue:128
msgid "Install"
msgstr "安裝"
@@ -763,7 +775,7 @@ msgstr "重設"
msgid "Run Mode"
msgstr "高階模式"
-#: src/views/config/ConfigEdit.vue:70 src/views/domain/DomainEdit.vue:225
+#: src/views/config/ConfigEdit.vue:78 src/views/domain/DomainEdit.vue:225
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:33
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:34
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:40
@@ -779,7 +791,7 @@ msgstr "儲存"
msgid "Save Directive"
msgstr "儲存指令"
-#: src/views/config/ConfigEdit.vue:43 src/views/domain/DomainAdd.vue:55
+#: src/views/config/ConfigEdit.vue:46 src/views/domain/DomainAdd.vue:55
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:37
msgid "Save error %{msg}"
msgstr "儲存錯誤 %{msg}"
@@ -793,7 +805,7 @@ msgstr "保存成功"
msgid "Save Successfully"
msgstr "保存成功"
-#: src/views/config/ConfigEdit.vue:41 src/views/domain/DomainAdd.vue:44
+#: src/views/config/ConfigEdit.vue:44 src/views/domain/DomainAdd.vue:44
#: src/views/domain/DomainEdit.vue:125
#: src/views/domain/ngx_conf/directive/DirectiveEditorItem.vue:35
msgid "Saved successfully"
@@ -811,7 +823,7 @@ msgstr "上傳"
#: src/components/StdDataDisplay/StdTable.vue:168
#: src/components/StdDataDisplay/StdTable.vue:343
#: src/components/StdDataDisplay/StdTable.vue:463
-#: src/layouts/HeaderLayout.vue:26 src/views/config/ConfigEdit.vue:29
+#: src/layouts/HeaderLayout.vue:26 src/views/config/ConfigEdit.vue:32
#: src/views/domain/DomainEdit.vue:87 src/views/domain/DomainList.vue:83
#: src/views/other/Install.vue:71 src/views/preference/Preference.vue:41
msgid "Server error"
@@ -967,7 +979,8 @@ msgstr "使用 HTTP01 挑戰提供者"
msgid "View"
msgstr "查看"
-#: src/views/domain/cert/IssueCert.vue:26 src/views/domain/DomainAdd.vue:22
+#: src/views/config/InspectConfig.vue:6 src/views/domain/cert/IssueCert.vue:26
+#: src/views/domain/DomainAdd.vue:22
msgid "Warning"
msgstr "警告"
diff --git a/frontend/src/layouts/HeaderLayout.vue b/frontend/src/layouts/HeaderLayout.vue
index e2334a35..943657af 100644
--- a/frontend/src/layouts/HeaderLayout.vue
+++ b/frontend/src/layouts/HeaderLayout.vue
@@ -6,6 +6,7 @@ import auth from '@/api/auth'
import {HomeOutlined, LogoutOutlined, MenuUnfoldOutlined, ReloadOutlined} from '@ant-design/icons-vue'
import {useRouter} from 'vue-router'
import ngx from '@/api/ngx'
+import logLevel from '@/views/config/constants'
const {$gettext} = gettext
@@ -21,7 +22,13 @@ function logout() {
function reload_nginx() {
ngx.reload().then(r => {
- message.success($gettext('Nginx reloaded successfully'))
+ if (r.level < logLevel.Warn) {
+ message.success($gettext('Nginx reloaded successfully'))
+ } else if (r.level === logLevel.Warn) {
+ message.warn(r.message)
+ } else {
+ message.error(r.message)
+ }
}).catch(e => {
message.error($gettext('Server error') + ' ' + e?.message)
})
diff --git a/frontend/src/lib/helper/index.ts b/frontend/src/lib/helper/index.ts
index 1354460c..d3358575 100644
--- a/frontend/src/lib/helper/index.ts
+++ b/frontend/src/lib/helper/index.ts
@@ -41,8 +41,28 @@ const urlJoin = (...args: string[]) =>
.replace(/\?/g, '&')
.replace('&', '?')
+function createEnum(definition: any) {
+ const strToValueMap: any = {}
+ const numToDescMap: any = {}
+ for (const enumName of Object.keys(definition)) {
+ const [value, desc] = definition[enumName]
+ strToValueMap[enumName] = value
+ numToDescMap[value] = desc
+ }
+ return {
+ ...strToValueMap,
+ getDesc(enumName: any) {
+ return (definition[enumName] && definition[enumName][1]) || ''
+ },
+ getDescFromValue(value: any) {
+ return numToDescMap[value] || ''
+ }
+ }
+}
+
export {
bytesToSize,
downloadCsv,
- urlJoin
+ urlJoin,
+ createEnum
}
diff --git a/frontend/src/version.json b/frontend/src/version.json
index 0d4bfbd5..a6866b76 100644
--- a/frontend/src/version.json
+++ b/frontend/src/version.json
@@ -1 +1 @@
-{"version":"1.7.2","build_id":73,"total_build":143}
\ No newline at end of file
+{"version":"1.7.4","build_id":76,"total_build":146}
\ No newline at end of file
diff --git a/frontend/src/views/config/Config.vue b/frontend/src/views/config/Config.vue
index a69de018..c3e24ff7 100644
--- a/frontend/src/views/config/Config.vue
+++ b/frontend/src/views/config/Config.vue
@@ -13,6 +13,7 @@ import configColumns from '@/views/config/config'
import {useRoute} from 'vue-router'
import FooterToolBar from '@/components/FooterToolbar/FooterToolBar.vue'
import router from '@/routes'
+import InspectConfig from '@/views/config/InspectConfig.vue'
const table = ref(null)
const route = useRoute()
@@ -34,9 +35,17 @@ const update = ref(1)
watch(get_params, () => {
update.value++
})
+
+const inspect_config = ref()
+
+watch(route, () => {
+ inspect_config.value?.test()
+})
+
+
{
const n = route.params.name
if (typeof n === 'string') {
@@ -41,6 +44,8 @@ function save() {
message.success($gettext('Saved successfully'))
}).catch(r => {
message.error(interpolate($gettext('Save error %{msg}'), {msg: r.message ?? ''}))
+ }).finally(() => {
+ inspect_config.value.test()
})
}
@@ -52,10 +57,13 @@ function format_code() {
message.error(interpolate($gettext('Format error %{msg}'), {msg: r.message ?? ''}))
})
}
+
+
+
@@ -75,10 +83,5 @@ function format_code() {
diff --git a/frontend/src/views/config/InspectConfig.vue b/frontend/src/views/config/InspectConfig.vue
new file mode 100644
index 00000000..d0dae7d9
--- /dev/null
+++ b/frontend/src/views/config/InspectConfig.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+ {{ data.message }}
+
+
+
+
+
+ {{ data.message }}
+
+
+
+
+
+
diff --git a/frontend/src/views/config/constants.ts b/frontend/src/views/config/constants.ts
new file mode 100644
index 00000000..8068822e
--- /dev/null
+++ b/frontend/src/views/config/constants.ts
@@ -0,0 +1,17 @@
+import {createEnum} from '@/lib/helper'
+
+// refer to https://nginx.org/en/docs/ngx_core_module.html#error_log
+// nginx log level: debug, info, notice, warn, error, crit, alert, or emerg
+
+const logLevel = createEnum({
+ Debug: [0, 'debug'],
+ Info: [1, 'info'],
+ Notice: [2, 'notice'],
+ Warn: [3, 'warn'],
+ Error: [4, 'error'],
+ Crit: [5, 'crit'],
+ Alert: [6, 'alert'],
+ Emerg: [7, 'emerg']
+})
+
+export default logLevel
diff --git a/frontend/version.json b/frontend/version.json
index 0d4bfbd5..a6866b76 100644
--- a/frontend/version.json
+++ b/frontend/version.json
@@ -1 +1 @@
-{"version":"1.7.2","build_id":73,"total_build":143}
\ No newline at end of file
+{"version":"1.7.4","build_id":76,"total_build":146}
\ No newline at end of file
diff --git a/server/api/config.go b/server/api/config.go
index caa9312d..8739d728 100644
--- a/server/api/config.go
+++ b/server/api/config.go
@@ -1,13 +1,12 @@
package api
import (
- "github.com/0xJacky/Nginx-UI/server/pkg/config_list"
- "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
- "github.com/gin-gonic/gin"
- "log"
- "net/http"
- "os"
- "strings"
+ "github.com/0xJacky/Nginx-UI/server/pkg/config_list"
+ "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
+ "github.com/gin-gonic/gin"
+ "log"
+ "net/http"
+ "os"
)
func GetConfigs(c *gin.Context) {
@@ -126,7 +125,7 @@ func AddConfig(c *gin.Context) {
output := nginx.Reload()
- if output != "" && strings.Contains(output, "error") {
+ if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{
"message": output,
})
@@ -172,7 +171,7 @@ func EditConfig(c *gin.Context) {
output := nginx.Reload()
- if output != "" && strings.Contains(output, "error") {
+ if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{
"message": output,
})
diff --git a/server/api/domain.go b/server/api/domain.go
index 012c9f10..ed4f3413 100644
--- a/server/api/domain.go
+++ b/server/api/domain.go
@@ -203,17 +203,18 @@ func EditDomain(c *gin.Context) {
enabledConfigFilePath = nginx.GetConfPath("sites-enabled", name)
if _, err = os.Stat(enabledConfigFilePath); err == nil {
// Test nginx configuration
- err = nginx.TestConf()
- if err != nil {
+ output := nginx.TestConf()
+ if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{
- "message": err.Error(),
+ "message": output,
"error": "nginx_config_syntax_error",
})
return
}
- output := nginx.Reload()
- if output != "" && strings.Contains(output, "error") {
+ output = nginx.Reload()
+
+ if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{
"message": output,
})
@@ -245,18 +246,19 @@ func EnableDomain(c *gin.Context) {
}
// Test nginx config, if not pass then rollback.
- err = nginx.TestConf()
- if err != nil {
+ output := nginx.TestConf()
+
+ if nginx.GetLogLevel(output) >= nginx.Warn {
_ = os.Remove(enabledConfigFilePath)
c.JSON(http.StatusInternalServerError, gin.H{
- "message": err.Error(),
+ "message": output,
})
return
}
- output := nginx.Reload()
+ output = nginx.Reload()
- if output != "" && strings.Contains(output, "error") {
+ if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{
"message": output,
})
@@ -295,7 +297,7 @@ func DisableDomain(c *gin.Context) {
output := nginx.Reload()
- if output != "" {
+ if nginx.GetLogLevel(output) >= nginx.Warn {
c.JSON(http.StatusInternalServerError, gin.H{
"message": output,
})
diff --git a/server/api/ngx.go b/server/api/ngx.go
index 043d47ea..da43f80f 100644
--- a/server/api/ngx.go
+++ b/server/api/ngx.go
@@ -1,65 +1,67 @@
package api
import (
- "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
- "github.com/gin-gonic/gin"
- "net/http"
- "strings"
+ "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
+ "github.com/gin-gonic/gin"
+ "net/http"
)
func BuildNginxConfig(c *gin.Context) {
- var ngxConf nginx.NgxConfig
- if !BindAndValid(c, &ngxConf) {
- return
- }
- c.Set("maybe_error", "nginx_config_syntax_error")
- c.JSON(http.StatusOK, gin.H{
- "content": ngxConf.BuildConfig(),
- })
+ var ngxConf nginx.NgxConfig
+ if !BindAndValid(c, &ngxConf) {
+ return
+ }
+ c.Set("maybe_error", "nginx_config_syntax_error")
+ c.JSON(http.StatusOK, gin.H{
+ "content": ngxConf.BuildConfig(),
+ })
}
func TokenizeNginxConfig(c *gin.Context) {
- var json struct {
- Content string `json:"content" binding:"required"`
- }
+ var json struct {
+ Content string `json:"content" binding:"required"`
+ }
- if !BindAndValid(c, &json) {
- return
- }
+ if !BindAndValid(c, &json) {
+ return
+ }
- c.Set("maybe_error", "nginx_config_syntax_error")
- ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
+ c.Set("maybe_error", "nginx_config_syntax_error")
+ ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
- c.JSON(http.StatusOK, ngxConfig)
+ c.JSON(http.StatusOK, ngxConfig)
}
func FormatNginxConfig(c *gin.Context) {
- var json struct {
- Content string `json:"content" binding:"required"`
- }
+ var json struct {
+ Content string `json:"content" binding:"required"`
+ }
- if !BindAndValid(c, &json) {
- return
- }
+ if !BindAndValid(c, &json) {
+ return
+ }
- c.Set("maybe_error", "nginx_config_syntax_error")
- c.JSON(http.StatusOK, gin.H{
- "content": nginx.FmtCode(json.Content),
- })
+ c.Set("maybe_error", "nginx_config_syntax_error")
+ c.JSON(http.StatusOK, gin.H{
+ "content": nginx.FmtCode(json.Content),
+ })
}
func ReloadNginx(c *gin.Context) {
- output := nginx.Reload()
+ output := nginx.Reload()
- if output != "" && strings.Contains(output, "error") {
- c.JSON(http.StatusInternalServerError, gin.H{
- "message": output,
- })
- return
- }
-
- c.JSON(http.StatusOK, gin.H{
- "message": "ok",
- })
+ c.JSON(http.StatusOK, gin.H{
+ "message": output,
+ "level": nginx.GetLogLevel(output),
+ })
+}
+
+func TestNginx(c *gin.Context) {
+ output := nginx.TestConf()
+
+ c.JSON(http.StatusOK, gin.H{
+ "message": output,
+ "level": nginx.GetLogLevel(output),
+ })
}
diff --git a/server/pkg/nginx/log.go b/server/pkg/nginx/log.go
new file mode 100644
index 00000000..bc22808e
--- /dev/null
+++ b/server/pkg/nginx/log.go
@@ -0,0 +1,30 @@
+package nginx
+
+import "strings"
+
+// refer to https://nginx.org/en/docs/ngx_core_module.html#error_log
+// nginx log level: debug, info, notice, warn, error, crit, alert, or emerg
+
+const (
+ Debug = iota
+ Info
+ Notice
+ Warn
+ Error
+ Crit
+ Alert
+ Emerg
+)
+
+var logLevel = [...]string{
+ "debug", "info", "notice", "warn", "error", "crit", "alert", "emerg",
+}
+
+func GetLogLevel(output string) int {
+ for k, v := range logLevel {
+ if strings.Contains(output, v) {
+ return k
+ }
+ }
+ return -1
+}
diff --git a/server/pkg/nginx/nginx.go b/server/pkg/nginx/nginx.go
index 2f06ba1b..daac985f 100644
--- a/server/pkg/nginx/nginx.go
+++ b/server/pkg/nginx/nginx.go
@@ -1,40 +1,30 @@
package nginx
import (
- "errors"
"github.com/0xJacky/Nginx-UI/server/settings"
"log"
"os/exec"
"path/filepath"
"regexp"
- "strings"
)
-func TestConf() error {
+func TestConf() string {
out, err := exec.Command("nginx", "-t").CombinedOutput()
if err != nil {
- log.Println(err)
+ log.Println("[error] nginx.TestConf", err)
}
- output := string(out)
- if strings.Contains(output, "failed") {
- return errors.New(output)
- }
- return nil
+
+ return string(out)
}
func Reload() string {
out, err := exec.Command("nginx", "-s", "reload").CombinedOutput()
if err != nil {
- log.Println(err)
- return err.Error()
+ log.Println("[error] nginx.Reload", err)
}
- output := string(out)
- if strings.Contains(output, "failed") {
- return output
- }
- return ""
+ return string(out)
}
func GetConfPath(dir ...string) string {
diff --git a/server/router/routers.go b/server/router/routers.go
index 9994d983..879c27d4 100644
--- a/server/router/routers.go
+++ b/server/router/routers.go
@@ -64,6 +64,8 @@ func InitRouter() *gin.Engine {
g.POST("ngx/format_code", api.FormatNginxConfig)
// nginx reload
g.POST("nginx/reload", api.ReloadNginx)
+ // nginx test
+ g.POST("nginx/test", api.TestNginx)
g.POST("domain/:name/enable", api.EnableDomain)
g.POST("domain/:name/disable", api.DisableDomain)