mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2025-05-12 02:45:49 +02:00
enhance: block template parser
This commit is contained in:
parent
f36e582976
commit
f15e66e0de
20 changed files with 249 additions and 108 deletions
|
@ -18,6 +18,10 @@ class Template extends Curd {
|
||||||
return http.get('template/block/' + name)
|
return http.get('template/block/' + name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_block(name: string, data: any) {
|
||||||
|
return http.post('template/block/' + name, data)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const template = new Template('/template')
|
const template = new Template('/template')
|
||||||
|
|
|
@ -6,7 +6,7 @@ import {useRoute, useRouter} from 'vue-router'
|
||||||
import {useGettext} from 'vue3-gettext'
|
import {useGettext} from 'vue3-gettext'
|
||||||
import Cert from '@/views/domain/cert/Cert.vue'
|
import Cert from '@/views/domain/cert/Cert.vue'
|
||||||
import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
|
import LogEntry from '@/views/domain/ngx_conf/LogEntry.vue'
|
||||||
import ConfigTemplate from '@/views/domain/ngx_conf/ConfigTemplate.vue'
|
import ConfigTemplate from '@/views/domain/ngx_conf/config_template/ConfigTemplate.vue'
|
||||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||||
import {PlusOutlined} from '@ant-design/icons-vue'
|
import {PlusOutlined} from '@ant-design/icons-vue'
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {useGettext} from 'vue3-gettext'
|
import {useGettext} from 'vue3-gettext'
|
||||||
import template from '@/api/template'
|
import template from '@/api/template'
|
||||||
import {computed, ref} from 'vue'
|
import {computed, provide, ref, watch} from 'vue'
|
||||||
import {storeToRefs} from 'pinia'
|
import {storeToRefs} from 'pinia'
|
||||||
import {useSettingsStore} from '@/pinia'
|
import {useSettingsStore} from '@/pinia'
|
||||||
import Template from '@/views/template/Template.vue'
|
import Template from '@/views/template/Template.vue'
|
||||||
import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
|
import DirectiveEditor from '@/views/domain/ngx_conf/directive/DirectiveEditor.vue'
|
||||||
import LocationEditor from '@/views/domain/ngx_conf/LocationEditor.vue'
|
import LocationEditor from '@/views/domain/ngx_conf/LocationEditor.vue'
|
||||||
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
import CodeEditor from '@/components/CodeEditor/CodeEditor.vue'
|
||||||
|
import TemplateForm from '@/views/domain/ngx_conf/config_template/TemplateForm.vue'
|
||||||
|
import * as wasi from 'wasi'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
const {$gettext} = useGettext()
|
const {$gettext} = useGettext()
|
||||||
const {language} = storeToRefs(useSettingsStore())
|
const {language} = storeToRefs(useSettingsStore())
|
||||||
|
@ -16,6 +19,7 @@ const props = defineProps(['ngx_config', 'current_server_index'])
|
||||||
const blocks = ref([])
|
const blocks = ref([])
|
||||||
const data: any = ref({})
|
const data: any = ref({})
|
||||||
const visible = ref(false)
|
const visible = ref(false)
|
||||||
|
const name = ref('')
|
||||||
|
|
||||||
function get_block_list() {
|
function get_block_list() {
|
||||||
template.get_block_list().then(r => {
|
template.get_block_list().then(r => {
|
||||||
|
@ -25,9 +29,11 @@ function get_block_list() {
|
||||||
|
|
||||||
get_block_list()
|
get_block_list()
|
||||||
|
|
||||||
function view(name: string) {
|
|
||||||
|
function view(n: string) {
|
||||||
visible.value = true
|
visible.value = true
|
||||||
template.get_block(name).then(r => {
|
name.value = n
|
||||||
|
template.get_block(n).then(r => {
|
||||||
data.value = r
|
data.value = r
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -54,6 +60,20 @@ async function add() {
|
||||||
|
|
||||||
visible.value = false
|
visible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const variables = computed(() => {
|
||||||
|
return data.value.variables
|
||||||
|
})
|
||||||
|
|
||||||
|
function build_template() {
|
||||||
|
template.build_block(name.value, variables.value).then(r => {
|
||||||
|
data.value.directives = r.directives
|
||||||
|
data.value.locations = r.locations
|
||||||
|
data.value.custom = r.custom
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
provide('build_template', build_template)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -88,6 +108,7 @@ async function add() {
|
||||||
>
|
>
|
||||||
<p>{{ $gettext('Author') }}: {{ data.author }}</p>
|
<p>{{ $gettext('Author') }}: {{ data.author }}</p>
|
||||||
<p>{{ $gettext('Description') }}: {{ trans_description(data) }}</p>
|
<p>{{ $gettext('Description') }}: {{ trans_description(data) }}</p>
|
||||||
|
<template-form :data="data.variables"/>
|
||||||
<template v-if="data.custom">
|
<template v-if="data.custom">
|
||||||
<h2>{{ $gettext('Custom') }}</h2>
|
<h2>{{ $gettext('Custom') }}</h2>
|
||||||
<code-editor v-model:content="data.custom" default-height="150px"/>
|
<code-editor v-model:content="data.custom" default-height="150px"/>
|
|
@ -0,0 +1,15 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import TemplateFormItem from '@/views/domain/ngx_conf/config_template/TemplateFormItem.vue'
|
||||||
|
|
||||||
|
const props = defineProps(['data'])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-form layout="vertical">
|
||||||
|
<template-form-item v-for="(v,k) in data" :name="k" :data="v"/>
|
||||||
|
</a-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
|
@ -0,0 +1,33 @@
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {computed, inject, watch} from 'vue'
|
||||||
|
import {storeToRefs} from 'pinia'
|
||||||
|
import {useSettingsStore} from '@/pinia'
|
||||||
|
import {useGettext} from 'vue3-gettext'
|
||||||
|
import _ from 'lodash'
|
||||||
|
|
||||||
|
const {$gettext} = useGettext()
|
||||||
|
|
||||||
|
const {language} = storeToRefs(useSettingsStore())
|
||||||
|
const props = defineProps(['data', 'name'])
|
||||||
|
|
||||||
|
const trans_name = computed(() => {
|
||||||
|
return props.data?.name?.[language.value] ?? props.data?.name?.en ?? ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const build_template: any = inject('build_template')!
|
||||||
|
|
||||||
|
const value = computed(() => props.data.value)
|
||||||
|
|
||||||
|
watch(value, _.throttle(build_template, 500))
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-form-item :label="trans_name">
|
||||||
|
<a-input v-if="data.type === 'string'" v-model:value="data.value"/>
|
||||||
|
<a-switch v-else-if="data.type === 'boolean'" v-model:checked="data.value"/>
|
||||||
|
</a-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
|
||||||
|
</style>
|
1
go.mod
1
go.mod
|
@ -33,6 +33,7 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||||
github.com/StackExchange/wmi v1.2.1 // indirect
|
github.com/StackExchange/wmi v1.2.1 // indirect
|
||||||
github.com/bytedance/sonic v1.8.7 // indirect
|
github.com/bytedance/sonic v1.8.7 // indirect
|
||||||
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
github.com/cenkalti/backoff/v4 v4.2.0 // indirect
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -1,3 +1,5 @@
|
||||||
|
github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak=
|
||||||
|
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||||
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
|
||||||
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA=
|
||||||
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8=
|
||||||
|
@ -71,6 +73,8 @@ github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWm
|
||||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
|
github.com/imdario/mergo v0.3.15 h1:M8XP7IuFNsqUx6VPK2P9OSmsYsI/YFaGil0uD21V3dM=
|
||||||
|
github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
|
||||||
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8=
|
||||||
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys=
|
||||||
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE=
|
||||||
|
|
|
@ -74,13 +74,22 @@ func GetTemplateBlock(c *gin.Context) {
|
||||||
service.ConfigInfoItem
|
service.ConfigInfoItem
|
||||||
service.ConfigDetail
|
service.ConfigDetail
|
||||||
}
|
}
|
||||||
detail, err := service.ParseTemplate("block", c.Param("name"))
|
var bindData map[string]service.TVariable
|
||||||
|
_ = c.ShouldBindJSON(&bindData)
|
||||||
|
info := service.GetTemplateInfo("block", c.Param("name"))
|
||||||
|
|
||||||
|
if bindData == nil {
|
||||||
|
bindData = info.Variables
|
||||||
|
}
|
||||||
|
|
||||||
|
detail, err := service.ParseTemplate("block", c.Param("name"), bindData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ErrHandler(c, err)
|
ErrHandler(c, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
info.Variables = bindData
|
||||||
c.JSON(http.StatusOK, resp{
|
c.JSON(http.StatusOK, resp{
|
||||||
service.GetTemplateInfo("block", c.Param("name")),
|
info,
|
||||||
detail,
|
detail,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,6 +80,7 @@ func InitRouter() *gin.Engine {
|
||||||
g.GET("template/configs", api.GetTemplateConfList)
|
g.GET("template/configs", api.GetTemplateConfList)
|
||||||
g.GET("template/blocks", api.GetTemplateBlockList)
|
g.GET("template/blocks", api.GetTemplateBlockList)
|
||||||
g.GET("template/block/:name", api.GetTemplateBlock)
|
g.GET("template/block/:name", api.GetTemplateBlock)
|
||||||
|
g.POST("template/block/:name", api.GetTemplateBlock)
|
||||||
|
|
||||||
g.GET("certs", api.GetCertList)
|
g.GET("certs", api.GetCertList)
|
||||||
g.GET("cert/:id", api.GetCert)
|
g.GET("cert/:id", api.GetCert)
|
||||||
|
|
|
@ -2,22 +2,33 @@ package service
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
"github.com/0xJacky/Nginx-UI/server/pkg/nginx"
|
||||||
"github.com/0xJacky/Nginx-UI/server/settings"
|
"github.com/0xJacky/Nginx-UI/server/settings"
|
||||||
"github.com/0xJacky/Nginx-UI/template"
|
templ "github.com/0xJacky/Nginx-UI/template"
|
||||||
|
"github.com/BurntSushi/toml"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/tufanbarisyildirim/gonginx/parser"
|
"github.com/tufanbarisyildirim/gonginx/parser"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"regexp"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TVariable struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Name map[string]string `json:"name"`
|
||||||
|
Value interface{} `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
type ConfigInfoItem struct {
|
type ConfigInfoItem struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Description map[string]string `json:"description"`
|
Description map[string]string `json:"description"`
|
||||||
Author string `json:"author"`
|
Author string `json:"author"`
|
||||||
Filename string `json:"filename"`
|
Filename string `json:"filename"`
|
||||||
|
Variables map[string]TVariable `json:"variables"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
|
func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
|
||||||
|
@ -26,7 +37,7 @@ func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
|
||||||
Filename: name,
|
Filename: name,
|
||||||
}
|
}
|
||||||
|
|
||||||
file, _ := template.DistFS.Open(filepath.Join(path, name))
|
file, _ := templ.DistFS.Open(filepath.Join(path, name))
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
r := bufio.NewReader(file)
|
r := bufio.NewReader(file)
|
||||||
bytes, _, err := r.ReadLine()
|
bytes, _, err := r.ReadLine()
|
||||||
|
@ -50,31 +61,11 @@ func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
|
||||||
}
|
}
|
||||||
content += line + "\n"
|
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]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
_, err = toml.Decode(content, &configListItem)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("toml.Decode", err.Error())
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,8 +74,8 @@ type ConfigDetail struct {
|
||||||
nginx.NgxServer
|
nginx.NgxServer
|
||||||
}
|
}
|
||||||
|
|
||||||
func ParseTemplate(path, name string) (c ConfigDetail, err error) {
|
func ParseTemplate(path, name string, bindData map[string]TVariable) (c ConfigDetail, err error) {
|
||||||
file, err := template.DistFS.Open(filepath.Join(path, name))
|
file, err := templ.DistFS.Open(filepath.Join(path, name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "error tokenized template")
|
err = errors.Wrap(err, "error tokenized template")
|
||||||
return
|
return
|
||||||
|
@ -113,7 +104,59 @@ func ParseTemplate(path, name string) (c ConfigDetail, err error) {
|
||||||
content += orig + "\n"
|
content += orig + "\n"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
content = strings.ReplaceAll(content, "{{ HTTP01PORT }}", settings.ServerSettings.HTTPChallengePort)
|
|
||||||
|
data := gin.H{
|
||||||
|
"HTTPPORT": settings.ServerSettings.HttpPort,
|
||||||
|
"HTTP01PORT": settings.ServerSettings.HTTPChallengePort,
|
||||||
|
}
|
||||||
|
|
||||||
|
for k, v := range bindData {
|
||||||
|
data[k] = v.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
t, err := template.New(name).Parse(custom)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "error parse template.custom")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var buf bytes.Buffer
|
||||||
|
|
||||||
|
err = t.Execute(&buf, data)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "error execute template")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
custom = strings.TrimSpace(buf.String())
|
||||||
|
|
||||||
|
templatePart := strings.Split(content, "# Nginx UI Template End")
|
||||||
|
if len(templatePart) < 2 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content = templatePart[1]
|
||||||
|
|
||||||
|
t, err = template.New(name).Parse(content)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "error parse template")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
|
||||||
|
err = t.Execute(&buf, data)
|
||||||
|
if err != nil {
|
||||||
|
err = errors.Wrap(err, "error execute template")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
content = buf.String()
|
||||||
|
|
||||||
|
log.Println(content)
|
||||||
|
|
||||||
p := parser.NewStringParser(content)
|
p := parser.NewStringParser(content)
|
||||||
config := p.Parse()
|
config := p.Parse()
|
||||||
c.Custom = custom
|
c.Custom = custom
|
||||||
|
@ -137,7 +180,7 @@ func ParseTemplate(path, name string) (c ConfigDetail, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetTemplateList(path string) (configList []ConfigInfoItem, err error) {
|
func GetTemplateList(path string) (configList []ConfigInfoItem, err error) {
|
||||||
configs, err := template.DistFS.ReadDir(path)
|
configs, err := templ.DistFS.ReadDir(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = errors.Wrap(err, "error get template list")
|
err = errors.Wrap(err, "error get template list")
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: Codeigniter Rewrite
|
name = "Codeigniter Rewrite"
|
||||||
# Description[en]: Codeigniter URL Rewrite Config
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: Codeigniter 伪静态配置
|
description = { en = "Codeigniter URL Rewrite Config", zh_CN = "Codeigniter 伪静态配置"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.php;
|
try_files $uri $uri/ /index.php;
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: PHP8.1
|
name = "PHP8.1"
|
||||||
# Description[en]: Enabled PHP 8.1 Config
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: 启用 PHP 8.1 配置
|
description = { en = "Enabled PHP 8.1 Config", zh_CN = "启用 PHP 8.1 配置"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
location ~ [^/]\.php(/|$)
|
location ~ [^/]\.php(/|$)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: HSTS
|
name = "HSTS"
|
||||||
# Description[en]: Enable HTTP Strict Transport Security
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: 启用 HTTP 严格传输安全
|
description = { en = "Enable HTTP Strict Transport Security", zh_CN = "启用 HTTP 严格传输安全"}
|
||||||
# Author: @0xJacky
|
|
||||||
|
[variables.maxAge]
|
||||||
|
type = "string"
|
||||||
|
name = { en = "Max Age", zh_CN = "有效时间"}
|
||||||
|
value = "31536000"
|
||||||
|
|
||||||
|
[variables.includeSubDomains]
|
||||||
|
type = "boolean"
|
||||||
|
name = { en = "Include sub domains", zh_CN = "包括子域名"}
|
||||||
|
value = true
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
|
|
||||||
|
add_header Strict-Transport-Security "max-age={{.maxAge}}; {{if .includeSubDomains}} includeSubDomains {{end}}" always;
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: HTTP to HTTPS
|
name = "HTTP to HTTPS"
|
||||||
# Description[en]: HTTP force redirect to HTTPS Config
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: HTTP 强制跳转 HTTPS 配置
|
description = { en = "HTTP force redirect to HTTPS Config", zh_CN = "HTTP 强制跳转 HTTPS 配置"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
return 307 https://$server_name$request_uri;
|
return 307 https://$server_name$request_uri;
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: Laravel Rewrite
|
name = "Laravel Rewrite"
|
||||||
# Description[en]: Laravel URL Rewrite Config
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: Laravel 伪静态配置
|
description = { en = "Laravel URL Rewrite Config", zh_CN = "Laravel 伪静态配置"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /server.php?$query_string;
|
try_files $uri $uri/ /server.php?$query_string;
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: Let's Encrypt
|
name = "Let's Encrypt"
|
||||||
# Description[en]: Let's Encrypt HTTPChallange
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: Let's Encrypt HTTP 鉴权
|
description = { en = "Let's Encrypt HTTPChallange", zh_CN = "Let's Encrypt HTTP 鉴权"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
|
|
||||||
location /.well-known/acme-challenge {
|
location /.well-known/acme-challenge {
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real_IP $remote_addr;
|
proxy_set_header X-Real_IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
|
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
|
||||||
proxy_pass http://127.0.0.1:{{ HTTP01PORT }};
|
proxy_pass http://127.0.0.1:{{.HTTP01PORT}};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: Nginx UI
|
name = "Nginx UI"
|
||||||
# Description[en]: Nginx UI Config Template
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: Nginx UI 配置模板
|
description = { en = "Nginx UI Config Templateg", zh_CN = "Nginx UI 配置模板"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
|
|
||||||
# Nginx UI Custom Start
|
# Nginx UI Custom Start
|
||||||
|
@ -19,5 +18,5 @@ location / {
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
proxy_set_header Connection $connection_upgrade;
|
proxy_set_header Connection $connection_upgrade;
|
||||||
proxy_pass http://127.0.0.1:9000/;
|
proxy_pass http://127.0.0.1:{{.HTTPPORT}}/;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,48 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: Reverse Proxy
|
name = "Reverse Proxy"
|
||||||
# Description[en]: Reverse Proxy Config
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: 反向代理配置
|
description = { en = "Reverse Proxy Config", zh_CN = "反向代理配置"}
|
||||||
# Author: @0xJacky
|
|
||||||
|
[variables.enableWebSocket]
|
||||||
|
type = "boolean"
|
||||||
|
name = { en = "Enable WebSocket", zh_CN = "启用 WebSocket"}
|
||||||
|
value = true
|
||||||
|
|
||||||
|
[variables.clientMaxBodySize]
|
||||||
|
type = "string"
|
||||||
|
name = { en = "Include sub domains", zh_CN = "客户端最大请求内容大小"}
|
||||||
|
value = "1000m"
|
||||||
|
|
||||||
|
[variables.port]
|
||||||
|
type = "string"
|
||||||
|
name = { en = "Port", zh_CN = "端口"}
|
||||||
|
value = 9000
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
|
|
||||||
|
|
||||||
|
# Nginx UI Custom Start
|
||||||
|
{{- if .enableWebSocket }}
|
||||||
|
map $http_upgrade $connection_upgrade {
|
||||||
|
default upgrade;
|
||||||
|
'' close;
|
||||||
|
}
|
||||||
|
{{- end }}
|
||||||
|
# Nginx UI Custom End
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://127.0.0.1:9000/;
|
{{ if .enableWebSocket }}
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection $connection_upgrade;
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
client_max_body_size {{ .clientMaxBodySize }};
|
||||||
|
|
||||||
proxy_redirect off;
|
proxy_redirect off;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
client_max_body_size 1000m;
|
|
||||||
|
proxy_pass http://127.0.0.1:{{ .port }}/;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
# Nginx UI Template Start
|
|
||||||
# Name: Reverse Proxy WebSocket
|
|
||||||
# Description[en]: Reverse Proxy with WebSocket Config
|
|
||||||
# Description[zh_CN]: 反向代理 WebSocket 配置
|
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
|
||||||
|
|
||||||
# Nginx UI Custom Start
|
|
||||||
map $http_upgrade $connection_upgrade {
|
|
||||||
default upgrade;
|
|
||||||
'' close;
|
|
||||||
}
|
|
||||||
# Nginx UI Custom End
|
|
||||||
|
|
||||||
location / {
|
|
||||||
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/;
|
|
||||||
proxy_redirect off;
|
|
||||||
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;
|
|
||||||
client_max_body_size 1000m;
|
|
||||||
}
|
|
|
@ -1,8 +1,7 @@
|
||||||
# Nginx UI Template Start
|
# Nginx UI Template Start
|
||||||
# Name: WordPress
|
name = "WordPress"
|
||||||
# Description[en]: WordPress Config Template
|
author = "@0xJacky"
|
||||||
# Description[zh_CN]: WordPress 配置模板
|
description = { en = "WordPress Config Template", zh_CN = "WordPress 配置模板"}
|
||||||
# Author: @0xJacky
|
|
||||||
# Nginx UI Template End
|
# Nginx UI Template End
|
||||||
location / {
|
location / {
|
||||||
try_files $uri $uri/ /index.php?$args;
|
try_files $uri $uri/ /index.php?$args;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue