Tokenized nginx config

This commit is contained in:
0xJacky 2022-07-26 11:49:37 +08:00
parent a3e7c58f53
commit 7abd5ce966
16 changed files with 534 additions and 107 deletions

View file

@ -187,7 +187,7 @@ docker run -dit \
- Make
- Golang 1.17+
- Golang 1.18+
- node.js 14+

View file

@ -187,7 +187,7 @@ docker run -dit \
- Make
- Golang 1.17+
- Golang 1.18+
- node.js 14+

View file

@ -186,7 +186,7 @@ On platforms that do not have an official build version, they can be built manua
- Make
- Golang 1.17+
- Golang 1.18+
- node.js 14+

View file

@ -51,7 +51,7 @@
"easygettext": "^2.17.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"yarn-audit-fix": "^9.1.2"
"yarn-audit-fix": "^9.3.2"
},
"eslintConfig": {
"root": true,

View file

@ -1,5 +1,4 @@
<template>
<!-- <codemirror v-model="current_value" :options="cmOptions"/>-->
<editor v-model="current_value" @init="editorInit" lang="nginx" theme="monokai" width="100%" height="1000"></editor>
</template>
<style lang="less">
@ -8,7 +7,6 @@
}
</style>
<script>
//import {codemirror} from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
import 'codemirror/theme/monokai.css'

View file

@ -1,17 +1,31 @@
<template>
<div>
<a-collapse :bordered="false" default-active-key="1">
<a-collapse-panel key="1">
<template v-slot:header>
<span style="margin-right: 10px">{{ $gettextInterpolate($gettext('Edit %{n}'), {n: name}) }}</span>
<a-tag color="blue" v-if="enabled">
{{ $gettext('Enabled') }}
</a-tag>
<a-tag color="orange" v-else>
{{ $gettext('Disabled') }}
</a-tag>
<a-card :bordered="false">
<template v-slot:title>
<span style="margin-right: 10px">{{ $gettextInterpolate($gettext('Edit %{n}'), {n: name}) }}</span>
<a-tag color="blue" v-if="enabled">
{{ $gettext('Enabled') }}
</a-tag>
<a-tag color="orange" v-else>
{{ $gettext('Disabled') }}
</a-tag>
</template>
<template v-slot:extra>
<a-switch size="small" v-model="advance_mode"/>
<template v-if="advance_mode">
{{ $gettext('Advance') }}
</template>
<div class="domain-edit-container">
<template v-else>
{{ $gettext('Basic') }}
</template>
</template>
<transition name="slide-fade">
<div v-if="advance_mode" key="advance">
<vue-itextarea v-model="configText"/>
</div>
<div class="domain-edit-container" key="basic" v-else>
<a-form-item :label="$gettext('Enabled')">
<a-switch v-model="enabled" @change="checked=>{checked?enable():disable()}"/>
</a-form-item>
@ -32,11 +46,8 @@
<p v-else v-translate>Make sure you have configured a reverse proxy for .well-known directory to HTTPChallengePort (default: 9180) before getting the certificate.</p>
</template>
</div>
</a-collapse-panel>
</a-collapse>
</transition>
<a-card :title="$gettext('Edit Configuration File')">
<vue-itextarea v-model="configText"/>
</a-card>
<footer-tool-bar>
@ -84,7 +95,8 @@ export default {
configText: '',
ws: null,
ok: false,
issuing_cert: false
issuing_cert: false,
advance_mode: false,
}
},
watch: {
@ -257,21 +269,7 @@ export default {
</script>
<style lang="less">
.ant-collapse {
background: #ffffff;
@media (prefers-color-scheme: dark) {
background: #28292c;
}
margin-bottom: 20px;
.ant-collapse-item {
border-bottom: unset;
}
}
.ant-collapse-content-box {
padding: 24px !important;
}
</style>
<style lang="less" scoped>
@ -290,4 +288,15 @@ export default {
}
}
.slide-fade-enter-active {
transition: all .5s ease-in-out;
}
.slide-fade-leave-active {
transition: all .5s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to
/* .slide-fade-leave-active for below version 2.1.8 */ {
transform: translateX(10px);
opacity: 0;
}
</style>

View file

@ -1490,10 +1490,10 @@
resolved "https://registry.npm.taobao.org/@types/range-parser/download/@types/range-parser-1.2.3.tgz?cache=0&sync_timestamp=1613379955500&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2F%40types%2Frange-parser%2Fdownload%2F%40types%2Frange-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c"
integrity sha1-fuMwunyq+5gJC+zoal7kQRWQTCw=
"@types/semver@^7.3.9":
version "7.3.9"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.9.tgz#152c6c20a7688c30b967ec1841d31ace569863fc"
integrity sha512-L/TMpyURfBkf+o/526Zb6kd/tchUP3iBDEPjqjb+U2MAJhVRxxrmr2fwpe08E7QsV7YLcpq0tUaQ9O9x97ZIxQ==
"@types/semver@^7.3.10":
version "7.3.10"
resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.10.tgz#5f19ee40cbeff87d916eedc8c2bfe2305d957f73"
integrity sha512-zsv3fsC7S84NN6nPK06u79oWgrPVd0NvOyqgghV1haPaFcVxIrP4DLomRwGAXk0ui4HZA7mOcSFL98sMVW9viw==
"@types/serve-static@*":
version "1.13.9"
@ -2227,14 +2227,14 @@ ansi-regex@^3.0.0:
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
ansi-regex@^4.1.0:
version "4.1.0"
resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc=
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
integrity "sha1-Fk2qyHqy1vbbOimHXi0XZlgtq+0= sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
ansi-regex@^5.0.0:
version "5.0.0"
resolved "https://registry.npm.taobao.org/ansi-regex/download/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha1-OIU59VF5vzkznIGvMKZU1p+Hy3U=
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
ansi-styles@^2.2.1:
version "2.2.1"
@ -2477,9 +2477,9 @@ async-validator@^3.0.3:
integrity sha512-DDmKA7sdSAJtTVeNZHrnr2yojfFaoeW8MfQN8CeuXg8DDQHTqKk9Fdv38dSvnesHoO8MUwMI2HphOeSyIF+wmQ==
async@^2.6.2:
version "2.6.3"
resolved "https://registry.npm.taobao.org/async/download/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff"
integrity sha1-1yYl4jRKNlbjo61Pp0n6gymdgv8=
version "2.6.4"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
integrity "sha1-cGt/9ghGZM1+rnE/b5ZUM7VQQiE= sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="
dependencies:
lodash "^4.17.14"
@ -3447,10 +3447,10 @@ commander@^7.2.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
commander@^9.2.0:
version "9.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.2.0.tgz#6e21014b2ed90d8b7c9647230d8b7a94a4a419a9"
integrity sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w==
commander@^9.3.0:
version "9.4.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c"
integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==
commander@~2.19.0:
version "2.19.0"
@ -4626,11 +4626,9 @@ events@^3.0.0:
integrity sha1-Mala0Kkk4tLEGagTrrLE6HjqdAA=
eventsource@^1.0.7:
version "1.0.7"
resolved "https://registry.npm.taobao.org/eventsource/download/eventsource-1.0.7.tgz#8fbc72c93fcd34088090bc0a4e64f4b5cee6d8d0"
integrity sha1-j7xyyT/NNAiAkLwKTmT0tc7m2NA=
dependencies:
original "^1.0.0"
version "1.1.2"
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.2.tgz#bc75ae1c60209e7cb1541231980460343eaea7c2"
integrity "sha1-vHWuHGAgnnyxVBIxmARgND6up8I= sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA=="
evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
version "1.0.3"
@ -5019,9 +5017,9 @@ flush-write-stream@^1.0.0:
readable-stream "^2.3.6"
follow-redirects@^1.0.0:
version "1.13.3"
resolved "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.13.3.tgz#e5598ad50174c1bc4e872301e82ac2cd97f90267"
integrity sha1-5VmK1QF0wbxOhyMB6CrCzZf5Amc=
version "1.15.1"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
integrity "sha1-DKakUjBsmyduTTEnSD4pV14getU= sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA=="
follow-redirects@^1.14.0:
version "1.15.0"
@ -5272,10 +5270,10 @@ globals@^12.1.0:
dependencies:
type-fest "^0.8.1"
globby@^13.1.1:
version "13.1.1"
resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.1.tgz#7c44a93869b0b7612e38f22ed532bfe37b25ea6f"
integrity sha512-XMzoDZbGZ37tufiv7g0N4F/zp3zkwdFtVbV3EHsVl1KQr4RPLfNoT068/97RPshz2J5xYNEjLKKBKaGHifBd3Q==
globby@^13.1.2:
version "13.1.2"
resolved "https://registry.yarnpkg.com/globby/-/globby-13.1.2.tgz#29047105582427ab6eca4f905200667b056da515"
integrity sha512-LKSDZXToac40u8Q1PQtZihbNdTYSNMuWe+K5l+oa6KgDzSvVrHXlJy40hUP522RjAIoNLJYBJi7ow+rbFpIhHQ==
dependencies:
dir-glob "^3.0.1"
fast-glob "^3.2.11"
@ -6933,9 +6931,9 @@ minimist-options@4.1.0:
kind-of "^6.0.3"
minimist@^1.2.0, minimist@^1.2.5:
version "1.2.5"
resolved "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=
version "1.2.6"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
integrity "sha1-hjelt1nqDW6YcCz7OpKDMjyTr0Q= sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
minipass-collect@^1.0.2:
version "1.0.2"
@ -7010,9 +7008,9 @@ mkdirp@^1.0.3:
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
moment@^2.10.2, moment@^2.21.0, moment@^2.24.0:
version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity "sha1-Pb4FKIn+fBsu2Wb8s6dzKJZO8Qg= sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w=="
move-concurrently@^1.0.1:
version "1.0.1"
@ -7546,13 +7544,6 @@ ora@^3.4.0:
strip-ansi "^5.2.0"
wcwidth "^1.0.1"
original@^1.0.0:
version "1.0.2"
resolved "https://registry.npm.taobao.org/original/download/original-1.0.2.tgz#e442a61cffe1c5fd20a65f3261c26663b303f25f"
integrity sha1-5EKmHP/hxf0gpl8yYcJmY7MD8l8=
dependencies:
url-parse "^1.4.3"
os-browserify@^0.3.0:
version "0.3.0"
resolved "https://registry.npm.taobao.org/os-browserify/download/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27"
@ -9149,9 +9140,9 @@ shebang-regex@^3.0.0:
integrity sha1-rhbxZE2HPsrYQ7AwexQzYtTEIXI=
shell-quote@^1.6.1:
version "1.7.2"
resolved "https://registry.npm.taobao.org/shell-quote/download/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
integrity sha1-Z6fQLHbJ2iT5nSCAj8re0ODgS+I=
version "1.7.3"
resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123"
integrity "sha1-qkDtrBcERbmkMeF7tiwLiBucQSM= sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw=="
signal-exit@^3.0.0, signal-exit@^3.0.2:
version "3.0.3"
@ -9397,9 +9388,9 @@ ssri@^6.0.1:
figgy-pudding "^3.5.1"
ssri@^7.0.0, ssri@^7.1.0:
version "7.1.0"
resolved "https://registry.npm.taobao.org/ssri/download/ssri-7.1.0.tgz#92c241bf6de82365b5c7fb4bd76e975522e1294d"
integrity sha1-ksJBv23oI2W1x/tL126XVSLhKU0=
version "7.1.1"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-7.1.1.tgz#33e44f896a967158e3c63468e47ec46613b95b5f"
integrity sha512-w+daCzXN89PseTL99MkA+fxJEcU3wfaE/ah0i0lnOlpG1CYLJ2ZjzEry68YBKfLs4JfoTShrTEsJkAZuNZ/stw==
dependencies:
figgy-pudding "^3.5.1"
minipass "^3.1.1"
@ -9788,9 +9779,9 @@ terser-webpack-plugin@^2.3.6:
webpack-sources "^1.4.3"
terser@^4.1.2, terser@^4.6.12:
version "4.8.0"
resolved "https://registry.npm.taobao.org/terser/download/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17"
integrity sha1-YwVjQ9fHC7KfOvZlhlpG/gOg3xc=
version "4.8.1"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f"
integrity "sha1-oA5WNFYt4iOf1ATGSQUb9vwhFE8= sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw=="
dependencies:
commander "^2.20.0"
source-map "~0.6.1"
@ -10159,10 +10150,10 @@ url-loader@^2.2.0:
mime "^2.4.4"
schema-utils "^2.5.0"
url-parse@^1.4.3, url-parse@^1.4.7:
version "1.5.3"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862"
integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==
url-parse@^1.4.7:
version "1.5.10"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1"
integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==
dependencies:
querystringify "^2.1.1"
requires-port "^1.0.0"
@ -10809,23 +10800,23 @@ yargs@^16.0.0:
y18n "^5.0.5"
yargs-parser "^20.2.2"
yarn-audit-fix@^9.1.2:
version "9.3.1"
resolved "https://registry.yarnpkg.com/yarn-audit-fix/-/yarn-audit-fix-9.3.1.tgz#cd2ebdbcab13e38dc067134c7c2321ba311555c0"
integrity sha512-JM7aIHEwL0YoXoadOOpZQOCmHIRvt7jA7OBGNnOjRXKwdyvdc4EljjaZB9EjQ6xpj3NNRWoHebApjPUOx2E0tg==
yarn-audit-fix@^9.3.2:
version "9.3.2"
resolved "https://registry.yarnpkg.com/yarn-audit-fix/-/yarn-audit-fix-9.3.2.tgz#9268aeaf70faafd6d8b8a71d0b8c8d97d6b809ec"
integrity sha512-hRPu2FRTLF5kL+fgq6NZDVgvGV7zEO6ghgfXoFmseDtDzqBIfKbGVNL+XqJ1fIil70x6XyrQwyARyyrMZtxpaw==
dependencies:
"@types/find-cache-dir" "^3.2.1"
"@types/fs-extra" "^9.0.13"
"@types/lodash-es" "^4.17.6"
"@types/semver" "^7.3.9"
"@types/semver" "^7.3.10"
"@types/yarnpkg__lockfile" "^1.1.5"
"@yarnpkg/lockfile" "^1.1.0"
chalk "^5.0.1"
commander "^9.2.0"
commander "^9.3.0"
find-cache-dir "^3.3.2"
find-up "^6.3.0"
fs-extra "^10.1.0"
globby "^13.1.1"
globby "^13.1.2"
js-yaml "^4.1.0"
lodash-es "^4.17.21"
pkg-dir "^6.0.1"

3
go.mod
View file

@ -1,6 +1,6 @@
module github.com/0xJacky/Nginx-UI
go 1.17
go 1.18
require (
github.com/dustin/go-humanize v1.0.0
@ -28,6 +28,7 @@ require (
github.com/StackExchange/wmi v1.2.1 // indirect
github.com/cenkalti/backoff/v4 v4.1.0 // indirect
github.com/creack/pty v1.1.18 // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/golang/protobuf v1.3.4 // indirect

2
go.sum
View file

@ -97,6 +97,8 @@ github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25Kn
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/exoscale/egoscale v0.46.0/go.mod h1:mpEXBpROAa/2i5GC0r33rfxG+TxSEka11g1PIXt9+zc=

View file

@ -4,10 +4,6 @@ server {
server_name {{ server_name }};
root ;
index ;
location /.well-known {
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;

View file

@ -16,10 +16,6 @@ server {
ssl_certificate {{ ssl_certificate }};
ssl_certificate_key {{ ssl_certificate_key }};
root ;
index ;
location /.well-known {
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;

View file

@ -0,0 +1,78 @@
# this is a comments
upstream my-api {
server 127.0.0.1:9001;
server 127.0.0.1:9002;
}
# this is a comments
server {
# this is a comments
listen 8443 ssl http2;
listen [::]:8443 ssl http2;
server_name cloud.jackyu.cn;
# this is a comments
ssl_certificate /etc/nginx/ssl/jackyu.cn/alpha/jackyu.cn_server_cert.pem;
ssl_certificate_key /etc/nginx/ssl/jackyu.cn/alpha/jackyu.cn_key.pem;
fastcgi_hide_header X-Powered-By; # Remove X-Powered-By, which is an information leak
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Make a regex exception for `/.well-known` so that clients can still
# access it despite the existence of the regex rule
# `location ~ /(\.|autotest|...)` which would otherwise handle requests
# for `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location ^~ /.well-known
{
# The rules in this block are an adaptation of the rules
# in `.htaccess` that concern `/.well-known`.
location = /.well-known/carddav { return 301 /remote.php/dav/; }
location = /.well-known/caldav { return 301 /remote.php/dav/; }
location /.well-known/acme-challenge { try_files $uri $uri/ =404; }
location /.well-known/pki-validation {
try_files $uri $uri/ =404;
}
# Let Nextcloud's API for `/.well-known` URIs handle all other
# requests by passing them to the front-end controller.
return 301 /index.php$request_uri;
}
# set max upload size
client_max_body_size 8192M;
fastcgi_buffers 64 4K;
# Enable gzip but do not remove ETag headers
gzip on; gzip_vary on; location /x/ {} gzip_comp_level 4;
gzip_min_length 256;gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
# Uncomment if your server is build with the ngx_pagespeed module
# This module is currently not supported.
#pagespeed off;
location / {
if ( $http_user_agent ~ ^DavClnt ) {
return 302 /remote.php/webdav/$is_args$args;
}
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_intercept_errors on;
proxy_pass http://172.17.0.1:7000;
}
}

View file

@ -0,0 +1,42 @@
package test
import (
"fmt"
"github.com/0xJacky/Nginx-UI/server/tool/nginx"
"testing"
)
func TestNgxConfParse(t *testing.T) {
c, err := nginx.ParseNgxConfig("nextcloud_ngx.conf")
if err != nil {
t.Fatal(err)
}
fmt.Println(c.FileName)
// directive in root
fmt.Println("Upstream")
for _, u := range c.Upstreams {
fmt.Println("upstream name", u.Name)
fmt.Printf("comments\n%v", u.Comments)
for _, d := range u.Directives {
fmt.Println("u.Directives.d", d)
}
}
fmt.Println("==========================")
fmt.Println("Servers")
for _, s := range c.Servers {
fmt.Printf("comments\n%v", s.Comments)
for _, d := range s.Directives {
fmt.Println(d)
}
// locations
for _, location := range s.Locations {
fmt.Printf("comments\n%v", location.Comments)
fmt.Println("path", location.Path)
fmt.Println("content", location.Content)
fmt.Println("==========================")
}
}
}

129
server/tool/nginx/parse.go Normal file
View file

@ -0,0 +1,129 @@
package nginx
import (
"bufio"
"github.com/emirpasic/gods/stacks/linkedliststack"
"github.com/pkg/errors"
"os"
"strings"
"unicode"
)
const (
Server = "server"
Location = "location"
Upstream = "upstream"
CommentStart = "#"
Empty = ""
)
func matchParentheses(stack *linkedliststack.Stack, v int32) {
if v == '{' {
stack.Push(v)
} else if v == '}' {
// stack is not empty and the top is == '{'
if top, ok := stack.Peek(); ok && top == '{' {
stack.Pop()
} else {
// fail
stack.Push(v)
}
}
}
func parseDirective(scanner *bufio.Scanner) (d NgxDirective) {
text := strings.TrimSpace(scanner.Text())
// escape empty line or comment line
if len(text) < 1 {
return
}
if text[0] == '#' {
d.Directive = "#"
d.Params = strings.TrimLeft(text, "#")
return
}
sep := len(text) - 1
for k, v := range text {
if unicode.IsSpace(v) {
sep = k
break
}
}
d.Directive = text[0:sep]
d.Params = text[sep:]
stack := linkedliststack.New()
if d.Directive == Server || d.Directive == Upstream || d.Directive == Location {
// { } in one line
// location = /.well-known/carddav { return 301 /remote.php/dav/; }
if strings.Contains(d.Params, "{") {
for _, v := range d.Params {
matchParentheses(stack, v)
}
if stack.Empty() {
return
}
}
// location ^~ /.well-known {
// location ^~ /.well-known
// {
// location ^~ /.well-known
//
// {
// { } not in one line
for scanner.Scan() {
text = strings.TrimSpace(scanner.Text())
// escape empty line
if text == "" {
continue
}
d.Params += "\n" + scanner.Text()
for _, v := range text {
matchParentheses(stack, v)
if stack.Empty() {
break
}
}
if stack.Empty() {
break
}
}
}
d.Params = strings.TrimSpace(d.Params)
return
}
func ParseNgxConfig(filename string) (c *NgxConfig, err error) {
file, err := os.Open(filename)
if err != nil {
return nil, errors.Wrap(err, "error open file in ParseNgxConfig")
}
defer file.Close()
scanner := bufio.NewScanner(file)
c = NewNgxConfig(filename)
for scanner.Scan() {
d := parseDirective(scanner)
paramsScanner := bufio.NewScanner(strings.NewReader(d.Params))
switch d.Directive {
case Server:
c.parseServer(paramsScanner)
case Upstream:
c.parseUpstream(paramsScanner)
case CommentStart:
c.commentQueue.Enqueue(d.Params)
}
}
if err = scanner.Err(); err != nil {
return nil, errors.Wrap(err, "error scanner in ParseNgxConfig")
}
return c, nil
}

View file

@ -0,0 +1,111 @@
package nginx
import (
"bufio"
"regexp"
"strings"
"unicode"
)
func (c *NgxConfig) parseServer(scanner *bufio.Scanner) {
server := NewNgxServer()
server.Directives = make(NgxDirectives)
for scanner.Scan() {
d := parseDirective(scanner)
switch d.Directive {
case Location:
server.parseLocation(d.Params)
case CommentStart:
server.commentQueue.Enqueue(d.Params)
default:
server.parseDirective(d)
}
}
// attach comments which are over the current server
server.Comments = c.commentQueue.DequeueAllComments()
c.Servers = append(c.Servers, *server)
}
func (c *NgxConfig) parseUpstream(scanner *bufio.Scanner) {
upstream := NgxUpstream{}
upstream.Directives = make(NgxDirectives)
d := NgxDirective{}
for scanner.Scan() {
text := strings.TrimSpace(scanner.Text())
// escape empty line or comment line
if len(text) < 1 || text[0] == '#' {
return
}
sep := len(text) - 1
for k, v := range text {
if unicode.IsSpace(v) {
sep = k
break
}
}
d.Directive = text[0:sep]
d.Params = strings.Trim(text[sep:], ";")
if d.Directive == Server {
upstream.Directives[d.Directive] = append(upstream.Directives[d.Directive], d)
} else if upstream.Name == "" {
upstream.Name = d.Directive
}
}
// attach comments which are over the current upstream
upstream.Comments = c.commentQueue.DequeueAllComments()
c.Upstreams = append(c.Upstreams, upstream)
}
func (s *NgxServer) parseDirective(d NgxDirective) {
orig := d.Orig()
// handle inline comments
str, comments, _ := strings.Cut(orig, "#")
regExp := regexp.MustCompile("(\\S+?)\\s+{?(.+?)[;|}]")
matchSlice := regExp.FindAllStringSubmatch(str, -1)
for k, v := range matchSlice {
// [[gzip_min_length 256; gzip_min_length 256] [gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; gzip_proxied expired no-cache no-store private no_last_modified no_etag auth] [gzip on; gzip on] [gzip_vary on; gzip_vary on] [location /x/ {} location /x/ {] [gzip_comp_level 4; gzip_comp_level 4]]
if len(v) > 0 {
scanner := bufio.NewScanner(strings.NewReader(v[0]))
if scanner.Scan() {
d = parseDirective(scanner)
// inline location
if d.Directive == Location {
s.parseLocation(d.Orig())
} else {
if k == 0 {
d.Comments = s.commentQueue.DequeueAllComments()
} else if k == len(matchSlice)-1 {
d.Comments = comments
}
// trim right ';'
d.TrimParams()
// map[directive]=>[]Params
s.Directives[d.Directive] = append(s.Directives[d.Directive], d)
}
}
}
}
}
func (s *NgxServer) parseLocation(str string) {
path, content, _ := strings.Cut(str, "{")
content = strings.TrimSpace(content)
content = strings.Trim(content, "}")
location := NgxLocation{
Path: path,
Content: content,
}
location.Comments = s.commentQueue.DequeueAllComments()
s.Locations = append(s.Locations, location)
}

74
server/tool/nginx/type.go Normal file
View file

@ -0,0 +1,74 @@
package nginx
import (
"github.com/emirpasic/gods/queues/linkedlistqueue"
"strings"
)
type CommentQueue struct {
*linkedlistqueue.Queue
}
type NgxConfig struct {
FileName string `json:"file_name"`
Upstreams []NgxUpstream `json:"upstreams"`
Servers []NgxServer `json:"ngx_server"`
commentQueue *CommentQueue
}
type NgxServer struct {
ServerName string `json:"server_name"`
Directives NgxDirectives `json:"directives"`
Locations []NgxLocation `json:"locations"`
Comments string `json:"comments"`
commentQueue *CommentQueue
}
type NgxUpstream struct {
Name string `json:"name"`
Directives NgxDirectives `json:"directives"`
Comments string `json:"comments"`
}
type NgxDirective struct {
Directive string `json:"directive"`
Params string `json:"params"`
Comments string `json:"comments"`
}
type NgxDirectives map[string][]NgxDirective
type NgxLocation struct {
Path string `json:"path"`
Content string `json:"content"`
Comments string `json:"comments"`
}
func (c *CommentQueue) DequeueAllComments() (comments string) {
for !c.Empty() {
comment, ok := c.Dequeue()
if ok {
comments += strings.TrimSpace(comment.(string)) + "\n"
}
}
return
}
func (d *NgxDirective) Orig() string {
return d.Directive + " " + d.Params
}
func (d *NgxDirective) TrimParams() {
d.Params = strings.TrimRight(strings.TrimSpace(d.Params), ";")
return
}
func NewNgxServer() *NgxServer {
return &NgxServer{commentQueue: &CommentQueue{linkedlistqueue.New()}}
}
func NewNgxConfig(filename string) *NgxConfig {
return &NgxConfig{FileName: filename, commentQueue: &CommentQueue{linkedlistqueue.New()}}
}