diff --git a/frontend/src/api/ngx.ts b/frontend/src/api/ngx.ts
index 8ed20597..62fb41e7 100644
--- a/frontend/src/api/ngx.ts
+++ b/frontend/src/api/ngx.ts
@@ -7,6 +7,10 @@ const ngx = {
tokenize_config(content: string) {
return http.post('/ngx/tokenize_config', {content})
+ },
+
+ format_code(content: string) {
+ return http.post('/ngx/format_code', {content})
}
}
diff --git a/frontend/src/views/config/ConfigEdit.vue b/frontend/src/views/config/ConfigEdit.vue
index 18c4dd96..25fc937e 100644
--- a/frontend/src/views/config/ConfigEdit.vue
+++ b/frontend/src/views/config/ConfigEdit.vue
@@ -6,6 +6,7 @@ import {computed, ref} from 'vue'
import config from '@/api/config'
import {message} from 'ant-design-vue'
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
+import ngx from '@/api/ngx'
const {$gettext, interpolate} = gettext
const route = useRoute()
@@ -43,6 +44,14 @@ function save() {
})
}
+function format_code() {
+ ngx.format_code(configText.value).then(r => {
+ configText.value = r.content
+ message.success($gettext('Format successfully'))
+ }).catch(r => {
+ message.error(interpolate($gettext('Format error %{msg}'), {msg: r.message ?? ''}))
+ })
+}
@@ -54,6 +63,9 @@ function save() {
Back
+
+ Format Code
+
Save
diff --git a/go.mod b/go.mod
index 1c043883..722eefd3 100644
--- a/go.mod
+++ b/go.mod
@@ -2,8 +2,6 @@ module github.com/0xJacky/Nginx-UI
go 1.19
-replace github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a => github.com/0xJacky/gonginx v0.0.0-20230104051937-4c3a63627efb
-
require (
github.com/creack/pty v1.1.18
github.com/dustin/go-humanize v1.0.0
@@ -21,7 +19,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/shirou/gopsutil/v3 v3.21.7
github.com/spf13/cast v1.3.1
- github.com/tufanbarisyildirim/gonginx v0.0.0-20220829083426-44da4d61ef9a
+ github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed
github.com/unknwon/com v1.0.1
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
gopkg.in/ini.v1 v1.62.0
diff --git a/go.sum b/go.sum
index 50c0475d..d8d0a3d9 100644
--- a/go.sum
+++ b/go.sum
@@ -432,6 +432,8 @@ github.com/tklauser/numcpus v0.2.3 h1:nQ0QYpiritP6ViFhrKYsiv6VVxOpum2Gks5GhnJbS/
github.com/tklauser/numcpus v0.2.3/go.mod h1:vpEPS/JC+oZGGQ/My/vJnNsvMDQL6PwOqt8dsCw5j+E=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
+github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed h1:EyT9V+boG4nI4pzIuN4AWHQNvyM1LxNS21MC1CDSfg4=
+github.com/tufanbarisyildirim/gonginx v0.0.0-20230104065106-9ae864d29eed/go.mod h1:+uQMU+LMBHOQermcm/ICplG+r35Ypb6Up9iYKlvKuTE=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs=
diff --git a/server/api/ngx.go b/server/api/ngx.go
index 5ff13569..76c700b4 100644
--- a/server/api/ngx.go
+++ b/server/api/ngx.go
@@ -1,33 +1,47 @@
package api
import (
- "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
- "github.com/gin-gonic/gin"
- "net/http"
+ "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
- }
+ var ngxConf nginx.NgxConfig
+ if !BindAndValid(c, &ngxConf) {
+ return
+ }
- c.JSON(http.StatusOK, gin.H{
- "content": ngxConf.BuildConfig(),
- })
+ 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
+ }
- ngxConfig := nginx.ParseNgxConfigByContent(json.Content)
+ 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"`
+ }
+
+ if !BindAndValid(c, &json) {
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{
+ "content": nginx.FmtCode(json.Content),
+ })
+}
diff --git a/server/api/template.go b/server/api/template.go
index c7b5a5cb..db6d1b04 100644
--- a/server/api/template.go
+++ b/server/api/template.go
@@ -1,10 +1,15 @@
package api
import (
+ "bufio"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/0xJacky/Nginx-UI/server/settings"
+ "github.com/0xJacky/Nginx-UI/template"
"github.com/gin-gonic/gin"
+ "io"
"net/http"
+ "path/filepath"
+ "regexp"
"strings"
)
@@ -57,3 +62,81 @@ proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
"tokenized": ngxConfig,
})
}
+
+func GetTemplateConfList(c *gin.Context) {
+ configs, err := template.DistFS.ReadDir("conf")
+ if err != nil {
+ ErrHandler(c, err)
+ return
+ }
+ type configItem struct {
+ Name string `json:"name"`
+ Description map[string]string `json:"description"`
+ Author string `json:"author"`
+ }
+
+ var configList []configItem
+ for _, config := range configs {
+ func() {
+ configListItem := configItem{
+ Description: make(map[string]string),
+ }
+
+ file, _ := template.DistFS.Open(filepath.Join("conf", config.Name()))
+ defer file.Close()
+ r := bufio.NewReader(file)
+ bytes, _, err := r.ReadLine()
+ if err == io.EOF {
+ return
+ }
+ line := strings.TrimSpace(string(bytes))
+
+ if line != "# Nginx UI Template Start" {
+ return
+ }
+ var content string
+ for {
+ bytes, _, err = r.ReadLine()
+ if err == io.EOF {
+ break
+ }
+ line = strings.TrimSpace(string(bytes))
+ if line == "# Nginx UI Template End" {
+ break
+ }
+ content += line + "\n"
+ }
+ re := regexp.MustCompile(`# (\S+): (.*)`)
+ matches := re.FindAllStringSubmatch(content, -1)
+ for _, match := range matches {
+ if len(match) < 3 {
+ continue
+ }
+ key := match[1]
+ switch {
+ case key == "Name":
+ configListItem.Name = match[2]
+ case key == "Author":
+ configListItem.Author = match[2]
+ case strings.Contains(key, "Description"):
+ re = regexp.MustCompile(`(\w+)\[(\w+)\]`)
+ matches = re.FindAllStringSubmatch(key, -1)
+ for _, m := range matches {
+ if len(m) < 3 {
+ continue
+ }
+ // lang => description
+ configListItem.Description[m[2]] = match[2]
+ }
+ }
+ }
+
+ configList = append(configList, configListItem)
+ }()
+
+ }
+
+ c.JSON(http.StatusOK, gin.H{
+ "data": configList,
+ })
+}
diff --git a/server/pkg/nginx/format_code.go b/server/pkg/nginx/format_code.go
index 48a4d15e..08f81f7b 100644
--- a/server/pkg/nginx/format_code.go
+++ b/server/pkg/nginx/format_code.go
@@ -2,9 +2,17 @@ package nginx
import (
"github.com/tufanbarisyildirim/gonginx"
+ "github.com/tufanbarisyildirim/gonginx/parser"
)
func (c *NgxConfig) FmtCode() (fmtContent string) {
fmtContent = gonginx.DumpConfig(c.c, gonginx.IndentedStyle)
return
}
+
+func FmtCode(content string) (fmtContent string) {
+ p := parser.NewStringParser(content)
+ c := p.Parse()
+ fmtContent = gonginx.DumpConfig(c, gonginx.IndentedStyle)
+ return
+}
diff --git a/server/router/routers.go b/server/router/routers.go
index e782a106..6a6986ed 100644
--- a/server/router/routers.go
+++ b/server/router/routers.go
@@ -60,6 +60,8 @@ func InitRouter() *gin.Engine {
g.POST("ngx/build_config", api.BuildNginxConfig)
// Tokenized nginx configuration to NgxConf
g.POST("ngx/tokenize_config", api.TokenizeNginxConfig)
+ // Format nginx configuration code
+ g.POST("ngx/format_code", api.FormatNginxConfig)
g.POST("domain/:name/enable", api.EnableDomain)
g.POST("domain/:name/disable", api.DisableDomain)
@@ -74,6 +76,7 @@ func InitRouter() *gin.Engine {
//g.GET("backup/:id", api.GetFileBackup)
g.GET("template", api.GetTemplate)
+ g.GET("template/configs", api.GetTemplateConfList)
g.GET("cert/issue", api.IssueCert)
diff --git a/template/block/codeigniter.conf b/template/block/codeigniter.conf
new file mode 100644
index 00000000..349a267d
--- /dev/null
+++ b/template/block/codeigniter.conf
@@ -0,0 +1,3 @@
+location / {
+ try_files $uri $uri/ /index.php;
+}
\ No newline at end of file
diff --git a/template/block/laravel.conf b/template/block/laravel.conf
new file mode 100644
index 00000000..9bacbc43
--- /dev/null
+++ b/template/block/laravel.conf
@@ -0,0 +1,3 @@
+location / {
+ try_files $uri $uri/ /server.php?$query_string;
+}
diff --git a/template/conf/nginx-ui.conf b/template/conf/nginx-ui.conf
new file mode 100644
index 00000000..ea38c4e8
--- /dev/null
+++ b/template/conf/nginx-ui.conf
@@ -0,0 +1,33 @@
+# Nginx UI Template Start
+# Name: Nginx UI
+# Description[en]: Nginx UI Config Template
+# Description[zh_CN]: Nginx UI 配置模板
+# Author: @0xJacky
+# Nginx UI Template End
+map $http_upgrade $connection_upgrade {
+ default upgrade;
+ '' close;
+}
+server {
+ listen 80;
+ listen [::]:80;
+ server_name ;
+ rewrite ^(.*)$ https://$host$1 permanent;
+}
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name ;
+ ssl_certificate ;
+ ssl_certificate_key ;
+ location / {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection $connection_upgrade;
+ proxy_pass http://127.0.0.1:9000/;
+ }
+}
diff --git a/template/conf/wordpress.conf b/template/conf/wordpress.conf
new file mode 100644
index 00000000..d9912f78
--- /dev/null
+++ b/template/conf/wordpress.conf
@@ -0,0 +1,45 @@
+# Nginx UI Template Start
+# Name: WordPress-PHP8.1
+# Description[en]: WordPress PHP 8.1 Config Template
+# Description[zh_CN]: WordPress PHP 8.1 配置模板
+# Author: @0xJacky
+# Nginx UI Template End
+server {
+ listen 80;
+ listen [::]:80;
+ server_name ;
+ rewrite ^(.*)$ https://$host$1 permanent;
+}
+
+server {
+ listen 443 ssl http2;
+ listen [::]:443 ssl http2;
+ server_name ;
+ ssl_certificate ;
+ ssl_certificate_key ;
+ root ;
+ index index.php;
+
+ location ~ [^/]\.php(/|$) {
+ try_files $uri =404;
+ fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
+ fastcgi_index index.php;
+ include fastcgi.conf;
+ }
+
+
+ location / {
+ try_files $uri $uri/ /index.php?$args;
+ }
+
+ # Add trailing slash to */wp-admin requests.
+ rewrite /wp-admin$ $scheme://$host$uri/ permanent;
+
+ location /.well-known {
+ proxy_set_header Host $host;
+ proxy_set_header X-Real_IP $remote_addr;
+ proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
+ proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
+ }
+
+}
diff --git a/template/template.go b/template/template.go
index 1c424a74..43959d82 100644
--- a/template/template.go
+++ b/template/template.go
@@ -2,5 +2,5 @@ package template
import "embed"
-//go:embed *
+//go:embed conf/* block/*
var DistFS embed.FS