diff --git a/README-zh_CN.md b/README-zh_CN.md
index ddc0c403..fe7c6dbb 100644
--- a/README-zh_CN.md
+++ b/README-zh_CN.md
@@ -187,7 +187,7 @@ docker run -dit \
- Make
-- Golang 1.17+
+- Golang 1.18+
- node.js 14+
diff --git a/README-zh_TW.md b/README-zh_TW.md
index 8b6297d6..77e291df 100644
--- a/README-zh_TW.md
+++ b/README-zh_TW.md
@@ -187,7 +187,7 @@ docker run -dit \
- Make
-- Golang 1.17+
+- Golang 1.18+
- node.js 14+
diff --git a/README.md b/README.md
index 329d96c4..c4281abf 100644
--- a/README.md
+++ b/README.md
@@ -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+
diff --git a/frontend/package.json b/frontend/package.json
index 2f067563..b86483ef 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -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,
diff --git a/frontend/src/components/VueItextarea/VueItextarea.vue b/frontend/src/components/VueItextarea/VueItextarea.vue
index f99b0f3d..5e2b1655 100644
--- a/frontend/src/components/VueItextarea/VueItextarea.vue
+++ b/frontend/src/components/VueItextarea/VueItextarea.vue
@@ -1,5 +1,4 @@
-
diff --git a/frontend/yarn.lock b/frontend/yarn.lock
index 098db6bd..6e5f8a41 100644
--- a/frontend/yarn.lock
+++ b/frontend/yarn.lock
@@ -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"
diff --git a/go.mod b/go.mod
index ad5354f1..05c7242f 100644
--- a/go.mod
+++ b/go.mod
@@ -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
diff --git a/go.sum b/go.sum
index 5b4ad7be..6736c3e3 100644
--- a/go.sum
+++ b/go.sum
@@ -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=
diff --git a/server/template/http-conf b/server/template/http-conf
index 08edfe22..7c633463 100644
--- a/server/template/http-conf
+++ b/server/template/http-conf
@@ -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;
diff --git a/server/template/https-conf b/server/template/https-conf
index b6f12a6b..b04d92f4 100644
--- a/server/template/https-conf
+++ b/server/template/https-conf
@@ -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;
diff --git a/server/test/nextcloud_ngx.conf b/server/test/nextcloud_ngx.conf
new file mode 100644
index 00000000..8dfd0cff
--- /dev/null
+++ b/server/test/nextcloud_ngx.conf
@@ -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;
+ }
+}
diff --git a/server/test/ngx_conf_parse_test.go b/server/test/ngx_conf_parse_test.go
new file mode 100644
index 00000000..ebed5f00
--- /dev/null
+++ b/server/test/ngx_conf_parse_test.go
@@ -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("==========================")
+ }
+ }
+
+}
diff --git a/server/tool/nginx/parse.go b/server/tool/nginx/parse.go
new file mode 100644
index 00000000..7b65395b
--- /dev/null
+++ b/server/tool/nginx/parse.go
@@ -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
+}
diff --git a/server/tool/nginx/tokenize.go b/server/tool/nginx/tokenize.go
new file mode 100644
index 00000000..8f4bea1f
--- /dev/null
+++ b/server/tool/nginx/tokenize.go
@@ -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)
+}
diff --git a/server/tool/nginx/type.go b/server/tool/nginx/type.go
new file mode 100644
index 00000000..18086341
--- /dev/null
+++ b/server/tool/nginx/type.go
@@ -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()}}
+}