From 7abd5ce966f1f6fa256460b7f55a911bdd6a64a0 Mon Sep 17 00:00:00 2001 From: 0xJacky Date: Tue, 26 Jul 2022 11:49:37 +0800 Subject: [PATCH] Tokenized nginx config --- README-zh_CN.md | 2 +- README-zh_TW.md | 2 +- README.md | 2 +- frontend/package.json | 2 +- .../components/VueItextarea/VueItextarea.vue | 2 - frontend/src/views/domain/DomainEdit.vue | 69 ++++++---- frontend/yarn.lock | 115 +++++++--------- go.mod | 3 +- go.sum | 2 + server/template/http-conf | 4 - server/template/https-conf | 4 - server/test/nextcloud_ngx.conf | 78 +++++++++++ server/test/ngx_conf_parse_test.go | 42 ++++++ server/tool/nginx/parse.go | 129 ++++++++++++++++++ server/tool/nginx/tokenize.go | 111 +++++++++++++++ server/tool/nginx/type.go | 74 ++++++++++ 16 files changed, 534 insertions(+), 107 deletions(-) create mode 100644 server/test/nextcloud_ngx.conf create mode 100644 server/test/ngx_conf_parse_test.go create mode 100644 server/tool/nginx/parse.go create mode 100644 server/tool/nginx/tokenize.go create mode 100644 server/tool/nginx/type.go 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()}} +}