diff --git a/_config.yml b/_config.yml index a578a4c..3f28c62 100644 --- a/_config.yml +++ b/_config.yml @@ -3,12 +3,12 @@ ## Source: https://github.com/hexojs/hexo/ # Site -title: Hexo -subtitle: '' -description: '' +title: test site +subtitle: 'subtitle' +description: 'description description description description' keywords: -author: John Doe -language: en +author: lensfrex +language: zh-cn timezone: '' # URL diff --git a/package-lock.json b/package-lock.json index d6b48a3..5c01a33 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.0.0", "dependencies": { "hexo": "^6.3.0", - "hexo-browsersync": "^0.3.0", "hexo-generator-archive": "^2.0.0", "hexo-generator-category": "^2.0.0", "hexo-generator-index": "^3.0.0", @@ -67,11 +66,6 @@ "node": ">=6.9.0" } }, - "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmmirror.com/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" - }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -80,24 +74,6 @@ "node": ">= 10" } }, - "node_modules/@types/cookie": { - "version": "0.4.1", - "resolved": "https://registry.npmmirror.com/@types/cookie/-/cookie-0.4.1.tgz", - "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" - }, - "node_modules/@types/cors": { - "version": "2.8.13", - "resolved": "https://registry.npmmirror.com/@types/cors/-/cors-2.8.13.tgz", - "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "20.3.1", - "resolved": "https://registry.npmmirror.com/@types/node/-/node-20.3.1.tgz", - "integrity": "sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==" - }, "node_modules/a-sync-waterfall": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz", @@ -244,27 +220,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, - "node_modules/async-each-series": { - "version": "0.1.1", - "resolved": "https://registry.npmmirror.com/async-each-series/-/async-each-series-0.1.1.tgz", - "integrity": "sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, - "node_modules/axios": { - "version": "0.21.4", - "resolved": "https://registry.npmmirror.com/axios/-/axios-0.21.4.tgz", - "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", - "dependencies": { - "follow-redirects": "^1.14.0" - } - }, "node_modules/babel-walk": { "version": "3.0.0-canary-5", "resolved": "https://registry.npmjs.org/babel-walk/-/babel-walk-3.0.0-canary-5.tgz", @@ -281,14 +241,6 @@ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, - "node_modules/base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", - "engines": { - "node": "^4.5.0 || >= 5.9" - } - }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -300,11 +252,6 @@ "node": ">= 0.8" } }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmmirror.com/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==" - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -338,217 +285,6 @@ "node": ">=8" } }, - "node_modules/browser-sync": { - "version": "2.29.3", - "resolved": "https://registry.npmmirror.com/browser-sync/-/browser-sync-2.29.3.tgz", - "integrity": "sha512-NiM38O6XU84+MN+gzspVmXV2fTOoe+jBqIBx3IBdhZrdeURr6ZgznJr/p+hQ+KzkKEiGH/GcC4SQFSL0jV49bg==", - "dependencies": { - "browser-sync-client": "^2.29.3", - "browser-sync-ui": "^2.29.3", - "bs-recipes": "1.3.4", - "chalk": "4.1.2", - "chokidar": "^3.5.1", - "connect": "3.6.6", - "connect-history-api-fallback": "^1", - "dev-ip": "^1.0.1", - "easy-extender": "^2.3.4", - "eazy-logger": "^4.0.1", - "etag": "^1.8.1", - "fresh": "^0.5.2", - "fs-extra": "3.0.1", - "http-proxy": "^1.18.1", - "immutable": "^3", - "localtunnel": "^2.0.1", - "micromatch": "^4.0.2", - "opn": "5.3.0", - "portscanner": "2.2.0", - "raw-body": "^2.3.2", - "resp-modifier": "6.0.2", - "rx": "4.1.0", - "send": "0.16.2", - "serve-index": "1.9.1", - "serve-static": "1.13.2", - "server-destroy": "1.0.1", - "socket.io": "^4.4.1", - "ua-parser-js": "^1.0.33", - "yargs": "^17.3.1" - }, - "bin": { - "browser-sync": "dist/bin.js" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/browser-sync-client": { - "version": "2.29.3", - "resolved": "https://registry.npmmirror.com/browser-sync-client/-/browser-sync-client-2.29.3.tgz", - "integrity": "sha512-4tK5JKCl7v/3aLbmCBMzpufiYLsB1+UI+7tUXCCp5qF0AllHy/jAqYu6k7hUF3hYtlClKpxExWaR+rH+ny07wQ==", - "dependencies": { - "etag": "1.8.1", - "fresh": "0.5.2", - "mitt": "^1.1.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/browser-sync-ui": { - "version": "2.29.3", - "resolved": "https://registry.npmmirror.com/browser-sync-ui/-/browser-sync-ui-2.29.3.tgz", - "integrity": "sha512-kBYOIQjU/D/3kYtUIJtj82e797Egk1FB2broqItkr3i4eF1qiHbFCG6srksu9gWhfmuM/TNG76jMfzAdxEPakg==", - "dependencies": { - "async-each-series": "0.1.1", - "chalk": "4.1.2", - "connect-history-api-fallback": "^1", - "immutable": "^3", - "server-destroy": "1.0.1", - "socket.io-client": "^4.4.1", - "stream-throttle": "^0.1.3" - } - }, - "node_modules/browser-sync/node_modules/connect": { - "version": "3.6.6", - "resolved": "https://registry.npmmirror.com/connect/-/connect-3.6.6.tgz", - "integrity": "sha512-OO7axMmPpu/2XuX1+2Yrg0ddju31B6xLZMWkJ5rYBu4YRmRVlOjvlY6kw2FJKiAzyxGwnrDUAG4s1Pf0sbBMCQ==", - "dependencies": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "~1.3.2", - "utils-merge": "1.0.1" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/browser-sync/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/browser-sync/node_modules/destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmmirror.com/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha512-3NdhDuEXnfun/z7x9GOElY49LoqVHoGScmOKwmxhsS8N5Y+Z8KyPPDnaSzqWgYt/ji4mqwfTS34Htrk0zPIXVg==" - }, - "node_modules/browser-sync/node_modules/finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha512-ejnvM9ZXYzp6PUPUyQBMBf0Co5VX2gr5H2VQe2Ui2jWXNlxv+PYZo8wpAymJNJdLsG1R4p+M4aynF8KuoUEwRw==", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/browser-sync/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/browser-sync/node_modules/http-errors/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/browser-sync/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/browser-sync/node_modules/mime": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "bin": { - "mime": "cli.js" - } - }, - "node_modules/browser-sync/node_modules/send": { - "version": "0.16.2", - "resolved": "https://registry.npmmirror.com/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dependencies": { - "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "~1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/browser-sync/node_modules/send/node_modules/statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/browser-sync/node_modules/serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmmirror.com/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", - "send": "0.16.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/browser-sync/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, - "node_modules/browser-sync/node_modules/statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmmirror.com/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha512-wuTCPGlJONk/a1kqZ4fQM2+908lC7fa7nPYpTC1EhnvqLX/IICbeP1OZGDtA374trpSq68YubKUMo8oRhN46yg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/bs-recipes": { - "version": "1.3.4", - "resolved": "https://registry.npmmirror.com/bs-recipes/-/bs-recipes-1.3.4.tgz", - "integrity": "sha512-BXvDkqhDNxXEjeGM8LFkSbR+jzmP/CYpCiVKYn+soB1dDldeU15EBNDkwVXndKuX35wnNUaPd0qSoQEAkmQtMw==" - }, "node_modules/bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -627,19 +363,6 @@ "fsevents": "~2.3.2" } }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmmirror.com/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -727,28 +450,6 @@ "node": ">= 0.10.0" } }, - "node_modules/connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmmirror.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/connect-injector": { - "version": "0.4.4", - "resolved": "https://registry.npmmirror.com/connect-injector/-/connect-injector-0.4.4.tgz", - "integrity": "sha512-hdBG8nXop42y2gWCqOV8y1O3uVk4cIU+SoxLCPyCUKRImyPiScoNiSulpHjoktRU1BdI0UzoUdxUa87thrcmHw==", - "dependencies": { - "debug": "^2.0.0", - "q": "^1.0.1", - "stream-buffers": "^0.2.3", - "uberproto": "^1.1.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/constantinople": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-4.0.1.tgz", @@ -758,26 +459,6 @@ "@babel/types": "^7.6.1" } }, - "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmmirror.com/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmmirror.com/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "dependencies": { - "object-assign": "^4", - "vary": "^1" - }, - "engines": { - "node": ">= 0.10" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -890,17 +571,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/dev-ip": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/dev-ip/-/dev-ip-1.0.1.tgz", - "integrity": "sha512-LmVkry/oDShEgSZPNgqCIp2/TlqtExeGmymru3uCELnfyjY11IzpAproLYs+1X88fXO6DBoYP3ul2Xo2yz2j6A==", - "bin": { - "dev-ip": "lib/dev-ip.js" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/doctypes": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz", @@ -981,28 +651,6 @@ "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/easy-extender": { - "version": "2.3.4", - "resolved": "https://registry.npmmirror.com/easy-extender/-/easy-extender-2.3.4.tgz", - "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", - "dependencies": { - "lodash": "^4.17.10" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/eazy-logger": { - "version": "4.0.1", - "resolved": "https://registry.npmmirror.com/eazy-logger/-/eazy-logger-4.0.1.tgz", - "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==", - "dependencies": { - "chalk": "4.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -1022,11 +670,6 @@ "node": ">=0.10.0" } }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmmirror.com/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", @@ -1035,128 +678,6 @@ "node": ">= 0.8" } }, - "node_modules/engine.io": { - "version": "6.5.0", - "resolved": "https://registry.npmmirror.com/engine.io/-/engine.io-6.5.0.tgz", - "integrity": "sha512-UlfoK1iD62Hkedw2TmuHdhDsZCGaAyp+LZ/AvnImjYBeWagA3qIEETum90d6shMeFZiDuGT66zVCdx1wKYKGGg==", - "dependencies": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.1.0", - "ws": "~8.11.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io-client": { - "version": "6.5.0", - "resolved": "https://registry.npmmirror.com/engine.io-client/-/engine.io-client-6.5.0.tgz", - "integrity": "sha512-C7eN3OKggSfd5g8IDgUA9guC8TNS6CEganKT7dL6Fp3q+FobcQ/WBn2Qq2XTL1vNTiFZfDzXohvqLuR9dWejdg==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1", - "engine.io-parser": "~5.1.0", - "ws": "~8.11.0", - "xmlhttprequest-ssl": "~2.0.0" - } - }, - "node_modules/engine.io-client/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/engine.io-client/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/engine.io-client/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/engine.io-parser": { - "version": "5.1.0", - "resolved": "https://registry.npmmirror.com/engine.io-parser/-/engine.io-parser-5.1.0.tgz", - "integrity": "sha512-enySgNiK5tyZFynt3z7iqBR+Bto9EVVVvDFuTT0ioHCGbzirZVGDGiQjZzEp8hWl6hd5FSVytJGuScX1C1C35w==", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/engine.io/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/engine.io/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/entities": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", @@ -1168,14 +689,6 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmmirror.com/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "engines": { - "node": ">=6" - } - }, "node_modules/escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1238,11 +751,6 @@ "node": ">= 0.6" } }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, "node_modules/fast-equals": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fast-equals/-/fast-equals-3.0.3.tgz", @@ -1308,19 +816,6 @@ "node": ">= 0.8" } }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", @@ -1342,24 +837,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha512-V3Z3WZWVUYd8hoCL5xfXJCaHWYzmtwW5XWYSlLgERi8PWd8bx1kUHUk8L1BT57e49oKnDDD180mjfrHc1yA9rg==", - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^3.0.0", - "universalify": "^0.1.0" - } - }, - "node_modules/fs-extra/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1383,14 +860,6 @@ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-intrinsic": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", @@ -1536,18 +1005,6 @@ "url": "https://opencollective.com/hexo" } }, - "node_modules/hexo-browsersync": { - "version": "0.3.0", - "resolved": "https://registry.npmmirror.com/hexo-browsersync/-/hexo-browsersync-0.3.0.tgz", - "integrity": "sha512-5grkDUG/jci1LgImUFHTGMhXRYFKYuBVVf1L62UAhd/IC/L3EfGtKXyPVqvxyVb4Pc5STY5tQR46xoBJLlWJNw==", - "dependencies": { - "browser-sync": "^2.18.13", - "connect-injector": "^0.4.4" - }, - "engines": { - "node": ">= 0.10.0" - } - }, "node_modules/hexo-cli": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/hexo-cli/-/hexo-cli-4.3.1.tgz", @@ -2032,19 +1489,6 @@ "node": ">= 0.8" } }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmmirror.com/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/http-proxy-agent": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", @@ -2123,14 +1567,6 @@ "node": ">=0.10.0" } }, - "node_modules/immutable": { - "version": "3.8.2", - "resolved": "https://registry.npmmirror.com/immutable/-/immutable-3.8.2.tgz", - "integrity": "sha512-15gZoQ38eYjEjxkorfbcgBKBL6R7T459OuK+CpcWt7O3KF4uPCx2tD0uFETlUDIyo+1789crbMhTvQBSR5yBMg==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2209,14 +1645,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -2236,14 +1664,6 @@ "node": ">=0.12.0" } }, - "node_modules/is-number-like": { - "version": "1.0.8", - "resolved": "https://registry.npmmirror.com/is-number-like/-/is-number-like-1.0.8.tgz", - "integrity": "sha512-6rZi3ezCyFcn5L71ywzz2bS5b2Igl1En3eTlZlvKjpz1n3IZLAYMbKYAIQgFmEu0GENg92ziU/faEOA/aixjbA==", - "dependencies": { - "lodash.isfinite": "^3.3.2" - } - }, "node_modules/is-plain-object": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", @@ -2376,136 +1796,40 @@ "canvas": "^2.5.0" }, "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha512-oBko6ZHlubVB5mRFkur5vgYR1UyqX+S6Y/oCfLhqNdcc2fYFlDpIoNc7AfKS1KOGcnNAkvsr0grLck9ANM815w==", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/jstransformer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", - "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", - "dependencies": { - "is-promise": "^2.0.0", - "promise": "^7.0.1" - } - }, - "node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/limiter": { - "version": "1.1.5", - "resolved": "https://registry.npmmirror.com/limiter/-/limiter-1.1.5.tgz", - "integrity": "sha512-FWWMIEOxz3GwUI4Ts/IvgVy6LPvoMPgjMdQ185nN6psJyBJ4yOpzqm695/h5umdLJg2vW3GR5iG11MAkR2AzJA==" - }, - "node_modules/localtunnel": { - "version": "2.0.2", - "resolved": "https://registry.npmmirror.com/localtunnel/-/localtunnel-2.0.2.tgz", - "integrity": "sha512-n418Cn5ynvJd7m/N1d9WVJISLJF/ellZnfsLnx8WBWGzxv/ntNcFkJ1o6se5quUhCplfLGBNL5tYHiq5WF3Nug==", - "dependencies": { - "axios": "0.21.4", - "debug": "4.3.2", - "openurl": "1.1.1", - "yargs": "17.1.1" - }, - "bin": { - "lt": "bin/lt.js" - }, - "engines": { - "node": ">=8.3.0" - } - }, - "node_modules/localtunnel/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmmirror.com/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/localtunnel/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { + "canvas": { "optional": true } } }, - "node_modules/localtunnel/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "engines": [ + "node >= 0.2.0" + ] }, - "node_modules/localtunnel/node_modules/yargs": { - "version": "17.1.1", - "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.1.1.tgz", - "integrity": "sha512-c2k48R0PwKIqKhPMWjeiF6y2xY/gPMUlro0sgxqXpbOIohWiLNXWslsootttv7E1e73QPAMQSg5FeySbVcpsPQ==", + "node_modules/jstransformer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz", + "integrity": "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==", "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=12" + "is-promise": "^2.0.0", + "promise": "^7.0.1" } }, - "node_modules/localtunnel/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, "engines": { - "node": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.isfinite": { - "version": "3.3.2", - "resolved": "https://registry.npmmirror.com/lodash.isfinite/-/lodash.isfinite-3.3.2.tgz", - "integrity": "sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==" - }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -2599,11 +1923,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/mitt": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/mitt/-/mitt-1.2.0.tgz", - "integrity": "sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==" - }, "node_modules/moize": { "version": "6.1.6", "resolved": "https://registry.npmjs.org/moize/-/moize-6.1.6.tgz", @@ -2768,30 +2087,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/openurl": { - "version": "1.1.1", - "resolved": "https://registry.npmmirror.com/openurl/-/openurl-1.1.1.tgz", - "integrity": "sha512-d/gTkTb1i1GKz5k3XE3XFV/PxQ1k45zDqGP2OA7YhgsaLoqm6qRvARAZOFer1fcXritWlGBRCu/UgeS4HAnXAA==" - }, - "node_modules/opn": { - "version": "5.3.0", - "resolved": "https://registry.npmmirror.com/opn/-/opn-5.3.0.tgz", - "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", - "dependencies": { - "is-wsl": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/opn/node_modules/is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==", - "engines": { - "node": ">=4" - } - }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -2884,27 +2179,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/portscanner": { - "version": "2.2.0", - "resolved": "https://registry.npmmirror.com/portscanner/-/portscanner-2.2.0.tgz", - "integrity": "sha512-IFroCz/59Lqa2uBvzK3bKDbDDIEaAY8XJ1jFxcLWTqosrsc32//P4VuSB2vZXoHiHqOmx8B5L5hnKOxL/7FlPw==", - "dependencies": { - "async": "^2.6.0", - "is-number-like": "^1.0.3" - }, - "engines": { - "node": ">=0.4", - "npm": ">=1.0.0" - } - }, - "node_modules/portscanner/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmmirror.com/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dependencies": { - "lodash": "^4.17.14" - } - }, "node_modules/prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", @@ -3062,15 +2336,6 @@ "node": ">=6" } }, - "node_modules/q": { - "version": "1.5.1", - "resolved": "https://registry.npmmirror.com/q/-/q-1.5.1.tgz", - "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==", - "engines": { - "node": ">=0.6.0", - "teleport": ">=0.2.0" - } - }, "node_modules/querystringify": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", @@ -3084,39 +2349,6 @@ "node": ">= 0.6" } }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmmirror.com/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmmirror.com/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -3141,14 +2373,6 @@ "node": ">=8.10.0" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -3170,28 +2394,11 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/resp-modifier": { - "version": "6.0.2", - "resolved": "https://registry.npmmirror.com/resp-modifier/-/resp-modifier-6.0.2.tgz", - "integrity": "sha512-U1+0kWC/+4ncRFYqQWTx/3qkfE6a4B/h3XXgmXypfa0SPZ3t7cbbaFk297PjQS/yov24R18h6OZe6iZwj3NSLw==", - "dependencies": { - "debug": "^2.2.0", - "minimatch": "^3.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, "node_modules/rfdc": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" }, - "node_modules/rx": { - "version": "4.1.0", - "resolved": "https://registry.npmmirror.com/rx/-/rx-4.1.0.tgz", - "integrity": "sha512-CiaiuN6gapkdl+cZUr67W6I8jquN4lkak3vtIsIWCl4XIPP8ffsoyN6/+PuGXnQy8Cu8W2y9Xxh31Rq4M6wUug==" - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -3276,55 +2483,6 @@ "node": ">= 0.8" } }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmmirror.com/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmmirror.com/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmmirror.com/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmmirror.com/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==" - }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -3339,11 +2497,6 @@ "node": ">= 0.8.0" } }, - "node_modules/server-destroy": { - "version": "1.0.1", - "resolved": "https://registry.npmmirror.com/server-destroy/-/server-destroy-1.0.1.tgz", - "integrity": "sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==" - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -3368,140 +2521,6 @@ "node": ">=8" } }, - "node_modules/socket.io": { - "version": "4.7.0", - "resolved": "https://registry.npmmirror.com/socket.io/-/socket.io-4.7.0.tgz", - "integrity": "sha512-eOpu7oCNiPGBHn9Falg0cAGivp6TpDI3Yt596fbsf+vln8kRLFWxXKrecFrybn/xNYVn9HcdJNAkYToCmTjsyg==", - "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "cors": "~2.8.5", - "debug": "~4.3.2", - "engine.io": "~6.5.0", - "socket.io-adapter": "~2.5.2", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-adapter": { - "version": "2.5.2", - "resolved": "https://registry.npmmirror.com/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", - "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", - "dependencies": { - "ws": "~8.11.0" - } - }, - "node_modules/socket.io-adapter/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmmirror.com/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/socket.io-client": { - "version": "4.7.0", - "resolved": "https://registry.npmmirror.com/socket.io-client/-/socket.io-client-4.7.0.tgz", - "integrity": "sha512-7Q8CeDrhuZzg4QLXl3tXlk5yb086oxYzehAVZRLiGCzCmtDneiHz1qHyyWcxhTgxXiokVpWQXoG/u60HoXSQew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.2", - "engine.io-client": "~6.5.0", - "socket.io-parser": "~4.2.4" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-client/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-client/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/socket.io-parser": { - "version": "4.2.4", - "resolved": "https://registry.npmmirror.com/socket.io-parser/-/socket.io-parser-4.2.4.tgz", - "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/socket.io-parser/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io-parser/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/socket.io/node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/socket.io/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -3524,34 +2543,6 @@ "node": ">= 0.6" } }, - "node_modules/stream-buffers": { - "version": "0.2.6", - "resolved": "https://registry.npmmirror.com/stream-buffers/-/stream-buffers-0.2.6.tgz", - "integrity": "sha512-ZRpmWyuCdg0TtNKk8bEqvm13oQvXMmzXDsfD4cBgcx5LouborvU5pm3JMkdTP3HcszyUI08AM1dHMXA5r2g6Sg==", - "engines": { - "node": ">= 0.3.0" - } - }, - "node_modules/stream-throttle": { - "version": "0.1.3", - "resolved": "https://registry.npmmirror.com/stream-throttle/-/stream-throttle-0.1.3.tgz", - "integrity": "sha512-889+B9vN9dq7/vLbGyuHeZ6/ctf5sNuGWsDy89uNxkFTAgzy0eK7+w5fL3KLNRTkLle7EgZGvHUphZW0Q26MnQ==", - "dependencies": { - "commander": "^2.2.0", - "limiter": "^1.0.5" - }, - "bin": { - "throttleproxy": "bin/throttleproxy.js" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/stream-throttle/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -3579,19 +2570,6 @@ } ] }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmmirror.com/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -3793,22 +2771,6 @@ "node": ">= 0.8.0" } }, - "node_modules/ua-parser-js": { - "version": "1.0.35", - "resolved": "https://registry.npmmirror.com/ua-parser-js/-/ua-parser-js-1.0.35.tgz", - "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", - "engines": { - "node": "*" - } - }, - "node_modules/uberproto": { - "version": "1.2.0", - "resolved": "https://registry.npmmirror.com/uberproto/-/uberproto-1.2.0.tgz", - "integrity": "sha512-pGtPAQmLwh+R9w81WVHzui1FfedpQWQpiaIIfPCwhtsBez4q6DYbJFfyXPVHPUTNFnedAvNEnkoFiLuhXIR94w==", - "engines": { - "node": "*" - } - }, "node_modules/universalify": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", @@ -3967,19 +2929,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4017,47 +2966,6 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" - }, - "node_modules/xmlhttprequest-ssl": { - "version": "2.0.0", - "resolved": "https://registry.npmmirror.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", - "integrity": "sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmmirror.com/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmmirror.com/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "engines": { - "node": ">=12" - } } } } diff --git a/package.json b/package.json index 74c9982..38ff83f 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ }, "dependencies": { "hexo": "^6.3.0", - "hexo-browsersync": "^0.3.0", "hexo-generator-archive": "^2.0.0", "hexo-generator-category": "^2.0.0", "hexo-generator-index": "^3.0.0", diff --git a/source/404.html b/source/404.html new file mode 100644 index 0000000..7bcf5ba --- /dev/null +++ b/source/404.html @@ -0,0 +1,28 @@ + + + + + +
+

+ +
+ 嗯? +
+

+

+

+

+

+ + + +

+

+ 啊哈!
+是不是来错地方了?

快回去吧~
+

+
+ + + \ No newline at end of file diff --git a/source/_discarded/Untitled.md b/source/_discarded/Untitled.md new file mode 100644 index 0000000..490a9cd --- /dev/null +++ b/source/_discarded/Untitled.md @@ -0,0 +1,5 @@ +title: Untitled +author: lensfrex +date: 2022-07-09 21:45:47 +tags: +--- diff --git a/source/_discarded/mysql踩坑.md b/source/_discarded/mysql踩坑.md new file mode 100644 index 0000000..5d0ee15 --- /dev/null +++ b/source/_discarded/mysql踩坑.md @@ -0,0 +1,97 @@ +title: mysql踩坑 +author: lensfrex +date: 2022-04-04 10:33:10 +tags: +--- +sudo /usr/bin/mysqld_safe & +het@iZbp1hzgpnnozttvvbihj7Z:/$ sudo find -name mysql.sock +find: ‘./proc/277011’: No such file or directory +het@iZbp1hzgpnnozttvvbihj7Z:/$ sudo find -name mysqladmincd^C +het@iZbp1hzgpnnozttvvbihj7Z:/$ cd etc/mysql +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql$ ls +conf.d debian.cnf debian-start my.cnf my.cnf.fallback mysql.cnf mysql.conf.d +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql$ cd conf.d +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/conf.d$ ls +mysql.cnf mysqldump.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/conf.d$ cd ../ +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql$ la +-bash: la: command not found +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql$ ls +conf.d debian.cnf debian-start my.cnf my.cnf.fallback mysql.cnf mysql.conf.d +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql$ cd mysql.conf.d +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ ls +mysql.cnf mysqld.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo nvim mysql.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo nvim mysqld.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo service mysql start +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo nvim mysqld.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ ls /var/run/mysqld/ +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo nvim mysqld.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ nvim /var/log/mysql/error.log +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ ls /var/log/mysql/ +ls: cannot open directory '/var/log/mysql/': Permission denied +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo nvim /var/log/mysql/error.log +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo nvim mysqld.cnf +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ sudo service mysql start + +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ +het@iZbp1hzgpnnozttvvbihj7Z:/etc/mysql/mysql.conf.d$ cd /etc/init.d +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ ls +aegis console-setup.sh hddtemp netfilter-persistent pppd-dns ssh +apparmor cron hwclock.sh network-manager procps status-server +apport cups irqbalance nginx-debug pulseaudio-enable-autospawn sysstat +atd cups-browsed keyboard-setup.sh ntp pureftpd udev +avahi-daemon dbus kmod php7.4-fpm resolvconf ufw +bluetooth fio lightdm plymouth rsync uuidd +boinc-client gdm3 lm-sensors plymouth-log rsyslog vsftpd +chrony grub-common mysql postfix screen-cleanup x11-common +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ cd mysql +-bash: cd: mysql: Not a directory +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ nvim mysql +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ sudo mysql +ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ sudo ./mysql +Usage: /etc/init.d/mysql start|stop|restart|reload|force-reload|status +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ sudo ./mysql start +Starting mysql (via systemctl): mysql.service. +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ sudo netstat -lapn | grep mysql +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ safe_mysqld& +[1] 285411 +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ -bash: safe_mysqld: command not found + +[1]+ Exit 127 safe_mysqld +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ safe_mysqld& +[1] 285486 +-bash: safe_mysqld: command not found +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ ^C +[1]+ Exit 127 safe_mysqld +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ safe_mysqld +-bash: safe_mysqld: command not found +het@iZbp1hzgpnnozttvvbihj7Z:/etc/init.d$ cd / +het@iZbp1hzgpnnozttvvbihj7Z:/$ sudo find -name mysqld_safe +./usr/bin/mysqld_safe +het@iZbp1hzgpnnozttvvbihj7Z:/$ /usr/bin/mysqld_safe & +[1] 286015 +het@iZbp1hzgpnnozttvvbihj7Z:/$ /usr/bin/mysqld_safe: 653: cannot create /var/log/mysql/error.log: Permission denied +Logging to '/var/log/mysql/error.log'. +2022-04-04T02:31:05.698613Z mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql +/usr/bin/mysqld_safe: 144: cannot create /var/log/mysql/error.log: Permission denied +/usr/bin/mysqld_safe: 1: eval: cannot create /var/log/mysql/error.log: Permission denied +/usr/bin/mysqld_safe: 916: cannot create /var/log/mysql/error.log: Permission denied +rm: cannot remove '/var/lib/mysql/iZbp1hzgpnnozttvvbihj7Z.pid.shutdown': Permission denied +2022-04-04T02:31:05.715768Z mysqld_safe mysqld from pid file /var/lib/mysql/iZbp1hzgpnnozttvvbihj7Z.pid ended +/usr/bin/mysqld_safe: 144: cannot create /var/log/mysql/error.log: Permission denied +^C +[1]+ Done /usr/bin/mysqld_safe +het@iZbp1hzgpnnozttvvbihj7Z:/$ sudo /usr/bin/mysqld_safe & +[1] 286238 +het@iZbp1hzgpnnozttvvbihj7Z:/$ 2022-04-04T02:31:13.353776Z mysqld_safe Logging to '/var/log/mysql/error.log'. +2022-04-04T02:31:13.384979Z mysqld_safe Starting mysqld daemon with databases from /var/lib/mysql + +het@iZbp1hzgpnnozttvvbihj7Z:/$ sudo netstat -lapn | grep mysql +tcp 0 0 127.0.0.1:33060 0.0.0.0:* LISTEN 286417/mysqld +tcp 0 0 127.0.0.1:3306 0.0.0.0:* LISTEN 286417/mysqld +unix 2 [ ACC ] STREAM LISTENING 256439674 286417/mysqld /var/run/mysqld/mysqlx.sock +unix 2 [ ACC ] STREAM LISTENING 256439696 286417/mysqld /var/run/mysqld/mysqld.sock +het@iZbp1hzgpnnozttvvbihj7Z:/$ sudo nginx +het@iZbp1hzgpnnozttvvbihj7Z:/$ diff --git a/source/_discarded/对docker容器使用ufw不生效的问题.md b/source/_discarded/对docker容器使用ufw不生效的问题.md new file mode 100644 index 0000000..b9a752e --- /dev/null +++ b/source/_discarded/对docker容器使用ufw不生效的问题.md @@ -0,0 +1,5 @@ +title: 对docker容器使用ufw不生效的问题 +author: lensfrex +date: 2022-07-29 15:42:50 +tags: +--- diff --git a/source/_drafts/docker-ufw.md b/source/_drafts/docker-ufw.md new file mode 100644 index 0000000..28c28d7 --- /dev/null +++ b/source/_drafts/docker-ufw.md @@ -0,0 +1,8 @@ +title: 对docker容器使用uwf不生效的问题 +author: lensfrex +date: 2022-07-29 16:07:16 +tags: +--- +"iptables": true + +但是docker内部就没法访问外网了 \ No newline at end of file diff --git a/source/_drafts/jackson-time-format.md b/source/_drafts/jackson-time-format.md new file mode 100644 index 0000000..81e6db3 --- /dev/null +++ b/source/_drafts/jackson-time-format.md @@ -0,0 +1,5 @@ +title: jackson中日期格式的自动处理 +author: lensfrex +date: 2022-07-15 21:18:14 +tags: +--- diff --git a/source/_drafts/linux-permission.md b/source/_drafts/linux-permission.md new file mode 100644 index 0000000..20c0332 --- /dev/null +++ b/source/_drafts/linux-permission.md @@ -0,0 +1,15 @@ +title: linux的权限代码含义解释 +author: lensfrex +tags: + - 学习 + - linux + - 权限管理 +categories: + - 学习 + - linux +date: 2022-04-29 16:56:00 +--- +最近接触到linux的权限管理,一些权限代码对于很多稍微用过linux的人来说很熟悉,什么`755`, `777`,`700`等等,但如果深入了解的话,就只能是背书似的去背有什么作用,但这些“7”、“6”、“0”究竟是些什么还是糊里糊涂(比如我←_←)。 + +所以在这里为了更加熟悉这些东西,在这里讲讲linux里边权限代码的数字的含义。 + diff --git a/source/_drafts/mybatis-plus-mysql-json.md b/source/_drafts/mybatis-plus-mysql-json.md new file mode 100644 index 0000000..2c6bd9c --- /dev/null +++ b/source/_drafts/mybatis-plus-mysql-json.md @@ -0,0 +1,6 @@ +title: mybatis-plus-mysql-json +author: lensfrex +date: 2022-07-15 21:38:08 +tags: +--- +@TableName(value = "notices_basic", autoResultMap = true) diff --git a/source/_drafts/mysql-33060.md b/source/_drafts/mysql-33060.md new file mode 100644 index 0000000..44dbe54 --- /dev/null +++ b/source/_drafts/mysql-33060.md @@ -0,0 +1,6 @@ +title: 关于mysql的33060端口问题 +author: lensfrex +date: 2022-07-29 16:41:49 +tags: +--- +今天把项目部署到服务器上,由于 \ No newline at end of file diff --git a/source/_drafts/spring-configuration.md b/source/_drafts/spring-configuration.md new file mode 100644 index 0000000..78f5cc4 --- /dev/null +++ b/source/_drafts/spring-configuration.md @@ -0,0 +1,5 @@ +--- +title: spring-configuration +author: lensfrex +tags: +--- diff --git a/source/_drafts/string-equals.md b/source/_drafts/string-equals.md new file mode 100644 index 0000000..ca4bb7b --- /dev/null +++ b/source/_drafts/string-equals.md @@ -0,0 +1,5 @@ +title: Java字符串equals()方法的一些小细节 +author: lensfrex +date: 2022-07-18 10:27:49 +tags: +--- diff --git a/source/_posts/hello-world.md b/source/_posts/hello-world.md index 1727930..6eae4cb 100644 --- a/source/_posts/hello-world.md +++ b/source/_posts/hello-world.md @@ -1,6 +1,18 @@ -title: Hello World -date: 2013-12-24 17:49:32 +title: 第一篇文章... tags: + - 闲聊 + - 日常 +categories: + - 闲聊 + - 日常 +author: lenfrex +cover: https://oss-img.ciduid.top/blog/covers/cover(15).png +date: 2022-02-23 17:34:00 --- +很久以前就试着建blog了,但是都只是在本地上跑服务器,最近想想好像前几个月在阿里云上买了一年的服务器好久一直没没动过🤦‍(捂脸),所以就打算在这里搭个blog和其他的东西玩玩。 -Welcome to [Hexo](http://zespia.tw/hexo)! This is your very first post. Check [documentation](http://zespia.tw/hexo/docs) to learn how to use. \ No newline at end of file +从一开始是想用wordpress搭的,但是折腾了一整天之后还是决定用hexo作为框架吧。 + +仔细想想确实没什么特别花哨的需求,只需要静态的网站页面就够了,用hexo不用太折腾,(而且js还是懂点,有问题有时直接改代码就好了🤣) + +*// 前几天交了备案,等着通过~~(不得不说可真是麻烦)~~,到时候直接用80/443端口就能访问,像普通网站一样,再也不用单独带一个端口号来访问了...(  ̄︿ ̄)* \ No newline at end of file diff --git a/source/_posts/http-servlet-tomcat.md b/source/_posts/http-servlet-tomcat.md index 372dd31..b796f64 100644 --- a/source/_posts/http-servlet-tomcat.md +++ b/source/_posts/http-servlet-tomcat.md @@ -1,514 +1,514 @@ -title: HTTP, Servlet, Tomcat -author: lensfrex -cover: https://oss-img.ciduid.top/blog/covers/topimage-xb3-pc.jpg -date: 2023-05-13 15:50:00 ---- -# 学习Servlet和Tomcat - -## 前置任务:了解学习HTTP - -如果你选了网络工程导论这门课,并且已经了解了HTTP相关的知识,则可以跳过本节,直接开主线任务:[传送点](#主线任务:Servlet,Tomcat),但是也可以重新开始学习这部分的内容。 - -想了解更多:[HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) - -### HTTP介绍 - -超文本传输协议(HyperText Transfer Protocol,HTTP)是一个应用层协议。所谓协议,就是数据传输格式的一个约定。 - -HTTP最初设计是用来传输html页面这种纯文本数据的,但是实际上只要声明好header,传输什么都是可以的,图片,文件等等,或者也可以摇身一变,变成另一个协议(grpc, 基于http2)来使用,总之,http其实是非常灵活的。 - -### HTTP消息 - -一个规范的,完整的HTTP消息结构是这样的: - -请求消息(GET方法): -地址:`https://github.com` - -```http -GET / HTTP/1.1 -Host: github.com -authority: github.com -accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 -accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 -user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 -content-length: 0 - - -``` - -请求消息(POST方法,带请求体): - -地址:`http://bkjx.wust.edu.cn/Logon.do?method=logon` - -```http -POST /Logon.do?method=logon HTTP/1.1 -Host: bkjx.wust.edu.cn -Proxy-Connection: Keep-Alive -Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 -Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 -Cache-Control: no-cache -Connection: keep-alive -Content-Type: application/x-www-form-urlencoded -Cookie: bzb_njw=303511D07EF501147333F6B099D16CB9; SERVERID=122 -Origin: http://bkjx.wust.edu.cn -Pragma: no-cache -Referer: http://bkjx.wust.edu.cn/ -Upgrade-Insecure-Requests: 1 -User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 -Content-Length: 94 - -userAccount=&userPassWorld=&encoded=dMcs2P8fNag0n1d03f0UVgu02^%^257F^%^25QF^%^25pcs0Ygd4fbgHs69 -``` - - -响应消息(header内容精简过): - -```http -HTTP/1.1 200 OK -Server: GitHub.com -Date: Sat, 13 May 2023 02:59:34 GMT -Content-Type: text/html; charset=utf-8 -Vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Language, Accept-Encoding, Accept, X-Requested-With -content-language: en-US -ETag: W/"bfeda72459b363617514a4f13882cece" -Set-Cookie: _octo=GH1.1.496438640.1683116779; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; Secure; SameSite=Lax -Accept-Ranges: bytes -Transfer-Encoding: chunked - - - - - - -...(还有一堆的网页内容) -``` - -请求和响应的消息体长得还挺像的,估计大家都能看出来了。 - -#### 第一行 -『起始行』与『状态行』 - -http请求消息中,第一行为『起始行』: -- `GET / HTTP/1.1` -- `GET /background.png HTTP/1.0` -- `POST /Logon.do?method=logon HTTP/1.1` - -起始行分为三个部分,分别定义了请求方法,请求目标和当前请求使用的http协议版本 - -第一个部分为『[请求方法](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods)』,一般有GET, POST, OPTIONS, PUT等好多种,但是实际使用几乎就只有GET和POST两种。 - -随后紧接着的部分是『请求目标』,在普通的http请求中也可以简单理解为请求路径,也就是咱们看到的浏览器地址后面的部分(xxx.com/abcd/efg中的/abcd/efg,bkjx.wust.edu.cn/Logon.do?method=logon中的/Logon.do?method=logon部分) - -在部分场合下,请求目标有时也是一个绝对路径的URL,如当使用HTTP代理访问网站时,浏览器向代理服务器(如软件)发送的数据也是一个http请求,只不过真实的请求放在了body部分,代理程序只负责原样发送数据:`CONNECT google.com:443 HTTP/1.1` - -这里就抄一下MDN的介绍: - -> - 一个绝对路径,末尾跟上一个 '?' 和查询字符串。这是最常见的形式,称为原始形式(origin form),被 GET、POST、HEAD 和 OPTIONS 方法所使用。 -> - - POST / HTTP/1.1 -> - - GET /background.png HTTP/1.0 -> - - HEAD /test.html?query=alibaba HTTP/1.1 -> - - OPTIONS /anypage.html HTTP/1.0 -> - 一个完整的 URL,被称为绝对形式(absolute form),主要在使用 GET 方法连接到代理时使用。GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1 -> - 由域名和可选端口(以 ':' 为前缀)组成的 URL 的 authority 部分,称为 authority form。仅在使用 CONNECT 建立 HTTP 隧道时才使用。CONNECT developer.mozilla.org:80 HTTP/1.1 -> - 星号形式(asterisk form),一个简单的星号('*'),配合 OPTIONS 方法使用,代表整个服务器。OPTIONS * HTTP/1.1 - -最后的一部分为『HTTP版本』,声明了这次请求使用的http版本。目前常用的版本有`HTTP/1.1`,`HTTP/2`,`HTTP/3`。 - -> 另外,和其他HTTP版本不同的是,HTTP/3版本是在基于UDP的QUIC协议之上实现传输的,QUIC是与TCP和UDP等同级(传输层)的协议,而其他的HTTP版本都是在TCP协议上实现的, - -对于响应消息,第一行为『状态行』。 -- `HTTP/1.1 200 OK` -- `HTTP/1.1 404 Not Found` -- `HTTP/1.1 500 Internal Server Error` **(心 脏 骤 停)** - -也是三个部分。 - -响应的状态行就挺简单的了。 - -第一个就不用说了。 - -第二个则为『状态码』,就是咱们常见的404, 200这些,表明了服务端处理请求的结果状态。 - -第三个部分则为『状态文本』,其实就是状态码的描述。 - -有哪些状态码,可以[自行了解了解](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status),最好记得一些常用的状态码的含义,要是乱抛状态码给前端有的是一顿毒打( - -当然,在许多场合中,业务状态(成功,认证错误,参数错误等等)一般并不通过状态码表示,而是200响应,在响应消息体里边体现错误;但是也有状态码和消息体都体现的情况。具体还是要跟前端和客户端的小伙伴商量约定好规范和文档,按照团队的规范和文档行事,能少很多不必要的麻烦。 - -#### 『标头』(Header) - -请求和响应的消息体过了第一行之后,就到了『标头』(header)部分了,一般咱们把这玩意叫『请求头』和『响应头』。 - -http消息的header实际上就是一个键值对,格式为`Key: Value`,一行一个 - -需要注意的是,这里的key是不分大小写的,例如`Host`,`host`,`HOST`,`hOST`都是同一个东西。 - -同一个key的Header也可以有多个值,因此,在各种http库中,获取到的header值都是一个List。 - -比如: -``` -Set-Cookie: logged_in=no; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; HttpOnly; Secure; SameSite=Lax -Set-Cookie: access_token=abcdefg; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; Secure; SameSite=Lax -``` - -虽然如此,但是除非有必要(例如上面的例子中给客户端返回Cookie),在响应或者请求的时候最好不要这么干,即使可以这么干,否则在对方处理的时候会很麻烦。 - -一般来说,咱们会经常见到这些请求头或者响应头: -> - `Host`: 请求的目标主机,通常是在同一个ip和端口上有多个不同的服务时,提供给nginx或者apache等类似的其他的反代网关判断究竟应该执行哪个配置块时使用的。 -> - `User-Agent`: 表明请求客户端信息,一般格式为`程序名/版本`,当然,也可以添加其他额外的信息,如firefox的ua:`Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0` -> - `Content-Type`: 请求/响应传输数据的类型,即下一节中body部分数据的格式。按照规范,这个字段的值应该使用MIME type格式,这里是一些[常用的MIME类型](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)。 -> - `Accept`: 能接受的数据格式,一般为用逗号`,`分隔开的若干个MIME type格式 -> - `Accept-Encoding`: 指定能够接受的响应数据编码,和`Accept`不同的是,`Accept`指定的是body部分的数据格式,但是这里指定的是整个响应的数据编码,通常是压缩算法,如`gzip, deflate, br`,设置了这个值后,如果服务端支持,响应的时候会对整个HTTP消息进行相应的压缩后,再返回响应给客户端,客户端需要进行解压解码后再进行处理。一般http框架和web框架都能自动进行自动的处理。 -> - `Referer`: 说明请求是从哪里来的 -> - `Cookie`: 向服务器请求时附带的一些信息,就是咱们常说的cookie,浏览器在请求的时候如果有相对应的Cookie,会自动附带上这些Cookie进行请求。 -> - `Set-Cookie`: 服务端响应回来的Cookie,浏览器看到这个header之后就会根据这个header的值去保存cookie到浏览器里边。下次请求cookie对应规则的地址时会自动附带这些信息,即上一条中的Cookie字段。 - -Cookie一般用于用户的识别和身份认证以及一些额外信息的保存。[了解更多关于Cookie的东西](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies) - -实际上,很多header值只是作为一个参考,作为后端开发,不应该过于信赖前端/客户端发来的数据,后端程序必须要对前端/客户端做充足的数据校验,如`Content-Type`,前端/客户端可以在请求的时候在`Content-Type`字段里说他发了`image/png`图片,但是可能实际上发来的数据是一个程序,如果不做任何校验直接保存到服务器上,那可就麻烦大了。 - -一般来说,很多http请求和web服务框架都能帮咱们写好这些通用的请求头和响应头,不用咱们过于操心,当然,如果有需求更改的话也能更改好。 - -这里对header的作用描述不一定十分的准确,可以查看相关的文档了解详细详情:[HTTP 标头(header)](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers),Ctrl+F直接一搜就到 - -#### 『主体』(body) - -在前面的header定义完之后,需要各一行空行,才到http消息中的『主体』部分。 - -这个body部分就是这个请求真正想要传输的数据。 - -这部分可以是纯文本,也可以是二进制,都行,只要Content-Type说好了就行,没说的话,一般也行,但是得看后端处不处理了,一些后端框架不会帮你自动判断Body格式,或者不同的Content-Type处理的方式不同,如果请求的时候没有设置对,可能会有些麻烦事。 - -> 另外,上面的起始行/状态行和header行以及body和上面几行中间间隔的空行,和windows一样,使用的换行符都为CRLF,也就是`\r\n`,而不是linux/unix常用的`\n`。当然,这个知道就好了,库会帮咱们处理好的。 - -### HTTPS - -HTTPS就是加密后的HTTP,'S'就是"Secure"。一般使用TLS来加密。原始的http消息经过全部加密后,再进行传输。只要中间偷听的人拿不到密钥,就不可能知道除了请求的ip以外任何的http信息。 - -关于现代TLS加密的机制,可以去看看[这篇文章](https://zhuanlan.zhihu.com/p/43789231) - -一般约定http跑在80端口上,而https跑在443端口上,但是也可以用其他端口。 - -我的建议是,https能上就上。 - -## 主线任务:Servlet,Tomcat - -### Servlet,介绍 - -在开始Tomcat的学习之前,咱们先来了解Servlet。 - -很多教程里都有讲过,就是运行在服务端的applet,也就是『Server Applet』。 - -说实话,当我听到“Applet”的时候...印象里貌似已经是上世纪早已失传的老东西了...但是其实现在咱们说的的“Server Applet”和那个客户端的“Applet”不是同一个东西,虽然都是当年就有的东西。 - -Servlet实际上就是一个接口。 - -咱们先来点开Servlet(清掉了注释): - -![Servlet.java](https://oss-img.ciduid.top/backend_tutorial/5.14/res/servlet.png "Servlet.java") - -```java -package javax.servlet; - -import java.io.IOException; - -public interface Servlet { - - public void init(ServletConfig config) throws ServletException; - - public ServletConfig getServletConfig(); - - public void service(ServletRequest req, ServletResponse res) - throws ServletException, IOException; - - public String getServletInfo(); - - public void destroy(); -} -``` - -是的,整个Servlet接口就这些代码。 - -那Servlet是干啥的? - -大伙想想接口(interface)是用来干什么的?当然是一种规范约定。Servlet就是一种规范,所有实现Servlet的类,也就是处理网络请求的类要做什么。你要是不想按照Servlet来写,也是可以的,但是会少了很多库和框架的支持,很多东西就要你手动实现了。 - -初始化`init(ServletConfig config)`该做什么,接收到请求`service(ServletRequest req, ServletResponse res)`该做什么,服务器要退出了`destroy()`又该做什么,这些Servlet都不负责帮你实现,都需要你自己去实现。 - -这里的Servlet只是非常底层的Servlet定义,实际上,咱们学Servlet,其实就是学HttpServlet,学HttpServlet来实现一些非常简单的Web响应处理;咱们说的Servlet,其实就是实现了HttpServlet的自己写的类。 - -![HttpServlet.java](https://oss-img.ciduid.top/backend_tutorial/5.14/res/HttpServlet.png "HttpServlet.java") - -HttpServlet根据Http对最原始的Servlet又封装了一层,也就是专门针对Http的Servlet。可以看到,相比于原来的几个方法,多了很多和http处理相关的方法。 - -HttpServlet最核心的方法就是`doGet(HttpServletRequest req, HttpServletResponse resp)`, `doPost(HttpServletRequest req, HttpServletResponse resp)`等等这种`doXxx`的方法,实际上就是对应请求中`GET`, `POST`等等请求的处理,当服务接受到这些请求的时候,就进入对应的方法处理,从req读请求,再向resp写响应。 - -恭喜你,当你接触到这里的时候,就已经到了开始入门写Web程序的阶段了,你现在在做的事就是十几年前的服务端程序员在干的事了,当年web服务还不复杂的时候,很多时候就是拿Servlet写页面渲染来实现web服务。 - -当然,只是实现了Servlet并不代表就是一个能跑的服务端程序了。是,我们是写了Servlet,但是Socket那些IO相关的东西咱还没有呢。 - -Servlet并不负责和客户端直接沟通,也就是说,那些Socket侦听8080啥的底层IO处理并不是在Servlet里面,实际的连接处理那是『Tomcat』那家伙来负责的。 - -### Tomcat,介绍 - -Tomcat是一个『Servlet容器』,也就是说,这玩意是个罐子,用来装一个个的Servlet程序。 - -![Tomcat](https://oss-img.ciduid.top/backend_tutorial/5.14/res/tomcat.png "Tomcat") - -上文说到过,咱们虽然写了Servlet,但是没人负责和客户端建立连接沟通,所以,这个事就是Tomcat来做的了。 - -要知道,解析原始Http消息是一件非常麻烦的事情,光是Http标准那几百页有的是你看的了,你要干吗?反正我是不会自己干的,更何况还有各种IO相关的脏活累活要干。但是咱们的大好人——Tomcat,这些都让它来负责了。 - -Tomcat侦听着端口,客户端向我们这边发来了一个请求,Tomcat对客户端发来的Http请求进行解析,解析出请求路径,方法,header之类的信息,根据这些信息,把请求小心翼翼地包装好,封装成HttpServlettRequest,交给对应的Servlet去处理,然后Servlet处理完之后就返回HttpServletResponse给Tomcat,Tomcat就把这个响应又写成http消息,交给客户端。一个通过Servlet实现的服务端程序处理一个请求地过程就这么完成了。 - -### Servlet,开干! - -说了这么多,估计大家手已经开始痒了。那就咱们现在就来开始写几个简单的HttpServlet玩玩! - -#### 梦的开始,Hello World - -计算机最经典的一句名言,莫过于那一声响彻云霄的 ***『Hello World!』*** - -现在,就来写个Servlet,当用浏览器访问的时候,能返回文本“Hello World!” - -咱先来建一个简单的工程,什么框架都不用加,这样就好了嗼 - -![新建工程](https://oss-img.ciduid.top/backend_tutorial/5.14/res/new_project.png "新建工程") - -很多JDK的发行版都没有带Servlet,因此如果写代码的时候没有Servlet和HttpServlet类,需要自己手动在Maven中引入依赖: - -```xml - - - jakarta.servlet - jakarta.servlet-api - 6.0.0 - provided - -``` - -注意,上面引用的是`jakarta.servlet`,因为19年oracle把javax送了出去,但是又不准继续使用javax这个名字,所以jdk11以后的版本用的都是jakarta作为包名,因此需要将名称改成jakarta。 - -也就是说,如果你还在用java 11以下的jdk,需要引入`javax.servlet`的servlet接口。 - -```xml - - - javax.servlet - javax.servlet-api - 4.0.1 - provided - -``` - -这些完事之后,就可以开撸了。 - -1. 继承HttpServlet类 - 前文说过,要实现Servlet,就需要实现相应的方法。但是咱不可能又要从头写起,因此咱们继承的是HttpServlet类,而不是直接实现Servlet接口。 - - ```java - import jakarta.servlet.http.HttpServlet; - - public class HelloWorld extends HttpServlet { - - } - ``` - - 这个时候,就可以去重写HttpServlet相应的`doXxx(HttpServletRequest req, HttpServletResponse resp)`方法来处理不同的Http请求了。 - -2. 重写`doXxx(HttpServletRequest req, HttpServletResponse resp)` - - > idea每日小技巧🥰 - - 简单,idea里边直接`Alt+Insert`,选择`Override Methods` - - ![Alt+Insert](https://oss-img.ciduid.top/backend_tutorial/5.14/res/insert.png "这只是一张图片") - - 可以看到,有很多可以重写的方法: - - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/override.png "可以重写的方法") - - 咱们这里选择`doGet()`这项就好了。 - - 选好之后,嘣,idea就给我们生成好了重写方法了。 - - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/override_2.png "可以重写的方法") - - 记得删除原来的`super.doGet(req, resp);` - - > 我就不删,咋的 - > 可能会导致服务端直接返回`400`或者`405`方法不支持错误给客户端,按住ctrl点开super的`doGet`就能看到了: - > ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/super.png "super") - - 往`doGet`方法添加(粘贴)这些内容: - ```java - PrintWriter writer = resp.getWriter(); - writer.print("Hello World!"); - writer.flush(); - ``` - -这样,一个直接向客户端(请求者)返回“Hello World!”字符串的Servlet就这样写完了,当下文Tomcat部署好之后,浏览器直接访问相应的页面,就能看到一个Hello World出现在你的浏览器屏幕。 - -就这? - -是的。因为这确实就这么简单,但是当咱们业务复杂起来之后,那可就有得你写了。不过,那是后话了,咱们现在学的是原理,诚然框架非常好使,刷刷刷就写完了,但是总归要知道为什么这样,否则只是*只知其然,而不知其所以然*。 - -欸欸欸?不是说好要跑起来吗? - -别急,咱还没搞好Tomcat呢 - -#### 梦的第二步,Tomcat - -前面说到过,要让服务程序真正跑起来,还得Tomcat来干那些IO的脏活累活。 - -首先,得去[Tomcat的官网](https://tomcat.apache.org/)下载好Tomcat. - -注意,Tomcat 10版本和9版本在Servlet的包路径上有很大的不同,原因同上,还是Oracle那家伙搞的麻烦... - -如果你用的是`javax.servlet`请使用[Tomcat 9版本](https://tomcat.apache.org/download-90.cgi);如果使用的是`jakarta.servlet`,请使用[Tomcat 10](https://tomcat.apache.org/download-10.cgi)。 - -下载完后,你能得到`apache-tomcat-10.1.8-windows-x64.zip`这样的压缩包,把它解压到你喜欢的地方。 - -1. 配置 - 接下来,又是喜闻乐见的环境配置环节了🥰 - - 在系统变量中,添加`CATALINA_HOME`和`CATALINA_BASE`两个环境变量,指向你刚刚解压的Tomcat路径,如我这里解压到了`D:\apache-tomcat-10.1.8`,环境变量的值就填`D:\apache-tomcat-10.1.8` - - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/location.png) - - 配置好之后,直接运行bin里边的`startup.bat`在启动tomcat。 - - 如果控制台中文乱码了,可以修改conf下的`logging.properties`文件,将里边的`utf-8`替换为`936`,保存之后再启动,就好了 - - 如果一切成功,控制台的输出应该是像这样的: - - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/tomcat_console.png) - - 咱来conf文件夹瞧瞧。 - - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/conf.png) - - 可以看到,有`server.xml`, `web.xml`和`content.xml`这三个配置文件。 - - *麻了,怎么又是XML...* - - 咱一个一个来看 - - `server.xml`负责配置服务器相关的配置参数,如监听端口,最大连接数等等最底层的IO配置。 - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/server.xml.png) - - `context.xml`配置的是servlet内容的路径等,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改,就会自动重新加载这个文件,而不需要重启服务器。 - - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/content.xml.png) - - `web.xml`这家伙可就大了。不管虽然说是大,但其实不是很大,主要都是注解之类的。 - - `web.xml`基本上可以不用动,只需要在咱们的Servlet类中用上`@WebServlet`注解,Tomcat就能好心帮我们挂载上去了。 - - 当然,如果你想自己手动写`web.xml`部署,也可以自己去了解了解,相信我,了解完之后你肯定会回来用注解的。 - - 打开你的浏览器,访问`http://127.0.0.1:8080`,如果你在`server.xml`里设置的端口不是`8080`,请以你的端口设置为准,如果一切正常,可以看到Tomcat默认的管理页面: - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/tomcat_index.png) - -2. 做点小修改 - 为了让Web部署更方便,咱们用注解来指定部署路径,用『Maven』来打包成war包进行部署。 - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/web_servlet.png) - - 图中加了个`@WebServlet("/yahaha")`,表明这个Servlet的路径是`/yahaha`,当访问到这个路径的时候,Tomcat就会去就调用我们写的这个Servlet。 - - 接着,为了让我们亲爱的的Maven把项目打包成war文件,向项目的`pom.xml`的添加以下内容: - - ```xml - war - - learn - - - org.apache.maven.plugins - maven-war-plugin - 3.3.2 - - - - ``` - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/pom.png) - - 好了之后,用maven打包,就得到了咱们想要的war文件了。 - -3. 放置War包 - 把刚刚得到的war包拿出来(learn.war)。不难注意到,我们在`pom.xml`中,用`learn`指定了最后打包输出的文件名为`learn.war`,只要你喜欢,起什么名字都好。 - - 把它放到tomcat的`webapps`文件夹里。如果没有启动Tomcat,就把它启动起来。如果你已经把tomcat开起来了,放到`webapps`文件夹下面之后,就能看到这么一行日志: - - ```log - 14-May-2023 09:13:32.437 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployWAR 正在部署web应用程序存档文件[D:\apache-tomcat-10.1.8\webapps\learn.war] - 14-May-2023 09:13:32.465 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployWAR web应用程序存档文件[D:\apache-tomcat-10.1.8\webapps\learn.war]的部署已在[27]ms内完成 - ``` - - 同时也能看到`webapps`文件夹下面多出了个`learn`,Tomcat帮我们解压好了war包。 - -4. 让我看看! - 打开你的浏览器,访问`http://127.0.0.1:8080/learn/yahaha`,就能看到咱们写的Servlet输出了那令人激动的`Hello World!`了! - ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hello_world.png) - - 注意,我们刚刚写的Servlet路径地址并不是`http://127.0.0.1:8080/yahaha`,而是`http://127.0.0.1:8080/应用名/servlet路径`,这里的应用名,就是咱们war包的名字。如果你想从根路径开始,可以把原来`webapps`里的`ROOT`文件夹删掉,也就是前面咱们看到的那个管理页面,然后将刚刚得到的`learn.war`该名成`ROOT.war`,然后像刚刚那样放到`webapps`文件夹下,咱们的这个war就会被部署挂载到根路径`/`下了,此时咱们写的Servlet路径就是`/yahaha`了。 - - 好了,这个就是你写的第一个Servlet了。能坚持走到这里,或许非常的不容易,看到这个`Hello World!`,或许可能会心中一股激动,这可是你写的第一个Web程序,这是从你的程序里,经过重重关卡发送到浏览器展示出来的文字,不亚于当年前辈们在地球上听到《东方红》时候的激动,指不定还会热泪盈眶,感慨万分;这么一行文字,可能倾注了你一天,或者好几天的时间和经历,但是这都没有关系,最终咱们还是做出来了,这是你自己第一次写出来的真正的Web程序,你这个时候,你已经正式踏上了后端开发的满满长路了。 - - 好了,先不发电了。 - -#### 意犹未尽,继续玩 - -就输出一个Hello World!怎么够?咱要玩大的! - -![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/HttpServletRequest.png) - -HttpServlet下有很多方法可以用,获取到的都是些Http参数,这些就是Tomcat帮我们解析好的,直接拿来就用。 - -例如,通过`getParameter(String name)`就能拿到请求参数,如`/yahaha?id=1234&type=none`中的`id`和`type`,可以通过`req.getParameter("id")`和`req.getParameter("type")`拿到相应的值,如果没有这个参数,获取到的就是`null`。这个看文档一看就知道。 -![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/doc.png) -![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/doc_cn.png) - -下面,咱们就来改写一下前面的Hello World,让他能够根据提供的参数,来输出不同的内容。 -![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hellox.png) - -像这样,通过`String id = req.getParameter("id");`拿到参数中的id,然后再在下面输出出来。 - -重新打包部署好,访问之前的地址:`http://127.0.0.1:8080/learn/yahaha` -![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hello_null.png) - -啊,输出了`Hello null!`。这是因为咱们还没给参数呢,当然是null。 - -没给,那就给嘛。`http://127.0.0.1:8080/learn/yahaha?id=lensfrex` -![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hello_lensfrex.png) - -这次咱给了id参数进去,可以看到,hello的内容已经不是null了,而是咱们提供的参数了。你喜欢的话,可以换成其他的参数,访问之后就能看到响应了不同的内容。 - -就这样,咱们的服务不是死的了,能根据请求的不同发生变化了。 - -到了这里,最基本的Servlet和Tomcat,大家应该是已经知道了。剩下的,就是去了解`HttpServletRequest`和`HttpServletResponse`的API用法了。这些文档就有很多的解释,也可以到处去看看教程,有很多实例可以学习学习。 - -### After Story - -这里带大家了解了http, Servlet以及Tomcat,看起来好像很麻烦的样子。是的,就是很麻烦,但是上古程序员就是这么走来的。 - -现在咱们有了『SpringBoot』以及『Spring』一系列的框架,这玩意可以说是Java能如此流行的最重要的原因。当然,没有Spring,也会有Summer,也会有Winter。SpringBoot Web已经给我们内置了一个Tomcat,而且帮我们自动配置好了一大堆东西,这些在下一部分中陈姐会带你们领略领略。当你学完Spring的时候,就能知道这真的是个非常牛的玩意。 - -SpringBoot Web诚然用的非常爽,但是还是不要忘了本,不论上层怎么玩,还是要知道这玩意最基本的东西是怎么一回事的,Servlet还是要了解知道一些的,万变不离其宗,Spring再牛,最基础的还是这些。 - -当你玩转SpringBoot的web之后,再来回头看看的时候,哈,原来是这么一回事。 - -另外,Servlet容器不只是有Tomcat,他的同事还有`Jetty`, `GlassFish`, `Undertow`等等,只不过Tomcat因为SpringBoot Web默认内置,因此用的也是最多的,如果你喜欢,或者有需求,也可以换成其他的Servlet容器。 - -## DLC - 课外读物 - -[Servlet入门](https://www.liaoxuefeng.com/wiki/1252599548343744/1304265949708322) - -[HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) - -[servlet的本质是什么,它是如何工作的? - bravo1988的回答](https://www.zhihu.com/question/21416727/answer/690289895) - -[servlet的本质是什么,它是如何工作的? - 柳树的回答](https://www.zhihu.com/question/21416727/answer/339012081) - -[Servlet到底是什么](http://c.biancheng.net/servlet2/what-is-servlet.html) - +title: HTTP, Servlet, Tomcat +author: lensfrex +cover: https://oss-img.ciduid.top/blog/covers/topimage-xb3-pc.jpg +date: 2023-05-13 15:50:00 +--- +# 学习Servlet和Tomcat + +## 前置任务:了解学习HTTP + +如果你选了网络工程导论这门课,并且已经了解了HTTP相关的知识,则可以跳过本节,直接开主线任务:[传送点](#主线任务:Servlet,Tomcat),但是也可以重新开始学习这部分的内容。 + +想了解更多:[HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) + +### HTTP介绍 + +超文本传输协议(HyperText Transfer Protocol,HTTP)是一个应用层协议。所谓协议,就是数据传输格式的一个约定。 + +HTTP最初设计是用来传输html页面这种纯文本数据的,但是实际上只要声明好header,传输什么都是可以的,图片,文件等等,或者也可以摇身一变,变成另一个协议(grpc, 基于http2)来使用,总之,http其实是非常灵活的。 + +### HTTP消息 + +一个规范的,完整的HTTP消息结构是这样的: + +请求消息(GET方法): +地址:`https://github.com` + +```http +GET / HTTP/1.1 +Host: github.com +authority: github.com +accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 +accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 +user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 +content-length: 0 + + +``` + +请求消息(POST方法,带请求体): + +地址:`http://bkjx.wust.edu.cn/Logon.do?method=logon` + +```http +POST /Logon.do?method=logon HTTP/1.1 +Host: bkjx.wust.edu.cn +Proxy-Connection: Keep-Alive +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 +Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 +Cache-Control: no-cache +Connection: keep-alive +Content-Type: application/x-www-form-urlencoded +Cookie: bzb_njw=303511D07EF501147333F6B099D16CB9; SERVERID=122 +Origin: http://bkjx.wust.edu.cn +Pragma: no-cache +Referer: http://bkjx.wust.edu.cn/ +Upgrade-Insecure-Requests: 1 +User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 +Content-Length: 94 + +userAccount=&userPassWorld=&encoded=dMcs2P8fNag0n1d03f0UVgu02^%^257F^%^25QF^%^25pcs0Ygd4fbgHs69 +``` + + +响应消息(header内容精简过): + +```http +HTTP/1.1 200 OK +Server: GitHub.com +Date: Sat, 13 May 2023 02:59:34 GMT +Content-Type: text/html; charset=utf-8 +Vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Language, Accept-Encoding, Accept, X-Requested-With +content-language: en-US +ETag: W/"bfeda72459b363617514a4f13882cece" +Set-Cookie: _octo=GH1.1.496438640.1683116779; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; Secure; SameSite=Lax +Accept-Ranges: bytes +Transfer-Encoding: chunked + + + + + + +...(还有一堆的网页内容) +``` + +请求和响应的消息体长得还挺像的,估计大家都能看出来了。 + +#### 第一行 -『起始行』与『状态行』 + +http请求消息中,第一行为『起始行』: +- `GET / HTTP/1.1` +- `GET /background.png HTTP/1.0` +- `POST /Logon.do?method=logon HTTP/1.1` + +起始行分为三个部分,分别定义了请求方法,请求目标和当前请求使用的http协议版本 + +第一个部分为『[请求方法](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods)』,一般有GET, POST, OPTIONS, PUT等好多种,但是实际使用几乎就只有GET和POST两种。 + +随后紧接着的部分是『请求目标』,在普通的http请求中也可以简单理解为请求路径,也就是咱们看到的浏览器地址后面的部分(xxx.com/abcd/efg中的/abcd/efg,bkjx.wust.edu.cn/Logon.do?method=logon中的/Logon.do?method=logon部分) + +在部分场合下,请求目标有时也是一个绝对路径的URL,如当使用HTTP代理访问网站时,浏览器向代理服务器(如软件)发送的数据也是一个http请求,只不过真实的请求放在了body部分,代理程序只负责原样发送数据:`CONNECT google.com:443 HTTP/1.1` + +这里就抄一下MDN的介绍: + +> - 一个绝对路径,末尾跟上一个 '?' 和查询字符串。这是最常见的形式,称为原始形式(origin form),被 GET、POST、HEAD 和 OPTIONS 方法所使用。 +> - - POST / HTTP/1.1 +> - - GET /background.png HTTP/1.0 +> - - HEAD /test.html?query=alibaba HTTP/1.1 +> - - OPTIONS /anypage.html HTTP/1.0 +> - 一个完整的 URL,被称为绝对形式(absolute form),主要在使用 GET 方法连接到代理时使用。GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1 +> - 由域名和可选端口(以 ':' 为前缀)组成的 URL 的 authority 部分,称为 authority form。仅在使用 CONNECT 建立 HTTP 隧道时才使用。CONNECT developer.mozilla.org:80 HTTP/1.1 +> - 星号形式(asterisk form),一个简单的星号('*'),配合 OPTIONS 方法使用,代表整个服务器。OPTIONS * HTTP/1.1 + +最后的一部分为『HTTP版本』,声明了这次请求使用的http版本。目前常用的版本有`HTTP/1.1`,`HTTP/2`,`HTTP/3`。 + +> 另外,和其他HTTP版本不同的是,HTTP/3版本是在基于UDP的QUIC协议之上实现传输的,QUIC是与TCP和UDP等同级(传输层)的协议,而其他的HTTP版本都是在TCP协议上实现的, + +对于响应消息,第一行为『状态行』。 +- `HTTP/1.1 200 OK` +- `HTTP/1.1 404 Not Found` +- `HTTP/1.1 500 Internal Server Error` **(心 脏 骤 停)** + +也是三个部分。 + +响应的状态行就挺简单的了。 + +第一个就不用说了。 + +第二个则为『状态码』,就是咱们常见的404, 200这些,表明了服务端处理请求的结果状态。 + +第三个部分则为『状态文本』,其实就是状态码的描述。 + +有哪些状态码,可以[自行了解了解](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status),最好记得一些常用的状态码的含义,要是乱抛状态码给前端有的是一顿毒打( + +当然,在许多场合中,业务状态(成功,认证错误,参数错误等等)一般并不通过状态码表示,而是200响应,在响应消息体里边体现错误;但是也有状态码和消息体都体现的情况。具体还是要跟前端和客户端的小伙伴商量约定好规范和文档,按照团队的规范和文档行事,能少很多不必要的麻烦。 + +#### 『标头』(Header) + +请求和响应的消息体过了第一行之后,就到了『标头』(header)部分了,一般咱们把这玩意叫『请求头』和『响应头』。 + +http消息的header实际上就是一个键值对,格式为`Key: Value`,一行一个 + +需要注意的是,这里的key是不分大小写的,例如`Host`,`host`,`HOST`,`hOST`都是同一个东西。 + +同一个key的Header也可以有多个值,因此,在各种http库中,获取到的header值都是一个List。 + +比如: +``` +Set-Cookie: logged_in=no; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; HttpOnly; Secure; SameSite=Lax +Set-Cookie: access_token=abcdefg; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; Secure; SameSite=Lax +``` + +虽然如此,但是除非有必要(例如上面的例子中给客户端返回Cookie),在响应或者请求的时候最好不要这么干,即使可以这么干,否则在对方处理的时候会很麻烦。 + +一般来说,咱们会经常见到这些请求头或者响应头: +> - `Host`: 请求的目标主机,通常是在同一个ip和端口上有多个不同的服务时,提供给nginx或者apache等类似的其他的反代网关判断究竟应该执行哪个配置块时使用的。 +> - `User-Agent`: 表明请求客户端信息,一般格式为`程序名/版本`,当然,也可以添加其他额外的信息,如firefox的ua:`Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0` +> - `Content-Type`: 请求/响应传输数据的类型,即下一节中body部分数据的格式。按照规范,这个字段的值应该使用MIME type格式,这里是一些[常用的MIME类型](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)。 +> - `Accept`: 能接受的数据格式,一般为用逗号`,`分隔开的若干个MIME type格式 +> - `Accept-Encoding`: 指定能够接受的响应数据编码,和`Accept`不同的是,`Accept`指定的是body部分的数据格式,但是这里指定的是整个响应的数据编码,通常是压缩算法,如`gzip, deflate, br`,设置了这个值后,如果服务端支持,响应的时候会对整个HTTP消息进行相应的压缩后,再返回响应给客户端,客户端需要进行解压解码后再进行处理。一般http框架和web框架都能自动进行自动的处理。 +> - `Referer`: 说明请求是从哪里来的 +> - `Cookie`: 向服务器请求时附带的一些信息,就是咱们常说的cookie,浏览器在请求的时候如果有相对应的Cookie,会自动附带上这些Cookie进行请求。 +> - `Set-Cookie`: 服务端响应回来的Cookie,浏览器看到这个header之后就会根据这个header的值去保存cookie到浏览器里边。下次请求cookie对应规则的地址时会自动附带这些信息,即上一条中的Cookie字段。 + +Cookie一般用于用户的识别和身份认证以及一些额外信息的保存。[了解更多关于Cookie的东西](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies) + +实际上,很多header值只是作为一个参考,作为后端开发,不应该过于信赖前端/客户端发来的数据,后端程序必须要对前端/客户端做充足的数据校验,如`Content-Type`,前端/客户端可以在请求的时候在`Content-Type`字段里说他发了`image/png`图片,但是可能实际上发来的数据是一个程序,如果不做任何校验直接保存到服务器上,那可就麻烦大了。 + +一般来说,很多http请求和web服务框架都能帮咱们写好这些通用的请求头和响应头,不用咱们过于操心,当然,如果有需求更改的话也能更改好。 + +这里对header的作用描述不一定十分的准确,可以查看相关的文档了解详细详情:[HTTP 标头(header)](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers),Ctrl+F直接一搜就到 + +#### 『主体』(body) + +在前面的header定义完之后,需要各一行空行,才到http消息中的『主体』部分。 + +这个body部分就是这个请求真正想要传输的数据。 + +这部分可以是纯文本,也可以是二进制,都行,只要Content-Type说好了就行,没说的话,一般也行,但是得看后端处不处理了,一些后端框架不会帮你自动判断Body格式,或者不同的Content-Type处理的方式不同,如果请求的时候没有设置对,可能会有些麻烦事。 + +> 另外,上面的起始行/状态行和header行以及body和上面几行中间间隔的空行,和windows一样,使用的换行符都为CRLF,也就是`\r\n`,而不是linux/unix常用的`\n`。当然,这个知道就好了,库会帮咱们处理好的。 + +### HTTPS + +HTTPS就是加密后的HTTP,'S'就是"Secure"。一般使用TLS来加密。原始的http消息经过全部加密后,再进行传输。只要中间偷听的人拿不到密钥,就不可能知道除了请求的ip以外任何的http信息。 + +关于现代TLS加密的机制,可以去看看[这篇文章](https://zhuanlan.zhihu.com/p/43789231) + +一般约定http跑在80端口上,而https跑在443端口上,但是也可以用其他端口。 + +我的建议是,https能上就上。 + +## 主线任务:Servlet,Tomcat + +### Servlet,介绍 + +在开始Tomcat的学习之前,咱们先来了解Servlet。 + +很多教程里都有讲过,就是运行在服务端的applet,也就是『Server Applet』。 + +说实话,当我听到“Applet”的时候...印象里貌似已经是上世纪早已失传的老东西了...但是其实现在咱们说的的“Server Applet”和那个客户端的“Applet”不是同一个东西,虽然都是当年就有的东西。 + +Servlet实际上就是一个接口。 + +咱们先来点开Servlet(清掉了注释): + +![Servlet.java](https://oss-img.ciduid.top/backend_tutorial/5.14/res/servlet.png "Servlet.java") + +```java +package javax.servlet; + +import java.io.IOException; + +public interface Servlet { + + public void init(ServletConfig config) throws ServletException; + + public ServletConfig getServletConfig(); + + public void service(ServletRequest req, ServletResponse res) + throws ServletException, IOException; + + public String getServletInfo(); + + public void destroy(); +} +``` + +是的,整个Servlet接口就这些代码。 + +那Servlet是干啥的? + +大伙想想接口(interface)是用来干什么的?当然是一种规范约定。Servlet就是一种规范,所有实现Servlet的类,也就是处理网络请求的类要做什么。你要是不想按照Servlet来写,也是可以的,但是会少了很多库和框架的支持,很多东西就要你手动实现了。 + +初始化`init(ServletConfig config)`该做什么,接收到请求`service(ServletRequest req, ServletResponse res)`该做什么,服务器要退出了`destroy()`又该做什么,这些Servlet都不负责帮你实现,都需要你自己去实现。 + +这里的Servlet只是非常底层的Servlet定义,实际上,咱们学Servlet,其实就是学HttpServlet,学HttpServlet来实现一些非常简单的Web响应处理;咱们说的Servlet,其实就是实现了HttpServlet的自己写的类。 + +![HttpServlet.java](https://oss-img.ciduid.top/backend_tutorial/5.14/res/HttpServlet.png "HttpServlet.java") + +HttpServlet根据Http对最原始的Servlet又封装了一层,也就是专门针对Http的Servlet。可以看到,相比于原来的几个方法,多了很多和http处理相关的方法。 + +HttpServlet最核心的方法就是`doGet(HttpServletRequest req, HttpServletResponse resp)`, `doPost(HttpServletRequest req, HttpServletResponse resp)`等等这种`doXxx`的方法,实际上就是对应请求中`GET`, `POST`等等请求的处理,当服务接受到这些请求的时候,就进入对应的方法处理,从req读请求,再向resp写响应。 + +恭喜你,当你接触到这里的时候,就已经到了开始入门写Web程序的阶段了,你现在在做的事就是十几年前的服务端程序员在干的事了,当年web服务还不复杂的时候,很多时候就是拿Servlet写页面渲染来实现web服务。 + +当然,只是实现了Servlet并不代表就是一个能跑的服务端程序了。是,我们是写了Servlet,但是Socket那些IO相关的东西咱还没有呢。 + +Servlet并不负责和客户端直接沟通,也就是说,那些Socket侦听8080啥的底层IO处理并不是在Servlet里面,实际的连接处理那是『Tomcat』那家伙来负责的。 + +### Tomcat,介绍 + +Tomcat是一个『Servlet容器』,也就是说,这玩意是个罐子,用来装一个个的Servlet程序。 + +![Tomcat](https://oss-img.ciduid.top/backend_tutorial/5.14/res/tomcat.png "Tomcat") + +上文说到过,咱们虽然写了Servlet,但是没人负责和客户端建立连接沟通,所以,这个事就是Tomcat来做的了。 + +要知道,解析原始Http消息是一件非常麻烦的事情,光是Http标准那几百页有的是你看的了,你要干吗?反正我是不会自己干的,更何况还有各种IO相关的脏活累活要干。但是咱们的大好人——Tomcat,这些都让它来负责了。 + +Tomcat侦听着端口,客户端向我们这边发来了一个请求,Tomcat对客户端发来的Http请求进行解析,解析出请求路径,方法,header之类的信息,根据这些信息,把请求小心翼翼地包装好,封装成HttpServlettRequest,交给对应的Servlet去处理,然后Servlet处理完之后就返回HttpServletResponse给Tomcat,Tomcat就把这个响应又写成http消息,交给客户端。一个通过Servlet实现的服务端程序处理一个请求地过程就这么完成了。 + +### Servlet,开干! + +说了这么多,估计大家手已经开始痒了。那就咱们现在就来开始写几个简单的HttpServlet玩玩! + +#### 梦的开始,Hello World + +计算机最经典的一句名言,莫过于那一声响彻云霄的 ***『Hello World!』*** + +现在,就来写个Servlet,当用浏览器访问的时候,能返回文本“Hello World!” + +咱先来建一个简单的工程,什么框架都不用加,这样就好了嗼 + +![新建工程](https://oss-img.ciduid.top/backend_tutorial/5.14/res/new_project.png "新建工程") + +很多JDK的发行版都没有带Servlet,因此如果写代码的时候没有Servlet和HttpServlet类,需要自己手动在Maven中引入依赖: + +```xml + + + jakarta.servlet + jakarta.servlet-api + 6.0.0 + provided + +``` + +注意,上面引用的是`jakarta.servlet`,因为19年oracle把javax送了出去,但是又不准继续使用javax这个名字,所以jdk11以后的版本用的都是jakarta作为包名,因此需要将名称改成jakarta。 + +也就是说,如果你还在用java 11以下的jdk,需要引入`javax.servlet`的servlet接口。 + +```xml + + + javax.servlet + javax.servlet-api + 4.0.1 + provided + +``` + +这些完事之后,就可以开撸了。 + +1. 继承HttpServlet类 + 前文说过,要实现Servlet,就需要实现相应的方法。但是咱不可能又要从头写起,因此咱们继承的是HttpServlet类,而不是直接实现Servlet接口。 + + ```java + import jakarta.servlet.http.HttpServlet; + + public class HelloWorld extends HttpServlet { + + } + ``` + + 这个时候,就可以去重写HttpServlet相应的`doXxx(HttpServletRequest req, HttpServletResponse resp)`方法来处理不同的Http请求了。 + +2. 重写`doXxx(HttpServletRequest req, HttpServletResponse resp)` + + > idea每日小技巧🥰 + + 简单,idea里边直接`Alt+Insert`,选择`Override Methods` + + ![Alt+Insert](https://oss-img.ciduid.top/backend_tutorial/5.14/res/insert.png "这只是一张图片") + + 可以看到,有很多可以重写的方法: + + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/override.png "可以重写的方法") + + 咱们这里选择`doGet()`这项就好了。 + + 选好之后,嘣,idea就给我们生成好了重写方法了。 + + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/override_2.png "可以重写的方法") + + 记得删除原来的`super.doGet(req, resp);` + + > 我就不删,咋的 + > 可能会导致服务端直接返回`400`或者`405`方法不支持错误给客户端,按住ctrl点开super的`doGet`就能看到了: + > ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/super.png "super") + + 往`doGet`方法添加(粘贴)这些内容: + ```java + PrintWriter writer = resp.getWriter(); + writer.print("Hello World!"); + writer.flush(); + ``` + +这样,一个直接向客户端(请求者)返回“Hello World!”字符串的Servlet就这样写完了,当下文Tomcat部署好之后,浏览器直接访问相应的页面,就能看到一个Hello World出现在你的浏览器屏幕。 + +就这? + +是的。因为这确实就这么简单,但是当咱们业务复杂起来之后,那可就有得你写了。不过,那是后话了,咱们现在学的是原理,诚然框架非常好使,刷刷刷就写完了,但是总归要知道为什么这样,否则只是*只知其然,而不知其所以然*。 + +欸欸欸?不是说好要跑起来吗? + +别急,咱还没搞好Tomcat呢 + +#### 梦的第二步,Tomcat + +前面说到过,要让服务程序真正跑起来,还得Tomcat来干那些IO的脏活累活。 + +首先,得去[Tomcat的官网](https://tomcat.apache.org/)下载好Tomcat. + +注意,Tomcat 10版本和9版本在Servlet的包路径上有很大的不同,原因同上,还是Oracle那家伙搞的麻烦... + +如果你用的是`javax.servlet`请使用[Tomcat 9版本](https://tomcat.apache.org/download-90.cgi);如果使用的是`jakarta.servlet`,请使用[Tomcat 10](https://tomcat.apache.org/download-10.cgi)。 + +下载完后,你能得到`apache-tomcat-10.1.8-windows-x64.zip`这样的压缩包,把它解压到你喜欢的地方。 + +1. 配置 + 接下来,又是喜闻乐见的环境配置环节了🥰 + + 在系统变量中,添加`CATALINA_HOME`和`CATALINA_BASE`两个环境变量,指向你刚刚解压的Tomcat路径,如我这里解压到了`D:\apache-tomcat-10.1.8`,环境变量的值就填`D:\apache-tomcat-10.1.8` + + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/location.png) + + 配置好之后,直接运行bin里边的`startup.bat`在启动tomcat。 + + 如果控制台中文乱码了,可以修改conf下的`logging.properties`文件,将里边的`utf-8`替换为`936`,保存之后再启动,就好了 + + 如果一切成功,控制台的输出应该是像这样的: + + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/tomcat_console.png) + + 咱来conf文件夹瞧瞧。 + + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/conf.png) + + 可以看到,有`server.xml`, `web.xml`和`content.xml`这三个配置文件。 + + *麻了,怎么又是XML...* + + 咱一个一个来看 + + `server.xml`负责配置服务器相关的配置参数,如监听端口,最大连接数等等最底层的IO配置。 + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/server.xml.png) + + `context.xml`配置的是servlet内容的路径等,tomcat服务器会定时去扫描这个文件。一旦发现文件被修改,就会自动重新加载这个文件,而不需要重启服务器。 + + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/content.xml.png) + + `web.xml`这家伙可就大了。不管虽然说是大,但其实不是很大,主要都是注解之类的。 + + `web.xml`基本上可以不用动,只需要在咱们的Servlet类中用上`@WebServlet`注解,Tomcat就能好心帮我们挂载上去了。 + + 当然,如果你想自己手动写`web.xml`部署,也可以自己去了解了解,相信我,了解完之后你肯定会回来用注解的。 + + 打开你的浏览器,访问`http://127.0.0.1:8080`,如果你在`server.xml`里设置的端口不是`8080`,请以你的端口设置为准,如果一切正常,可以看到Tomcat默认的管理页面: + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/tomcat_index.png) + +2. 做点小修改 + 为了让Web部署更方便,咱们用注解来指定部署路径,用『Maven』来打包成war包进行部署。 + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/web_servlet.png) + + 图中加了个`@WebServlet("/yahaha")`,表明这个Servlet的路径是`/yahaha`,当访问到这个路径的时候,Tomcat就会去就调用我们写的这个Servlet。 + + 接着,为了让我们亲爱的的Maven把项目打包成war文件,向项目的`pom.xml`的添加以下内容: + + ```xml + war + + learn + + + org.apache.maven.plugins + maven-war-plugin + 3.3.2 + + + + ``` + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/pom.png) + + 好了之后,用maven打包,就得到了咱们想要的war文件了。 + +3. 放置War包 + 把刚刚得到的war包拿出来(learn.war)。不难注意到,我们在`pom.xml`中,用`learn`指定了最后打包输出的文件名为`learn.war`,只要你喜欢,起什么名字都好。 + + 把它放到tomcat的`webapps`文件夹里。如果没有启动Tomcat,就把它启动起来。如果你已经把tomcat开起来了,放到`webapps`文件夹下面之后,就能看到这么一行日志: + + ```log + 14-May-2023 09:13:32.437 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployWAR 正在部署web应用程序存档文件[D:\apache-tomcat-10.1.8\webapps\learn.war] + 14-May-2023 09:13:32.465 信息 [Catalina-utility-1] org.apache.catalina.startup.HostConfig.deployWAR web应用程序存档文件[D:\apache-tomcat-10.1.8\webapps\learn.war]的部署已在[27]ms内完成 + ``` + + 同时也能看到`webapps`文件夹下面多出了个`learn`,Tomcat帮我们解压好了war包。 + +4. 让我看看! + 打开你的浏览器,访问`http://127.0.0.1:8080/learn/yahaha`,就能看到咱们写的Servlet输出了那令人激动的`Hello World!`了! + ![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hello_world.png) + + 注意,我们刚刚写的Servlet路径地址并不是`http://127.0.0.1:8080/yahaha`,而是`http://127.0.0.1:8080/应用名/servlet路径`,这里的应用名,就是咱们war包的名字。如果你想从根路径开始,可以把原来`webapps`里的`ROOT`文件夹删掉,也就是前面咱们看到的那个管理页面,然后将刚刚得到的`learn.war`该名成`ROOT.war`,然后像刚刚那样放到`webapps`文件夹下,咱们的这个war就会被部署挂载到根路径`/`下了,此时咱们写的Servlet路径就是`/yahaha`了。 + + 好了,这个就是你写的第一个Servlet了。能坚持走到这里,或许非常的不容易,看到这个`Hello World!`,或许可能会心中一股激动,这可是你写的第一个Web程序,这是从你的程序里,经过重重关卡发送到浏览器展示出来的文字,不亚于当年前辈们在地球上听到《东方红》时候的激动,指不定还会热泪盈眶,感慨万分;这么一行文字,可能倾注了你一天,或者好几天的时间和经历,但是这都没有关系,最终咱们还是做出来了,这是你自己第一次写出来的真正的Web程序,你这个时候,你已经正式踏上了后端开发的满满长路了。 + + 好了,先不发电了。 + +#### 意犹未尽,继续玩 + +就输出一个Hello World!怎么够?咱要玩大的! + +![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/HttpServletRequest.png) + +HttpServlet下有很多方法可以用,获取到的都是些Http参数,这些就是Tomcat帮我们解析好的,直接拿来就用。 + +例如,通过`getParameter(String name)`就能拿到请求参数,如`/yahaha?id=1234&type=none`中的`id`和`type`,可以通过`req.getParameter("id")`和`req.getParameter("type")`拿到相应的值,如果没有这个参数,获取到的就是`null`。这个看文档一看就知道。 +![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/doc.png) +![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/doc_cn.png) + +下面,咱们就来改写一下前面的Hello World,让他能够根据提供的参数,来输出不同的内容。 +![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hellox.png) + +像这样,通过`String id = req.getParameter("id");`拿到参数中的id,然后再在下面输出出来。 + +重新打包部署好,访问之前的地址:`http://127.0.0.1:8080/learn/yahaha` +![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hello_null.png) + +啊,输出了`Hello null!`。这是因为咱们还没给参数呢,当然是null。 + +没给,那就给嘛。`http://127.0.0.1:8080/learn/yahaha?id=lensfrex` +![](https://oss-img.ciduid.top/backend_tutorial/5.14/res/hello_lensfrex.png) + +这次咱给了id参数进去,可以看到,hello的内容已经不是null了,而是咱们提供的参数了。你喜欢的话,可以换成其他的参数,访问之后就能看到响应了不同的内容。 + +就这样,咱们的服务不是死的了,能根据请求的不同发生变化了。 + +到了这里,最基本的Servlet和Tomcat,大家应该是已经知道了。剩下的,就是去了解`HttpServletRequest`和`HttpServletResponse`的API用法了。这些文档就有很多的解释,也可以到处去看看教程,有很多实例可以学习学习。 + +### After Story + +这里带大家了解了http, Servlet以及Tomcat,看起来好像很麻烦的样子。是的,就是很麻烦,但是上古程序员就是这么走来的。 + +现在咱们有了『SpringBoot』以及『Spring』一系列的框架,这玩意可以说是Java能如此流行的最重要的原因。当然,没有Spring,也会有Summer,也会有Winter。SpringBoot Web已经给我们内置了一个Tomcat,而且帮我们自动配置好了一大堆东西,这些在下一部分中陈姐会带你们领略领略。当你学完Spring的时候,就能知道这真的是个非常牛的玩意。 + +SpringBoot Web诚然用的非常爽,但是还是不要忘了本,不论上层怎么玩,还是要知道这玩意最基本的东西是怎么一回事的,Servlet还是要了解知道一些的,万变不离其宗,Spring再牛,最基础的还是这些。 + +当你玩转SpringBoot的web之后,再来回头看看的时候,哈,原来是这么一回事。 + +另外,Servlet容器不只是有Tomcat,他的同事还有`Jetty`, `GlassFish`, `Undertow`等等,只不过Tomcat因为SpringBoot Web默认内置,因此用的也是最多的,如果你喜欢,或者有需求,也可以换成其他的Servlet容器。 + +## DLC - 课外读物 + +[Servlet入门](https://www.liaoxuefeng.com/wiki/1252599548343744/1304265949708322) + +[HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) + +[servlet的本质是什么,它是如何工作的? - bravo1988的回答](https://www.zhihu.com/question/21416727/answer/690289895) + +[servlet的本质是什么,它是如何工作的? - 柳树的回答](https://www.zhihu.com/question/21416727/answer/339012081) + +[Servlet到底是什么](http://c.biancheng.net/servlet2/what-is-servlet.html) + [一些Servlet应用的教程](https://www.runoob.com/servlet/servlet-form-data.html) \ No newline at end of file diff --git a/source/about/index.md b/source/about/index.md new file mode 100644 index 0000000..8abdad3 --- /dev/null +++ b/source/about/index.md @@ -0,0 +1,4 @@ +--- +title: about +date: 2022-02-23 20:01:17 +--- diff --git a/source/assets/wallpaper-2311325.jpg b/source/assets/wallpaper-2311325.jpg new file mode 100644 index 0000000..0bde2ca Binary files /dev/null and b/source/assets/wallpaper-2311325.jpg differ diff --git a/source/assets/wallpaper-2572384.jpg b/source/assets/wallpaper-2572384.jpg new file mode 100644 index 0000000..9681c27 Binary files /dev/null and b/source/assets/wallpaper-2572384.jpg differ diff --git a/source/assets/wallpaper-878514.jpg b/source/assets/wallpaper-878514.jpg new file mode 100644 index 0000000..38b190e Binary files /dev/null and b/source/assets/wallpaper-878514.jpg differ diff --git a/source/backend_tutorial/HTTP,Servlet和Tomcat.md b/source/backend_tutorial/HTTP,Servlet和Tomcat.md new file mode 100644 index 0000000..97e218e --- /dev/null +++ b/source/backend_tutorial/HTTP,Servlet和Tomcat.md @@ -0,0 +1,192 @@ +# 学习Servlet和Tomcat + +## 前置任务:了解学习HTTP + +如果你选了网络工程导论这门课,并且已经了解了HTTP相关的知识,则可以跳过本节,直接开主线任务:[传送点](####Teleport1),但是也可以重新开始学习这部分的内容。 + +想了解更多:[HTTP | MDN](https://developer.mozilla.org/zh-CN/docs/Web/HTTP) + +### HTTP介绍 + +超文本传输协议(HyperText Transfer Protocol,HTTP)是一个应用层协议。所谓协议,就是数据传输格式的一个约定。 + +HTTP最初设计是用来传输html页面这种纯文本数据的,但是实际上只要声明好header,传输什么都是可以的,图片,文件等等,或者也可以摇身一变,变成另一个协议(grpc, 基于http2)来使用,总之,http其实是非常灵活的。 + +### HTTP消息 + +一个规范的,完整的HTTP消息结构是这样的: + +请求(GET方法): +地址:`https://github.com` + +```http +GET / HTTP/1.1 +Host: github.com +authority: github.com +accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 +accept-language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 +user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 +content-length: 0 + + +``` + +请求(POST方法,带请求体): + +地址:`http://bkjx.wust.edu.cn/Logon.do?method=logon` + +```http +POST /Logon.do?method=logon HTTP/1.1 +Host: bkjx.wust.edu.cn +Proxy-Connection: Keep-Alive +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 +Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 +Cache-Control: no-cache +Connection: keep-alive +Content-Type: application/x-www-form-urlencoded +Cookie: bzb_njw=303511D07EF501147333F6B099D16CB9; SERVERID=122 +Origin: http://bkjx.wust.edu.cn +Pragma: no-cache +Referer: http://bkjx.wust.edu.cn/ +Upgrade-Insecure-Requests: 1 +User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.35 +Content-Length: 94 + +userAccount=&userPassword=&encoded=dMcs2P8fNag0n1d03f0UVgu02^%^257F^%^25QF^%^25pcs0Ygd4fbgHs69 +``` + +响应(header内容精简过): +```http +HTTP/1.1 200 OK +Server: GitHub.com +Date: Sat, 13 May 2023 02:59:34 GMT +Content-Type: text/html; charset=utf-8 +Vary: X-PJAX, X-PJAX-Container, Turbo-Visit, Turbo-Frame, Accept-Language, Accept-Encoding, Accept, X-Requested-With +content-language: en-US +ETag: W/"bfeda72459b363617514a4f13882cece" +Set-Cookie: _octo=GH1.1.496438640.1683116779; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; Secure; SameSite=Lax +Accept-Ranges: bytes +Transfer-Encoding: chunked + + + + + + +...(还有一堆的网页内容) +``` + +请求和响应的消息体长得还挺像的,估计大家都能看出来了。 + +#### 第一行 -『起始行』与『状态行』 + +http请求消息中,第一行为『起始行』: +- `GET / HTTP/1.1` +- `GET /background.png HTTP/1.0` +- `POST /Logon.do?method=logon HTTP/1.1` + +起始行分为三个部分,分别定义了请求方法,请求目标和当前请求使用的http协议版本 + +第一个部分为『[请求方法](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods)』,一般有GET, POST, OPTIONS, PUT等好多种,但是实际使用几乎就只有GET和POST两种。 + +随后紧接着的部分是『请求目标』,在普通的http请求中也可以简单理解为请求路径,也就是咱们看到的浏览器地址后面的部分(xxx.com/abcd/efg中的/abcd/efg,bkjx.wust.edu.cn/Logon.do?method=logon中的/Logon.do?method=logon部分) + +在部分场合下,请求目标有时也是一个绝对路径的URL,如当使用HTTP代理访问网站时,浏览器向代理服务器(如软件)发送的数据也是一个http请求,只不过真实的请求放在了body部分,代理程序只负责原样发送数据:`CONNECT google.com:443 HTTP/1.1` + +这里就抄一下MDN的介绍: + +> - 一个绝对路径,末尾跟上一个 '?' 和查询字符串。这是最常见的形式,称为原始形式(origin form),被 GET、POST、HEAD 和 OPTIONS 方法所使用。 +> - - POST / HTTP/1.1 +> - - GET /background.png HTTP/1.0 +> - - HEAD /test.html?query=alibaba HTTP/1.1 +> - - OPTIONS /anypage.html HTTP/1.0 +> - 一个完整的 URL,被称为绝对形式(absolute form),主要在使用 GET 方法连接到代理时使用。GET http://developer.mozilla.org/en-US/docs/Web/HTTP/Messages HTTP/1.1 +> - 由域名和可选端口(以 ':' 为前缀)组成的 URL 的 authority 部分,称为 authority form。仅在使用 CONNECT 建立 HTTP 隧道时才使用。CONNECT developer.mozilla.org:80 HTTP/1.1 +> - 星号形式(asterisk form),一个简单的星号('*'),配合 OPTIONS 方法使用,代表整个服务器。OPTIONS * HTTP/1.1 + +最后的一部分为『HTTP版本』,声明了这次请求使用的http版本。目前常用的版本有`HTTP/1.1`,`HTTP/2`,`HTTP/3`。 + +> 另外,和其他HTTP版本不同的是,HTTP/3版本是在基于UDP的QUIC协议之上实现传输的,QUIC是与TCP和UDP等同级(传输层)的协议,而其他的HTTP版本都是在TCP协议上实现的, + +对于响应消息,第一行为『状态行』。 +- `HTTP/1.1 200 OK` +- `HTTP/1.1 404 Not Found` +- `HTTP/1.1 500 Internal Server Error` **(心 脏 骤 停)** + +也是三个部分。 + +响应的状态行就挺简单的了。 + +第一个就不用说了。 + +第二个则为『状态码』,就是咱们常见的404, 200这些,表明了服务端处理请求的结果状态。 + +第三个部分则为『状态文本』,其实就是状态码的描述。 + +有哪些状态码,可以[自行了解了解](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status),最好记得一些常用的状态码的含义,要是乱抛状态码给前端有的是一顿毒打( + +当然,在许多场合中,业务状态(成功,认证错误,参数错误等等)一般并不通过状态码表示,而是200响应,在响应消息体里边体现错误;但是也有状态码和消息体都体现的情况。具体还是要跟前端和客户端的小伙伴商量约定好规范和文档,按照团队的规范和文档行事,能少很多不必要的麻烦。 + +#### 『标头』(Header) + +请求和响应的消息体过了第一行之后,就到了『标头』(header)部分了,一般咱们把这玩意叫『请求头』和『响应头』。 + +http消息的header实际上就是一个键值对,格式为`Key: Value`,一行一个 + +需要注意的是,这里的key是不分大小写的,例如`Host`,`host`,`HOST`,`hOST`都是同一个东西。 + +同一个key的Header也可以有多个值,因此,在各种http库中,获取到的header值都是一个List。 + +比如: +``` +Set-Cookie: logged_in=no; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; HttpOnly; Secure; SameSite=Lax +Set-Cookie: access_token=abcdefg; Path=/; Domain=github.com; Expires=Mon, 13 May 2024 02:59:39 GMT; Secure; SameSite=Lax +``` + +虽然如此,但是除非有必要(例如上面的例子中给客户端返回Cookie),在响应或者请求的时候最好不要这么干,即使可以这么干,否则在对方处理的时候会很麻烦。 + +一般来说,咱们会经常见到这些请求头或者响应头: +> - `Host`: 请求的目标主机,通常是在同一个ip和端口上有多个不同的服务时,提供给nginx或者apache等类似的其他的反代网关判断究竟应该执行哪个配置块时使用的。 +> - `User-Agent`: 表明请求客户端信息,一般格式为`程序名/版本`,当然,也可以添加其他额外的信息,如firefox的ua:`Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/111.0` +> - `Content-Type`: 请求/响应传输数据的类型,即下一节中body部分数据的格式。按照规范,这个字段的值应该使用MIME type格式,这里是一些[常用的MIME类型](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types)。 +> - `Accept`: 能接受的数据格式,一般为用逗号`,`分隔开的若干个MIME type格式 +> - `Accept-Encoding`: 指定能够接受的响应数据编码,和`Accept`不同的是,`Accept`指定的是body部分的数据格式,但是这里指定的是整个响应的数据编码,通常是压缩算法,如`gzip, deflate, br`,设置了这个值后,如果服务端支持,响应的时候会对整个HTTP消息进行相应的压缩后,再返回响应给客户端,客户端需要进行解压解码后再进行处理。一般http框架和web框架都能自动进行自动的处理。 +> - `Referer`: 说明请求是从哪里来的 +> - `Cookie`: 向服务器请求时附带的一些信息,就是咱们常说的cookie,浏览器在请求的时候如果有相对应的Cookie,会自动附带上这些Cookie进行请求。 +> - `Set-Cookie`: 服务端响应回来的Cookie,浏览器看到这个header之后就会根据这个header的值去保存cookie到浏览器里边。下次请求cookie对应规则的地址时会自动附带这些信息,即上一条中的Cookie字段。 + +Cookie一般用于用户的识别和身份认证以及一些额外信息的保存。[了解更多关于Cookie的东西](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies) + +实际上,很多header值只是作为一个参考,作为后端开发,不应该过于信赖前端/客户端发来的数据,后端程序必须要对前端/客户端做充足的数据校验,如`Content-Type`,前端/客户端可以在请求的时候在`Content-Type`字段里说他发了`image/png`图片,但是可能实际上发来的数据是一个程序,如果不做任何校验直接保存到服务器上,那可就麻烦大了。 + +一般来说,很多http请求和web服务框架都能帮咱们写好这些通用的请求头和响应头,不用咱们过于操心,当然,如果有需求更改的话也能更改好。 + +这里对header的作用描述不一定十分的准确,可以查看相关的文档了解详细详情:[HTTP 标头(header)](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers),Ctrl+F直接一搜就到 + +#### 『主体』(body) + +在前面的header定义完之后,需要各一行空行,才到http消息中的『主体』部分。 + +这个body部分就是这个请求真正想要传输的数据。 + +这部分可以是纯文本,也可以是二进制,都行,只要Content-Type说好了就行,没说的话,一般也行,但是得看后端处不处理了,一些后端框架不会帮你自动判断Body格式,或者不同的Content-Type处理的方式不同,如果请求的时候没有设置对,可能会有些麻烦事。 + +> 另外,上面的起始行/状态行和header行以及body和上面几行中间间隔的空行,和windows一样,使用的换行符都为CRLF,也就是`\r\n`,而不是linux/unix常用的`\n`。当然,这个知道就好了,库会帮咱们处理好的。 + +### HTTPS + +HTTPS就是加密后的HTTP,'S'就是"Secure"。一般使用TLS来加密。原始的http消息经过全部加密后,再进行传输。只要中间偷听的人拿不到密钥,就不可能知道除了请求的ip以外任何的http信息。 + +关于现代TLS加密的机制,可以去看看[这篇文章](https://zhuanlan.zhihu.com/p/43789231) + +一般约定http跑在80端口上,而https跑在443端口上,但是也可以用其他端口。 + +我的建议是,https能上就上。 + +#### Teleport1 + +## 主线任务:Servlet,Tomcat + +## Servlet + +在开始Tomcat的学习之前,咱们先要了解Servlet。 \ No newline at end of file diff --git a/source/backend_tutorial/index.md b/source/backend_tutorial/index.md new file mode 100644 index 0000000..94e2b71 --- /dev/null +++ b/source/backend_tutorial/index.md @@ -0,0 +1,6 @@ +title: 后端教程 +date: 2023-05-13 15:50:00 +--- +### 后端教程 + +这里是后端教程的首页。 \ No newline at end of file diff --git a/source/categories/index.md b/source/categories/index.md new file mode 100644 index 0000000..73b55de --- /dev/null +++ b/source/categories/index.md @@ -0,0 +1,4 @@ +--- +title: categories +date: 2022-02-23 20:01:42 +--- diff --git a/source/giants/index.md b/source/giants/index.md new file mode 100644 index 0000000..a2fefb8 --- /dev/null +++ b/source/giants/index.md @@ -0,0 +1,12 @@ +title: 大佬们 +date: 2022-03-07 15:17:03 +--- +*这里收录了一些大佬们的链接,有空可以去逛逛哦* + +--- + +[柳婼 の blog – 我不管,反正我最萌~ (liuchuo.net)](https://www.liuchuo.net/) + +[Monkeyhbd - 猴猴的奇妙屋 (cn)](http://www.monkeyhbd.cn/) + +[Monkeyhbd - 猴猴的奇妙屋 (global)](http://www.monkeyhbd.com/) \ No newline at end of file diff --git a/source/images/pasted-0.png b/source/images/pasted-0.png new file mode 100644 index 0000000..acbdfac Binary files /dev/null and b/source/images/pasted-0.png differ diff --git a/source/ipv6/index.md b/source/ipv6/index.md new file mode 100644 index 0000000..1666947 --- /dev/null +++ b/source/ipv6/index.md @@ -0,0 +1,12 @@ +title: ipv6 +date: 2022-03-20 16:55:43 +--- +#### **本小破站已支持ipv6!** + +当您支持使用ipv6方式访问时,将会自动切换成ipv6地址进行传输 + +以下链接是本站的纯ipv6版。 + +如果您无法通过该链接访问,可能是您并不支持ipv6访问 + +https://ipv6.ciduid.top \ No newline at end of file diff --git a/source/microBlog/index.md b/source/microBlog/index.md new file mode 100644 index 0000000..65011d9 --- /dev/null +++ b/source/microBlog/index.md @@ -0,0 +1,8 @@ +title: 只言片语 +date: 2022-03-07 15:20:44 +--- +*这里记录的是一些零碎的小事情,因为没必要单独开一个文章,所以就在这里单独放一个页面* + +--- + +- gitlab居然要4gb的内存...像我这种2gb的低配服还是算了吧...刚刚装上去卡得不得了...后来还是卸了,转用gitea了 \ No newline at end of file diff --git a/source/nginx-docs/beginners-guide.md b/source/nginx-docs/beginners-guide.md new file mode 100644 index 0000000..cfb934b --- /dev/null +++ b/source/nginx-docs/beginners-guide.md @@ -0,0 +1,341 @@ +title: 初级教程 +cover: https://res.ciduid.top/blog/covers/cover(8).jpg +date: 2022-08-06 16:52:03 +--- + +> 读nginx文档的时候突然想自己试着把文档翻一翻了... +> +> 这些翻译并没有严格按照英语语法去对应中文,而是经过自己的一点修改 +> +> 翻译得并不是很好,只是自己学习文档的同时顺便翻译翻译,还请见谅.... +> +> 将来会不定期更新的...要是哪天弃坑了也不是不可能... + + +## Beginner’s Guide / 初级教程 + +This guide gives a basic introduction to nginx and describes some simple +tasks that can be done with it. It is supposed that nginx is already +installed on the reader’s machine. If it is not, see the [Installing nginx](https://nginx.org/en/docs/install.html) page. This guide describes how to start and stop nginx, and reload its configuration, explains the structure of the configuration file and describes how to set up nginx to serve out static content, how to configure nginx as a proxy server, and how to connect it with a FastCGI application. + +本教程介绍了一些基本的nginx指令及其相关用法和使用场景,该教程假定nginx已经安装在您的设备上,如果您还未安装nginx,请前往“[安装nginx](https://nginx.org/en/docs/install.html)”进行安装。 + +该教程主要内容有: + +- 启动与停止nginx以及配置文件的热重载 + +- 配置文件的结构 + +- 如何使用nginx来分发静态内容 + +- 如何将nginx配置为一个代理服务器,以及如何通过FastCGI来连接其他应用。 + +nginx has one master process and several worker processes. The main purpose of the master process is to read and **evaluate** configuration, and maintain worker processes. Worker processes do actual processing of requests. nginx employs **event-based model** and **OS-dependent mechanisms** to efficiently **distribute** requests among worker processes. The number of worker processes is defined in the configuration file and may be fixed for a given configuration or automatically adjusted to the number of available CPU cores (see [worker_processes](https://nginx.org/en/docs/ngx_core_module.html#worker_processes)). + +nginx在运行中会创建一个master进程和若干个worker进程。master进程主要用于读取并验证配置文件以及worker进程的**维护**,而真正的请求则是由worker进程来处理。 + +nginx采用**事件驱动模型**以及**系统相关机制**来高效地将请求**分发**给各个worker进程,worker进程的数量被定义在配置文件中,但是,这个数量可能会固定为配置文件所设置的大小,也有可能会调整为可用的CPU内核数。详见:[worker进程](https://nginx.org/en/docs/ngx_core_module.html#worker_processes) + +The way nginx and its modules work is determined in the configuration file. By default, the configuration file is named `nginx.conf` and placed in the directory `/usr/local/nginx/conf`, `/etc/nginx`, or `/usr/local/etc/nginx`. + +nginx及其相关的模块的工作方式是由配置文件决定的。nginx的配置文件默认为`nginx.conf`,该文件一般位于`/usr/local/nginx/conf`、`/etc/nginx`或` /usr/local/etc/nginx`这几个文件夹中。 + +#### 启动、停止以及热重载配置文件 / Starting, Stopping, and Reloading Configuration + +To start nginx, run the executable file. Once nginx is started, it can be controlled by **invoking** the executable with the `-s` parameter. Use the following **syntax**: + +要启动nginx,只需运行nginx的二进制可执行文件即可。nginx启动后,使用`-s`参数**调用**可执行文件就能控制nginx的启停以及配置文件重载。以下是相关调用**语法**: + +> nginx -s *signal* + +Where *signal* may be one of the following: + +`signal`应为一下几种情况: + +- `stop` — 快速停止 + +- `quit` — “优雅”地停止 + +- `reload` — 重新加载配置文件 + +- `reopen` — 重新打开日志文件 + +For example, to stop nginx processes with waiting for the worker processes to finish serving current requests, the following command can be executed: + +例如,要使nginx的worker进程结束完当前所有的请求之后再停止,应当这样执行: + +> nginx -s quit + +*This command should be executed under the same user that started nginx.* + +*该命令应当由启动nginx的用户执行* + +Changes made in the configuration file will not be applied until the command to reload configuration is sent to nginx or it is restarted. To reload configuration, execute: + +如果对配置文件进行了修改,这些修改不会立即生效。您应当将执行重载配置文件命令发送给nginx或者直接将其重启。 + +若要重载配置文件,请执行: + +> nginx -s reload + +Once the master process receives the signal to reload configuration, it checks the **syntax validity** of the new configuration file and tries to apply the configuration provided in it. If this is a success, the master process starts new worker processes and sends messages to old worker processes, requesting them to shut down. Otherwise, the master process rolls back the changes and continues to work with the old configuration. Old worker processes, receiving a command to shut down, stop accepting new connections and continue to service current requests until all such requests are serviced. After that, the old worker processes exit. + +master进程一旦接收到这个重载配置文件的信号,其会检查配置文件**语法的正确性**然后尝试应用这些修改。如果成功,master进程则会启动新的worker进程并且将消息发送给旧的worker进程,要求其停止。否则master进程不会去应用这些更改,并继续以旧的配置来工作。 + +旧的worker进程收到关闭命令后,不会再接受新的连接请求,但仍在进行的请求仍会被处理,直到这些请求完成。最后,旧的worker进程就会退出。 + +A signal may also be sent to nginx processes with the help of Unix tools such as the `kill` utility. In this case a signal is sent directly to a process with a given process ID. The process ID of the nginx master process is written, by default, to the `nginx.pid` in the directory `/usr/local/nginx/logs` or `/var/run`. For example, if the master process ID is 1628, to send the QUIT signal resulting in nginx’s graceful shutdown, execute: + +控制信号也可以通过一些例如`kill`等Unix工具来发送给nginx进程。这样就可以通过指定的PID来直接向nginx进程发送信号。这些nginx PID默认记录在`nginx.pid`文件中,该文件一般位于`/usr/local/nginx/logs`或`/var/run`文件夹中。 + +例如,master进程的PID为1628,要向其发送`QUIT`信号来将nginx“优雅”地关闭,应当这样执行命令: + +> kill -s QUIT 1628 + +For getting the list of all running nginx processes, the `ps` utility may be used, for example, in the following way: + +要获得所有的nginx进程信息,可以使用`ps`命令,例如: + +> ps -ax | grep nginx + +For more information on sending signals to nginx, see [Controlling nginx](https://nginx.org/en/docs/control.html). + +想要了解更多的关于将信号发送至nginx进程的方法,详见:[控制nginx](https://nginx.org/en/docs/control.html) + +#### 配置文件结构 / Configuration File’s Structure + +nginx consists of modules which are controlled by **directives** specified in the configuration file. Directives are divided into simple directives and block directives. A simple directive consists of the name and parameters **separated** by spaces and ends with a **semicolon**(`;`). A block directive has the same structure as a simple directive, but instead of the semicolon it ends with a set of additional instructions surrounded by **braces** (`{` and `}`). If a block directive can have other directives inside braces, it is called a context (examples: [events](https://nginx.org/en/docs/ngx_core_module.html#events), [http](https://nginx.org/en/docs/http/ngx_http_core_module.html#http), [server](https://nginx.org/en/docs/http/ngx_http_core_module.html#server), and [location](https://nginx.org/en/docs/http/ngx_http_core_module.html#location)). + +nginx是由多个模块构成的,而这些模块是由配置文件中设定的**指令**控制的。 + +这些指令分成数个基本指令和指令块。一条基本指令包括指令名及若干个以空格**分隔**的参数,并且以`;`(**分号**)结束。指令块跟基本指令有相似的结构,但跟基本指令不同的是,指令块不以分号结束,而是以一组**大括号**括起来的附加指令结束。如果一个指令块的大括号里边包括有其他的指令,则会被称为~~*“context”*~~(姑且也成为块吧...)(例如:[events块](https://nginx.org/en/docs/ngx_core_module.html#events)、[http块](https://nginx.org/en/docs/http/ngx_http_core_module.html#http)、 [server块](https://nginx.org/en/docs/http/ngx_http_core_module.html#server)以及[location块](https://nginx.org/en/docs/http/ngx_http_core_module.html#location)) + +Directives placed in the configuration file outside of any contexts are considered to be in the [main](https://nginx.org/en/docs/ngx_core_module.html) context. The `events` and `http` directives reside in the `main` context, `server` in `http`, and `location` in `server`. + +The rest of a line after the `#` sign is considered a comment. + +放置在任何块之外的指令被视作是放置于main块当中。`events`和`http`指令块是放在main块中的;`server`块是放在`http`块中的;而`location`块则又放置在`server`块中 + +在一行中以`#`开始的部分则会被视作注释。 + +#### 处理静态内容请求 / Serving Static Content + +An important web server task is serving out files (such as images or static HTML pages). You will implement an example where, depending on the request, files will be served from different local directories: `/data/www` (which may contain HTML files) and `/data/images` (containing images). This will require editing of the configuration file and setting up of a [server](https://nginx.org/en/docs/http/ngx_http_core_module.html#server) block inside the [http](https://nginx.org/en/docs/http/ngx_http_core_module.html#http) block with two [location](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) blocks. + +传输文件(例如图像或者静态HTML页面之类的数据)是网络服务中非常重要的一部分。 + +你在这里将会实现一个根据请求来从本地目录`/data/www`(包含了HTML文件)和`/data/image`(包含了图像)对外分提供文件的例子。 + +这需要你编辑配置文件并在http块中设置一个server块,而在这个server块中又包含有两个location块。 + +First, create the `/data/www` directory and put an `index.html` file with any text content into it and create the `/data/images` directory and place some images in it. + +首先,创建`/data/www`目录,并将一个`index.html`文件放置于其中,文件内容文本随意;同时还应当创建好`/data/images`目录,并把一些图片放进去。 + +Next, open the configuration file. The default configuration file already includes several examples of the `server` block, mostly **commented out**. For now comment out all such blocks and start a new `server` block: + +接着,打开配置文件。默认的配置文件已经包含有一些`server`块的例子了,大部分是被**注释掉**的。现在,把所有的类似的块都给注释掉,然后自己新建一个`server`块。 + +```nginx +http { + server { + } +} +``` + +Generally, the configuration file may include several `server` blocks [distinguished](https://nginx.org/en/docs/http/request_processing.html) by ports on which they [listen](https://nginx.org/en/docs/http/ngx_http_core_module.html#listen) to and by [server names](https://nginx.org/en/docs/http/server_names.html). Once nginx decides which `server` processes a request, it tests the URI specified in the request’s header against the parameters of the `location` directives defined inside the `server` block. + +通常来说,配置文件可能会包含好几个`server`块,这些`server`块是根据其[侦听的端口(listen)](https://nginx.org/en/docs/http/ngx_http_core_module.html#listen)以及[服务器名(server_name)](https://nginx.org/en/docs/http/server_names.html)来进行[区分](https://nginx.org/en/docs/http/request_processing.html)的,nginx会把在请求头中指定的URI参数与在`server`块中`location`指令的参数进行匹配。 + +Add the following `location` block to the `server` block: + +在`server`块添加一个像这样的`location`块: + +```nginx +loaction / { + root /data/www; +} +``` + +This `location` block specifies the “`/`” prefix compared with the URI from the request. For matching requests, the URI will be added to the path specified in the [root](https://nginx.org/en/docs/http/ngx_http_core_module.html#root) directive, that is, to `/data/www`, to form the path to the requested file on the local file system. If there are several matching `location` blocks nginx selects the one with the longest prefix. The `location` block above provides the shortest prefix, of length one, and so only if all other `location` blocks fail to provide a match, this block will be used. + +Next, add the second `location` block: + +(前缀(路径)匹配规则)这个`location`块指定了与之相配的URI路径`/`。对于匹配到的请求,这个URI会被添加到在[root](https://nginx.org/en/docs/http/ngx_http_core_module.html#root)指令中设定的路径,也就是`/data/www`,以形成请求本地文件的路径。如有多个`location`块能被匹配到,nginx会使用路径最长的那个`location`块。上述示例中的`location`块只提供了最短的路径,长度为1,所以在只有其他路径都匹配不到的时候才会被使用。 + +接着,添加第二个`location`块: + +```nginx +location /images/ { + root /data; +} +``` + +It will be a match for requests starting with `/images/` (`location /` also matches such requests, but has shorter prefix). + +The resulting configuration of the `server` block should look like this: + +这能够使其匹配到以`/images/`开头的请求(当然`location /`也能被匹配到,但它的路径更短,所以不会被使用)。 + +最终这个`server`块是这样子的: + +```nginx +server { + location / { + root /data/www; + } + + location /images/ { + root /data; + } +} +``` + +This is already a working configuration of a server that listens on the standard port 80 and is accessible on the local machine at `http://localhost/`. In response to requests with URIs starting with `/images/`, the server will send files from the `/data/images` directory. For example, in response to the `http://localhost/images/example.png` request nginx will send the `/data/images/example.png` file. If such file does not exist, nginx will send a response **indicating** the 404 error. Requests with URIs not starting with `/images/` will be **mapped onto** the `/data/www` directory. For example, in response to the `http://localhost/some/example.html` request nginx will send the `/data/www/some/example.html` file. + +现在,这个`server`块侦听在80端口上,在本地计算机通过地址`http://localhost/`就能访问到。 + +对于以`/images/`为开头的请求,服务器会从`/data/images/`目录获取文件,并将文件数据返回。 + +- 例如:对于请求`http://localhost/images/example.png`,nginx将会把`/data/images/example.png`文件发送出去。 + +如果文件不存在,nginx会发送**表示**404错误的响应。除了`/images/`为开头的请求,其他的请求都会被**映射到**`/data/www`文件夹中。 + +- 例如:对于请求`http://localhost/some/example.html`,nginx将会把`/data/www/some/example.html`文件发送出去。 + +To apply the new configuration, start nginx if it is not yet started or send the `reload` signal to the nginx’s master process, by executing: + +为了使配置生效,启动nginx(如果nginx没有启动起来的话),或者通过执行以下命令来将`reload`命令发送给nginx的master进程: + +> nginx -s reload + +In case something does not work as expected, you may try to find out the reason in `access.log` and `error.log` files in the directory `/usr/local/nginx/logs` or `/var/log/nginx`. + +如果因为各种原因,nginx并没有像预期的那样工作,你应该去在`/usr/local/nginx/logs` 或者 `/var/log/nginx`的日志文件`access.log`和`error.log`那里看看出什么问题了。 + +#### 设置一个简单的反代服务器 / Setting Up a Simple Proxy Server + +One of the **frequent** uses of nginx is setting it up as a proxy server, which means a server that receives requests, **passes** them to the proxied servers, **retrieves** responses from them, and sends them to the clients. + +nginx的另一个**常用**的用法是将其设成一个代理服务器,这意味着发送到服务器的请求会被路由**转发**到被代理的服务器上,并且相应的响应也会被转发回客户端(请求者)。 + +We will configure a basic proxy server, which serves requests of images with files from the local directory and sends all other requests to a proxied server. In this example, both servers will be defined on a single nginx **instance**. + +这里,我们将会设置一个基本的代理服务器,来实现将本地的图片请求发送出去,并且把其他所有的请求交给被代理的服务器。在这个例子中,两个服务器(被代理服务器、代理服务器)都是设定在同一个nginx**实例**上的。 + +First, define the proxied server by adding one more `server` block to the nginx’s configuration file with the following contents: + +首先,新增一个`server`块到nginx的配置文件中,像下面那样,以便新增一个被代理服务器: + +```nginx +server { + listen 8080; + root /data/up1; + + location / { + } +} +``` + +This will be a simple server that listens on the port 8080 (previously, the `listen` directive has not been specified since the standard port 80 was used) and maps all requests to the `/data/up1` directory on the local file system. Create this directory and put the `index.html` file into it. Note that the `root` directive is placed in the `server` context. Such `root` directive is used when the `location` block selected for serving a request does not include its own `root` directive. + +这样,一个侦听在8080端口的服务器就成了(在之前的例子中,由于没有定义`listen`,因此侦听的是默认的80端口),在这个服务器中,所有的请求都会映射到本地文件系统的`/data/up1`目录中。把这个目录创建好,然后把`index.html`放在里边。 + +这里的`root`指令是放在`server`部分的。像这种在`location`外的`root`指令是`location`里面没有指定`root`的时候生效的 + +Next, use the server configuration from the previous section and modify it to make it a proxy server configuration. In the first `location` block, put the [proxy_pass](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass) directive with the protocol, name and port of the proxied server specified in the parameter (in our case, it is `http://localhost:8080`): + +接着,用回之前的例子,改一改,来让这个配置文件设置成一个代理服务器的配置文件。在第一个`location`里边,加入[proxy_pass](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass)指令,在其参数中带上想要代理的服务器的协议、名称(地址)以及端口,在我们的这个例子中,应该写成`http://localhost:8080`。 + +```nginx +server { + location / { + proxy_pass http://localhost:8080; + } + location /images/ { + root /data; + } +} +``` + +We will modify the second `location` block, which currently maps requests with the `/images/` prefix to the files under the `/data/images` directory, to make it match the requests of images with typical file extensions. The modified `location` block looks like this: + +修改第二个`location`块,它能把路径为`/images/`开头的的请求路由到`/data/images`目录下,并且只匹配后缀为`.gif`、`.jpg`或`.png`的文件请求。 + +修改后的`location`块如下所示: + +```nginx +location ~ \.(gif|jpg|png)$ { + root /data/images; +} +``` + +The parameter is a regular expression matching all URIs ending with `.gif`, `.jpg`, or `.png`. A regular expression should be preceded with `~`. The corresponding requests will be mapped to the `/data/images` directory. + +这个参数是一个正则表达式,能匹配所有以`.gif`、`.jpg`或`.png`结尾的URI。正则表达式前面应加上`~`。相应的请求将被映射到`/data/images`目录中。 + +When nginx selects a `location` block to serve a request it first checks [location](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) directives that specify prefixes, remembering `location` with the longest prefix, and then checks regular expressions. If there is a match with a regular expression, nginx picks this `location` or, otherwise, it picks the one remembered earlier. + +The resulting configuration of a proxy server will look like this: + +当nginx选择用哪一个`location`块来处理请求时,它首先检查指定路径的[location](https://nginx.org/en/docs/http/ngx_http_core_module.html#location)指令,然后再检查用正则表达式的`location`。如果有匹配,nginx会就选择这个用正则表达式作为参数的`location`,否则就使用路径最长的`location`块来处理请求。 + +最终的配置是这样的: + +```nginx +server { + location / { + proxy_pass http://localhost:8080/; + } + location ~ \.(gif|jpg|png)$ { + root /data/images; + } +} +``` + +This server will filter requests ending with `.gif`, `.jpg`, or `.png` and map them to the `/data/images` directory (by adding URI to the `root` directive’s parameter) and pass all other requests to the proxied server configured above. + +To apply new configuration, send the `reload` signal to nginx as described in the previous sections. + +There are many [more](https://nginx.org/en/docs/http/ngx_http_proxy_module.html) directives that may be used to further configure a proxy connection. + +现在,这个`server`能够处理以`.gif`、`.jpg`或`.png`结尾的请求,并将它们映射到`/data/images`目录(通过在`root`指令的参数中添加URI路径作为真实文件路径),其他的请求就会转发到配置好的被代理服务器上。 + +要让配置生效,还是想上面那样,运行`nginx -s reload`。 + +有[很多指令](https://nginx.org/en/docs/http/ngx_http_proxy_module.html)可以用来进一步配置代理连接。 + +#### Setting Up FastCGI Proxying / FastCGI代理设置 + +nginx can be used to route requests to FastCGI servers which run applications built with various frameworks and programming languages such as PHP. + +The most basic nginx configuration to work with a FastCGI server includes using the [fastcgi_pass](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass) directive instead of the `proxy_pass` directive, and [fastcgi_param](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param) directives to set parameters passed to a FastCGI server. Suppose the FastCGI server is accessible on `localhost:9000`. Taking the proxy configuration from the previous section as a basis, replace the `proxy_pass` directive with the `fastcgi_pass` directive and change the parameter to `localhost:9000`. In PHP, the `SCRIPT_FILENAME` parameter is used for determining the script name, and the `QUERY_STRING` parameter is used to pass request parameters. The resulting configuration would be: + +nginx可以用来路由请求到FastCGI服务器,以便运行用各种框架和编程语言(如PHP)构建的应用程序。 + +在这里的配置中,代理转发用的是[fastcgi_pass](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_pass)指令而不是`proxy_pass`指令;[fastcgi_param](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param)指令是用来设置传递给FastCGI服务器的参数。 + +假设我们的FastCGI服务器运行在`localhost:9000`上。 + +以上一节的代理配置为基础,将`proxy_pass`指令改成`fastcgi_pass`,把参数改成`localhost:9000`。 + +在PHP中,`SCRIPT_FILENAME`参数用来确定脚本名称,`QUERY_STRING`参数是用来用于传递请求参数的。 + +最终的配置是这样的: + +```nginx +server { + location / { + fastcgi_pass localhost:9000; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param QUERY_STRING $query_string; + } + location ~ \.(gif|jpg|png)$ { + root /data/images; + } +} +``` + +This will set up a server that will route all requests except for requests for static images to the proxied server operating on `localhost:9000` through the FastCGI protocol. + +这样,nginx就会通过FastCGI协议把所有的请求(除了那些图像的静态请求)路由到运行在`localhost:9000`的FastCGI服务器上。 \ No newline at end of file diff --git a/source/nginx-docs/configure.md b/source/nginx-docs/configure.md new file mode 100644 index 0000000..4f069eb --- /dev/null +++ b/source/nginx-docs/configure.md @@ -0,0 +1,506 @@ +## Building nginx from Sources + +The build is configured using the `configure` command. It defines various aspects of the system, including the methods nginx is allowed to use for connection processing. At the end it creates a `Makefile`. + +The `configure` command supports the following parameters: + +`--help` + +prints a help message. + +``--prefix=`*path*` `` + +defines a directory that will keep server files. This same directory will also be used for all relative paths set by `configure` (except for paths to libraries sources) and in the `nginx.conf` configuration file. It is set to the `/usr/local/nginx` directory by default. + +``--sbin-path=`*path*` `` + +sets the name of an nginx executable file. This name is used only during installation. By default the file is named `` `*prefix*`/sbin/nginx``. + +``--modules-path=`*path*` `` + +defines a directory where nginx dynamic modules will be installed. By default the `` `*prefix*`/modules`` directory is used. + +``--conf-path=`*path*` `` + +sets the name of an `nginx.conf` configuration file. If needs be, nginx can always be started with a different configuration file, by specifying it in the command-line parameter ``-c `*file*` ``. By default the file is named `` `*prefix*`/conf/nginx.conf``. + +``--error-log-path=`*path*` `` + +sets the name of the primary error, warnings, and diagnostic file. After installation, the file name can always be changed in the `nginx.conf` configuration file using the [error_log](https://nginx.org/en/docs/ngx_core_module.html#error_log) directive. By default the file is named `` `*prefix*`/logs/error.log``. + +``--pid-path=`*path*` `` + +sets the name of an `nginx.pid` file that will store the process ID of the main process. After installation, the file name can always be changed in the `nginx.conf` configuration file using the [pid](https://nginx.org/en/docs/ngx_core_module.html#pid) directive. By default the file is named `` `*prefix*`/logs/nginx.pid``. + +``--lock-path=`*path*` `` + +sets a prefix for the names of lock files. After installation, the value can always be changed in the `nginx.conf` configuration file using the [lock_file](https://nginx.org/en/docs/ngx_core_module.html#lock_file) directive. By default the value is `` `*prefix*`/logs/nginx.lock``. + +``--user=`*name*` `` + +sets the name of an unprivileged user whose credentials will be used by worker processes. After installation, the name can always be changed in the `nginx.conf` configuration file using the [user](https://nginx.org/en/docs/ngx_core_module.html#user) directive. The default user name is nobody. + +``--group=`*name*` `` + +sets the name of a group whose credentials will be used by worker processes. After installation, the name can always be changed in the `nginx.conf` configuration file using the [user](https://nginx.org/en/docs/ngx_core_module.html#user) directive. By default, a group name is set to the name of an unprivileged user. + +``--build=`*name*` `` + +sets an optional nginx build name. + +``--builddir=`*path*` `` + +sets a build directory. + +`--with-select_module` +`--without-select_module` + +enables or disables building a module that allows the server to work with the `select()` method. This module is built automatically if the platform does not appear to support more appropriate methods such as kqueue, epoll, or /dev/poll. + +`--with-poll_module` +`--without-poll_module` + +enables or disables building a module that allows the server to work with the `poll()` method. This module is built automatically if the platform does not appear to support more appropriate methods such as kqueue, epoll, or /dev/poll. + +`--with-threads` + +enables the use of [thread pools](https://nginx.org/en/docs/ngx_core_module.html#thread_pool). + +`--with-file-aio` + +enables the use of [asynchronous file I/O](https://nginx.org/en/docs/http/ngx_http_core_module.html#aio) (AIO) on FreeBSD and Linux. + +`--with-http_ssl_module` + +enables building a module that adds the [HTTPS protocol support](https://nginx.org/en/docs/http/ngx_http_ssl_module.html) to an HTTP server. This module is not built by default. The OpenSSL library is required to build and run this module. + +`--with-http_v2_module` + +enables building a module that provides support for [HTTP/2](https://nginx.org/en/docs/http/ngx_http_v2_module.html). This module is not built by default. + +`--with-http_realip_module` + +enables building the [ngx_http_realip_module](https://nginx.org/en/docs/http/ngx_http_realip_module.html) module that changes the client address to the address sent in the specified header field. This module is not built by default. + +`--with-http_addition_module` + +enables building the [ngx_http_addition_module](https://nginx.org/en/docs/http/ngx_http_addition_module.html) module that adds text before and after a response. This module is not built by default. + +`--with-http_xslt_module` +`--with-http_xslt_module=dynamic` + +enables building the [ngx_http_xslt_module](https://nginx.org/en/docs/http/ngx_http_xslt_module.html) module that transforms XML responses using one or more XSLT stylesheets. This module is not built by default. The [libxml2](http://xmlsoft.org/) and [libxslt](http://xmlsoft.org/XSLT/) libraries are required to build and run this module. + +`--with-http_image_filter_module` +`--with-http_image_filter_module=dynamic` + +enables building the [ngx_http_image_filter_module](https://nginx.org/en/docs/http/ngx_http_image_filter_module.html) module that transforms images in JPEG, GIF, PNG, and WebP formats. This module is not built by default. + +`--with-http_geoip_module` +`--with-http_geoip_module=dynamic` + +enables building the [ngx_http_geoip_module](https://nginx.org/en/docs/http/ngx_http_geoip_module.html) module that creates variables depending on the client IP address and the precompiled [MaxMind](http://www.maxmind.com/) databases. This module is not built by default. + +`--with-http_sub_module` + +enables building the [ngx_http_sub_module](https://nginx.org/en/docs/http/ngx_http_sub_module.html) module that modifies a response by replacing one specified string by another. This module is not built by default. + +`--with-http_dav_module` + +enables building the [ngx_http_dav_module](https://nginx.org/en/docs/http/ngx_http_dav_module.html) module that provides file management automation via the WebDAV protocol. This module is not built by default. + +`--with-http_flv_module` + +enables building the [ngx_http_flv_module](https://nginx.org/en/docs/http/ngx_http_flv_module.html) module that provides pseudo-streaming server-side support for Flash Video (FLV) files. This module is not built by default. + +`--with-http_mp4_module` + +enables building the [ngx_http_mp4_module](https://nginx.org/en/docs/http/ngx_http_mp4_module.html) module that provides pseudo-streaming server-side support for MP4 files. This module is not built by default. + +`--with-http_gunzip_module` + +enables building the [ngx_http_gunzip_module](https://nginx.org/en/docs/http/ngx_http_gunzip_module.html) module that decompresses responses with “`Content-Encoding: gzip`” for clients that do not support “gzip” encoding method. This module is not built by default. + +`--with-http_gzip_static_module` + +enables building the [ngx_http_gzip_static_module](https://nginx.org/en/docs/http/ngx_http_gzip_static_module.html) module that enables sending precompressed files with the “`.gz`” filename extension instead of regular files. This module is not built by default. + +`--with-http_auth_request_module` + +enables building the [ngx_http_auth_request_module](https://nginx.org/en/docs/http/ngx_http_auth_request_module.html) module that implements client authorization based on the result of a subrequest. This module is not built by default. + +`--with-http_random_index_module` + +enables building the [ngx_http_random_index_module](https://nginx.org/en/docs/http/ngx_http_random_index_module.html) module that processes requests ending with the slash character (‘`/`’) and picks a random file in a directory to serve as an index file. This module is not built by default. + +`--with-http_secure_link_module` + +enables building the [ngx_http_secure_link_module](https://nginx.org/en/docs/http/ngx_http_secure_link_module.html) module. This module is not built by default. + +`--with-http_degradation_module` + +enables building the `ngx_http_degradation_module` module. This module is not built by default. + +`--with-http_slice_module` + +enables building the [ngx_http_slice_module](https://nginx.org/en/docs/http/ngx_http_slice_module.html) module that splits a request into subrequests, each returning a certain range of response. The module provides more effective caching of big responses. This module is not built by default. + +`--with-http_stub_status_module` + +enables building the [ngx_http_stub_status_module](https://nginx.org/en/docs/http/ngx_http_stub_status_module.html) module that provides access to basic status information. This module is not built by default. + +`--without-http_charset_module` + +disables building the [ngx_http_charset_module](https://nginx.org/en/docs/http/ngx_http_charset_module.html) module that adds the specified charset to the “Content-Type” response header field and can additionally convert data from one charset to another. + +`--without-http_gzip_module` + +disables building a module that [compresses responses](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) of an HTTP server. The zlib library is required to build and run this module. + +`--without-http_ssi_module` + +disables building the [ngx_http_ssi_module](https://nginx.org/en/docs/http/ngx_http_ssi_module.html) module that processes SSI (Server Side Includes) commands in responses passing through it. + +`--without-http_userid_module` + +disables building the [ngx_http_userid_module](https://nginx.org/en/docs/http/ngx_http_userid_module.html) module that sets cookies suitable for client identification. + +`--without-http_access_module` + +disables building the [ngx_http_access_module](https://nginx.org/en/docs/http/ngx_http_access_module.html) module that allows limiting access to certain client addresses. + +`--without-http_auth_basic_module` + +disables building the [ngx_http_auth_basic_module](https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html) module that allows limiting access to resources by validating the user name and password using the “HTTP Basic Authentication” protocol. + +`--without-http_mirror_module` + +disables building the [ngx_http_mirror_module](https://nginx.org/en/docs/http/ngx_http_mirror_module.html) module that implements mirroring of an original request by creating background mirror subrequests. + +`--without-http_autoindex_module` + +disables building the [ngx_http_autoindex_module](https://nginx.org/en/docs/http/ngx_http_autoindex_module.html) module that processes requests ending with the slash character (‘`/`’) and produces a directory listing in case the [ngx_http_index_module](https://nginx.org/en/docs/http/ngx_http_index_module.html) module cannot find an index file. + +`--without-http_geo_module` + +disables building the [ngx_http_geo_module](https://nginx.org/en/docs/http/ngx_http_geo_module.html) module that creates variables with values depending on the client IP address. + +`--without-http_map_module` + +disables building the [ngx_http_map_module](https://nginx.org/en/docs/http/ngx_http_map_module.html) module that creates variables with values depending on values of other variables. + +`--without-http_split_clients_module` + +disables building the [ngx_http_split_clients_module](https://nginx.org/en/docs/http/ngx_http_split_clients_module.html) module that creates variables for A/B testing. + +`--without-http_referer_module` + +disables building the [ngx_http_referer_module](https://nginx.org/en/docs/http/ngx_http_referer_module.html) module that can block access to a site for requests with invalid values in the “Referer” header field. + +`--without-http_rewrite_module` + +disables building a module that allows an HTTP server to [redirect requests and change URI of requests](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html). The PCRE library is required to build and run this module. + +`--without-http_proxy_module` + +disables building an HTTP server [proxying module](https://nginx.org/en/docs/http/ngx_http_proxy_module.html). + +`--without-http_fastcgi_module` + +disables building the [ngx_http_fastcgi_module](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html) module that passes requests to a FastCGI server. + +`--without-http_uwsgi_module` + +disables building the [ngx_http_uwsgi_module](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html) module that passes requests to a uwsgi server. + +`--without-http_scgi_module` + +disables building the [ngx_http_scgi_module](https://nginx.org/en/docs/http/ngx_http_scgi_module.html) module that passes requests to an SCGI server. + +`--without-http_grpc_module` + +disables building the [ngx_http_grpc_module](https://nginx.org/en/docs/http/ngx_http_grpc_module.html) module that passes requests to a gRPC server. + +`--without-http_memcached_module` + +disables building the [ngx_http_memcached_module](https://nginx.org/en/docs/http/ngx_http_memcached_module.html) module that obtains responses from a memcached server. + +`--without-http_limit_conn_module` + +disables building the [ngx_http_limit_conn_module](https://nginx.org/en/docs/http/ngx_http_limit_conn_module.html) module that limits the number of connections per key, for example, the number of connections from a single IP address. + +`--without-http_limit_req_module` + +disables building the [ngx_http_limit_req_module](https://nginx.org/en/docs/http/ngx_http_limit_req_module.html) module that limits the request processing rate per key, for example, the processing rate of requests coming from a single IP address. + +`--without-http_empty_gif_module` + +disables building a module that [emits single-pixel transparent GIF](https://nginx.org/en/docs/http/ngx_http_empty_gif_module.html). + +`--without-http_browser_module` + +disables building the [ngx_http_browser_module](https://nginx.org/en/docs/http/ngx_http_browser_module.html) module that creates variables whose values depend on the value of the “User-Agent” request header field. + +`--without-http_upstream_hash_module` + +disables building a module that implements the [hash](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#hash) load balancing method. + +`--without-http_upstream_ip_hash_module` + +disables building a module that implements the [ip_hash](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#ip_hash) load balancing method. + +`--without-http_upstream_least_conn_module` + +disables building a module that implements the [least_conn](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#least_conn) load balancing method. + +`--without-http_upstream_random_module` + +disables building a module that implements the [random](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#random) load balancing method. + +`--without-http_upstream_keepalive_module` + +disables building a module that provides [caching of connections](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive) to upstream servers. + +`--without-http_upstream_zone_module` + +disables building a module that makes it possible to store run-time state of an upstream group in a shared memory [zone](https://nginx.org/en/docs/http/ngx_http_upstream_module.html#zone). + +`--with-http_perl_module` +`--with-http_perl_module=dynamic` + +enables building the [embedded Perl module](https://nginx.org/en/docs/http/ngx_http_perl_module.html). This module is not built by default. + +``--with-perl_modules_path=`*path*` `` + +defines a directory that will keep Perl modules. + +``--with-perl=`*path*` `` + +sets the name of the Perl binary. + +``--http-log-path=`*path*` `` + +sets the name of the primary request log file of the HTTP server. After installation, the file name can always be changed in the `nginx.conf` configuration file using the [access_log](https://nginx.org/en/docs/http/ngx_http_log_module.html#access_log) directive. By default the file is named `` `*prefix*`/logs/access.log``. + +``--http-client-body-temp-path=`*path*` `` + +defines a directory for storing temporary files that hold client request bodies. After installation, the directory can always be changed in the `nginx.conf` configuration file using the [client_body_temp_path](https://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_temp_path) directive. By default the directory is named `` `*prefix*`/client_body_temp``. + +``--http-proxy-temp-path=`*path*` `` + +defines a directory for storing temporary files with data received from proxied servers. After installation, the directory can always be changed in the `nginx.conf` configuration file using the [proxy_temp_path](https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_temp_path) directive. By default the directory is named `` `*prefix*`/proxy_temp``. + +``--http-fastcgi-temp-path=`*path*` `` + +defines a directory for storing temporary files with data received from FastCGI servers. After installation, the directory can always be changed in the `nginx.conf` configuration file using the [fastcgi_temp_path](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_temp_path) directive. By default the directory is named `` `*prefix*`/fastcgi_temp``. + +``--http-uwsgi-temp-path=`*path*` `` + +defines a directory for storing temporary files with data received from uwsgi servers. After installation, the directory can always be changed in the `nginx.conf` configuration file using the [uwsgi_temp_path](https://nginx.org/en/docs/http/ngx_http_uwsgi_module.html#uwsgi_temp_path) directive. By default the directory is named `` `*prefix*`/uwsgi_temp``. + +``--http-scgi-temp-path=`*path*` `` + +defines a directory for storing temporary files with data received from SCGI servers. After installation, the directory can always be changed in the `nginx.conf` configuration file using the [scgi_temp_path](https://nginx.org/en/docs/http/ngx_http_scgi_module.html#scgi_temp_path) directive. By default the directory is named `` `*prefix*`/scgi_temp``. + +`--without-http` + +disables the [HTTP](https://nginx.org/en/docs/http/ngx_http_core_module.html) server. + +`--without-http-cache` + +disables HTTP cache. + +`--with-mail` +`--with-mail=dynamic` + +enables POP3/IMAP4/SMTP [mail proxy](https://nginx.org/en/docs/mail/ngx_mail_core_module.html) server. + +`--with-mail_ssl_module` + +enables building a module that adds the [SSL/TLS protocol support](https://nginx.org/en/docs/mail/ngx_mail_ssl_module.html) to the mail proxy server. This module is not built by default. The OpenSSL library is required to build and run this module. + +`--without-mail_pop3_module` + +disables the [POP3](https://nginx.org/en/docs/mail/ngx_mail_pop3_module.html) protocol in mail proxy server. + +`--without-mail_imap_module` + +disables the [IMAP](https://nginx.org/en/docs/mail/ngx_mail_imap_module.html) protocol in mail proxy server. + +`--without-mail_smtp_module` + +disables the [SMTP](https://nginx.org/en/docs/mail/ngx_mail_smtp_module.html) protocol in mail proxy server. + +`--with-stream` +`--with-stream=dynamic` + +enables building the [stream module](https://nginx.org/en/docs/stream/ngx_stream_core_module.html) for generic TCP/UDP proxying and load balancing. This module is not built by default. + +`--with-stream_ssl_module` + +enables building a module that adds the [SSL/TLS protocol support](https://nginx.org/en/docs/stream/ngx_stream_ssl_module.html) to the stream module. This module is not built by default. The OpenSSL library is required to build and run this module. + +`--with-stream_realip_module` + +enables building the [ngx_stream_realip_module](https://nginx.org/en/docs/stream/ngx_stream_realip_module.html) module that changes the client address to the address sent in the PROXY protocol header. This module is not built by default. + +`--with-stream_geoip_module` +`--with-stream_geoip_module=dynamic` + +enables building the [ngx_stream_geoip_module](https://nginx.org/en/docs/stream/ngx_stream_geoip_module.html) module that creates variables depending on the client IP address and the precompiled [MaxMind](http://www.maxmind.com/) databases. This module is not built by default. + +`--with-stream_ssl_preread_module` + +enables building the [ngx_stream_ssl_preread_module](https://nginx.org/en/docs/stream/ngx_stream_ssl_preread_module.html) module that allows extracting information from the [ClientHello](https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.1.2) message without terminating SSL/TLS. This module is not built by default. + +`--without-stream_limit_conn_module` + +disables building the [ngx_stream_limit_conn_module](https://nginx.org/en/docs/stream/ngx_stream_limit_conn_module.html) module that limits the number of connections per key, for example, the number of connections from a single IP address. + +`--without-stream_access_module` + +disables building the [ngx_stream_access_module](https://nginx.org/en/docs/stream/ngx_stream_access_module.html) module that allows limiting access to certain client addresses. + +`--without-stream_geo_module` + +disables building the [ngx_stream_geo_module](https://nginx.org/en/docs/stream/ngx_stream_geo_module.html) module that creates variables with values depending on the client IP address. + +`--without-stream_map_module` + +disables building the [ngx_stream_map_module](https://nginx.org/en/docs/stream/ngx_stream_map_module.html) module that creates variables with values depending on values of other variables. + +`--without-stream_split_clients_module` + +disables building the [ngx_stream_split_clients_module](https://nginx.org/en/docs/stream/ngx_stream_split_clients_module.html) module that creates variables for A/B testing. + +`--without-stream_return_module` + +disables building the [ngx_stream_return_module](https://nginx.org/en/docs/stream/ngx_stream_return_module.html) module that sends some specified value to the client and then closes the connection. + +`--without-stream_set_module` + +disables building the [ngx_stream_set_module](https://nginx.org/en/docs/stream/ngx_stream_set_module.html) module that sets a value for a variable. + +`--without-stream_upstream_hash_module` + +disables building a module that implements the [hash](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#hash) load balancing method. + +`--without-stream_upstream_least_conn_module` + +disables building a module that implements the [least_conn](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#least_conn) load balancing method. + +`--without-stream_upstream_random_module` + +disables building a module that implements the [random](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#random) load balancing method. + +`--without-stream_upstream_zone_module` + +disables building a module that makes it possible to store run-time state of an upstream group in a shared memory [zone](https://nginx.org/en/docs/stream/ngx_stream_upstream_module.html#zone). + +`--with-google_perftools_module` + +enables building the [ngx_google_perftools_module](https://nginx.org/en/docs/ngx_google_perftools_module.html) module that enables profiling of nginx worker processes using [Google Performance Tools](https://github.com/gperftools/gperftools). The module is intended for nginx developers and is not built by default. + +`--with-cpp_test_module` + +enables building the `ngx_cpp_test_module` module. + +``--add-module=`*path*` `` + +enables an external module. + +``--add-dynamic-module=`*path*` `` + +enables an external dynamic module. + +`--with-compat` + +enables dynamic modules compatibility. + +``--with-cc=`*path*` `` + +sets the name of the C compiler. + +``--with-cpp=`*path*` `` + +sets the name of the C preprocessor. + +``--with-cc-opt=`*parameters*` `` + +sets additional parameters that will be added to the CFLAGS variable. When using the system PCRE library under FreeBSD, `--with-cc-opt="-I /usr/local/include"` should be specified. If the number of files supported by `select()` needs to be increased it can also be specified here such as this: `--with-cc-opt="-D FD_SETSIZE=2048"`. + +``--with-ld-opt=`*parameters*` `` + +sets additional parameters that will be used during linking. When using the system PCRE library under FreeBSD, `--with-ld-opt="-L /usr/local/lib"` should be specified. + +``--with-cpu-opt=`*cpu*` `` + +enables building per specified CPU: `pentium`, `pentiumpro`, `pentium3`, `pentium4`, `athlon`, `opteron`, `sparc32`, `sparc64`, `ppc64`. + +`--without-pcre` + +disables the usage of the PCRE library. + +`--with-pcre` + +forces the usage of the PCRE library. + +``--with-pcre=`*path*` `` + +sets the path to the sources of the PCRE library. The library distribution needs to be downloaded from the [PCRE](http://www.pcre.org/) site and extracted. The rest is done by nginx’s `./configure` and `make`. The library is required for regular expressions support in the [location](https://nginx.org/en/docs/http/ngx_http_core_module.html#location) directive and for the [ngx_http_rewrite_module](https://nginx.org/en/docs/http/ngx_http_rewrite_module.html) module. + +``--with-pcre-opt=`*parameters*` `` + +sets additional build options for PCRE. + +`--with-pcre-jit` + +builds the PCRE library with “just-in-time compilation” support (1.1.12, the [pcre_jit](https://nginx.org/en/docs/ngx_core_module.html#pcre_jit) directive). + +`--without-pcre2` + +disables use of the PCRE2 library instead of the original PCRE library (1.21.5). + +``--with-zlib=`*path*` `` + +sets the path to the sources of the zlib library. The library distribution (version 1.1.3 — 1.2.11) needs to be downloaded from the [zlib](http://zlib.net/) site and extracted. The rest is done by nginx’s `./configure` and `make`. The library is required for the [ngx_http_gzip_module](https://nginx.org/en/docs/http/ngx_http_gzip_module.html) module. + +``--with-zlib-opt=`*parameters*` `` + +sets additional build options for zlib. + +``--with-zlib-asm=`*cpu*` `` + +enables the use of the zlib assembler sources optimized for one of the specified CPUs: `pentium`, `pentiumpro`. + +`--with-libatomic` + +forces the libatomic_ops library usage. + +``--with-libatomic=`*path*` `` + +sets the path to the libatomic_ops library sources. + +``--with-openssl=`*path*` `` + +sets the path to the OpenSSL library sources. + +``--with-openssl-opt=`*parameters*` `` + +sets additional build options for OpenSSL. + +`--with-debug` + +enables the [debugging log](https://nginx.org/en/docs/debugging_log.html). + +Example of parameters usage (all of this needs to be typed in one line): + +> ./configure +> --sbin-path=/usr/local/nginx/nginx +> --conf-path=/usr/local/nginx/nginx.conf +> --pid-path=/usr/local/nginx/nginx.pid +> --with-http_ssl_module +> --with-pcre=../pcre2-10.39 +> --with-zlib=../zlib-1.2.11 + +After configuration, nginx is compiled and installed using `make`. diff --git a/source/nginx-docs/control.md b/source/nginx-docs/control.md new file mode 100644 index 0000000..4a84087 --- /dev/null +++ b/source/nginx-docs/control.md @@ -0,0 +1,144 @@ +title: 控制nginx +cover: https://res.ciduid.top/blog/covers/cover(8).jpg +date: 2022-08-06 16:52:03 +--- + +## Controlling nginx + +[修改配置 Changing Configuration](https://nginx.org/en/docs/control.html#reconfiguration) + +[日志切割 Rotating Log-files](https://nginx.org/en/docs/control.html#logs) + +[热更新 Upgrading Executable on the Fly](https://nginx.org/en/docs/control.html#upgrade) + +nginx can be controlled with signals. The process ID of the master process is written to the file `/usr/local/nginx/logs/nginx.pid` by default. This name may be changed at configuration time, or in `nginx.conf` using the [pid](https://nginx.org/en/docs/ngx_core_module.html#pid) directive. The master process supports the following signals: + +nginx可以用信号来控制,nginx主进程ID默认写在`/usr/local/nginx/logs/nginx.pid`文件中。这个文件的位置可以在编译配置的时候指定,或者在`nginx.conf`中使用[pid](https://nginx.org/en/docs/ngx_core_module.html#pid)指令指定。 + +主进程支持以下信号的控制 + +> | | | +> | --- | --- | +> | TERM, INT | fast shutdown | +> | QUIT | graceful shutdown | +> | HUP | changing configuration, keeping up with a changed time zone (only for FreeBSD and Linux), starting new worker processes with a new configuration, graceful shutdown of old worker processes | +> | USR1 | re-opening log files | +> | USR2 | upgrading an executable file | +> | WINCH | graceful shutdown of worker processes | + +> | | | +> | --- | --- | +> | TERM, INT | 快速关闭 | +> | QUIT | 平稳关闭 | +> | HUP | 用于一般用于配置文件更改,修改时区(仅适用于FreeBSD和Linux)时使用,用新的配置启动新的worker进程,平稳关闭旧的worker进程 | +> | USR1 | 重新打开日志文件 | +> | USR2 | 升级可执行文件 | +> | WINCH | 平稳关闭worker进程 | + +Individual worker processes can be controlled with signals as well, though it is not required. The supported signals are: + +单个worker进程也能用信号来控制,不过这不是必须的 + +支持的信号有 + +> | | | +> | --- | --- | +> | TERM, INT | fast shutdown | +> | QUIT | graceful shutdown | +> | USR1 | re-opening log files | +> | WINCH | abnormal termination for debugging (requires [debug_points](https://nginx.org/en/docs/ngx_core_module.html#debug_points) to be enabled) | + +> | | | +> | --- | --- | +> | TERM, INT | 快速关闭 | +> | QUIT | 平稳关闭 | +> | USR1 | 重新打开日志文件 | +> | WINCH | 用于调试的非正常终止 (需要启用[debug_points](https://nginx.org/en/docs/ngx_core_module.html#debug_points)) | + +#### Changing Configuration + +In order for nginx to re-read the configuration file, a HUP signal should be sent to the master process. The master process first checks the syntax validity, then tries to apply new configuration, that is, to open log files and new listen sockets. If this fails, it rolls back changes and continues to work with old configuration. If this succeeds, it starts new worker processes, and sends messages to old worker processes requesting them to shut down gracefully. Old worker processes close listen sockets and continue to service old clients. After all clients are serviced, old worker processes are shut down. + +为了让nginx重新读取配置文件,应该向主进程发送一个HUP信号。主进程首先检查语法的有效性,然后尝试应用新的配置,也就是打开日志文件和新的监听套接字。如果失败了,它就回滚变化,继续用旧的配置工作。如果成功了,它会启动新的工作进程,并向旧的工作进程发送消息,要求它们优雅地关闭。旧的工作进程关闭监听套接字,继续为旧的客户提供服务。在所有客户都得到服务后,旧的工作进程被关闭。 + +Let’s illustrate this by example. Imagine that nginx is run on FreeBSD and the command + +> ps axw -o pid,ppid,user,%cpu,vsz,wchan,command | egrep '(nginx|PID)' + +produces the following output: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 33126 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx +> 33127 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) +> 33128 33126 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 33129 33126 nobody 0.0 1364 kqread nginx: worker process (nginx) + +If HUP is sent to the master process, the output becomes: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx +> 33129 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) +> 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) +> 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) +> 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) + +One of the old worker processes with PID 33129 still continues to work. After some time it exits: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx +> 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) +> 33135 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) +> 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) + +#### Rotating Log-files + +In order to rotate log files, they need to be renamed first. After that USR1 signal should be sent to the master process. The master process will then re-open all currently open log files and assign them an unprivileged user under which the worker processes are running, as an owner. After successful re-opening, the master process closes all open files and sends the message to worker process to ask them to re-open files. Worker processes also open new files and close old files right away. As a result, old files are almost immediately available for post processing, such as compression. + +#### Upgrading Executable on the Fly + +In order to upgrade the server executable, the new executable file should be put in place of an old file first. After that USR2 signal should be sent to the master process. The master process first renames its file with the process ID to a new file with the `.oldbin` suffix, e.g. `/usr/local/nginx/logs/nginx.pid.oldbin`, then starts a new executable file that in turn starts new worker processes: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx +> 33134 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) +> 33135 33126 nobody 0.0 1380 kqread nginx: worker process (nginx) +> 33136 33126 nobody 0.0 1368 kqread nginx: worker process (nginx) +> 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx +> 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) + +After that all worker processes (old and new ones) continue to accept requests. If the WINCH signal is sent to the first master process, it will send messages to its worker processes, requesting them to shut down gracefully, and they will start to exit: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx +> 33135 33126 nobody 0.0 1380 kqread nginx: worker process is shutting down (nginx) +> 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx +> 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) + +After some time, only the new worker processes will process requests: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 33126 1 root 0.0 1164 pause nginx: master process /usr/local/nginx/sbin/nginx +> 36264 33126 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx +> 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) + +It should be noted that the old master process does not close its listen sockets, and it can be managed to start its worker processes again if needed. If for some reason the new executable file works unacceptably, one of the following can be done: + +- Send the HUP signal to the old master process. The old master process will start new worker processes without re-reading the configuration. After that, all new processes can be shut down gracefully, by sending the QUIT signal to the new master process. + +- Send the TERM signal to the new master process. It will then send a message to its worker processes requesting them to exit immediately, and they will all exit almost immediately. (If new processes do not exit for some reason, the KILL signal should be sent to them to force them to exit.) When the new master process exits, the old master process will start new worker processes automatically. + +If the new master process exits then the old master process discards the `.oldbin` suffix from the file name with the process ID. + +If upgrade was successful, then the QUIT signal should be sent to the old master process, and only new processes will stay: + +> PID PPID USER %CPU VSZ WCHAN COMMAND +> 36264 1 root 0.0 1148 pause nginx: master process /usr/local/nginx/sbin/nginx +> 36265 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36266 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) +> 36267 36264 nobody 0.0 1364 kqread nginx: worker process (nginx) diff --git a/source/nginx-docs/index.md b/source/nginx-docs/index.md new file mode 100644 index 0000000..b00eeb8 --- /dev/null +++ b/source/nginx-docs/index.md @@ -0,0 +1,10 @@ +# 目录 + +1. [Beginner's Guide](https://huhu.ciduid.top/nginx-docs/beginners-guide.html) + +2. [Configure](https://huhu.ciduid.top/nginx-docs/configure.html) + +3. [Control](https://huhu.ciduid.top/nginx-docs/control.html) + +4. [Install](https://huhu.ciduid.top/nginx-docs/install.html) + - [Linux Packages](https://huhu.ciduid.top/nginx-docs/linux-packages.html) \ No newline at end of file diff --git a/source/nginx-docs/install.md b/source/nginx-docs/install.md new file mode 100644 index 0000000..af94517 --- /dev/null +++ b/source/nginx-docs/install.md @@ -0,0 +1,23 @@ +# 安装nginx / Installing nginx + +nginx can be installed differently, depending on the operating system. + +根据系统的不一样,有很多种办法来安装nginx + +## 在Linux上安装 / Installation on Linux + +For Linux, nginx [packages](https://nginx.org/en/linux_packages.html) from nginx.org can be used. + +对于linux,您可以使用来自nginx.org的[nginx软件包](https://nginx.org/en/linux_packages.html) + +## 在FreeBSD上安装 / Installation on FreeBSD + +On FreeBSD, nginx can be installed either from the [packages](https://docs.freebsd.org/en/books/handbook/ports/#pkgng-intro) or through the [ports](https://docs.freebsd.org/en/books/handbook/ports/#ports-using) system. The ports system provides greater flexibility, allowing selection among a wide range of options. The port will compile nginx with the specified options and install it. + +在FreeBSD上,nginx可以从[packages](https://docs.freebsd.org/en/books/handbook/ports/#pkgng-intro)或通过[ports](https://docs.freebsd.org/en/books/handbook/ports/#ports-using)系统安装。ports系统提供了更大的灵活性,允许在大量的选项中进行选择。pors能够根据特定的选项来编译nginx并安装。 + +## 从源码安装 / Building from Sources + +If some special functionality is required, not available with packages and ports, nginx can also be compiled from source files. While more flexible, this approach may be complex for a beginner. For more information, see [Building nginx from Sources](https://nginx.org/en/docs/configure.html). + +如果您想要一些特别的功能,而这些功能是软件包和ports都没法提供,可以从源码编译安装nginx。虽然这种方法更加灵活,但对初学者来说可能比较复杂。详情可见[从源码构建nginx](https://nginx.org/en/docs/configure.html)。 \ No newline at end of file diff --git a/source/nginx-docs/linux-packages.md b/source/nginx-docs/linux-packages.md new file mode 100644 index 0000000..8bfcc37 --- /dev/null +++ b/source/nginx-docs/linux-packages.md @@ -0,0 +1,350 @@ +## nginx: Linux packages + +[Supported distributions and versions](https://nginx.org/en/linux_packages.html#distributions) +[Installation instructions](https://nginx.org/en/linux_packages.html#instructions) +     [RHEL/CentOS](https://nginx.org/en/linux_packages.html#RHEL-CentOS) +     [Debian](https://nginx.org/en/linux_packages.html#Debian) +     [Ubuntu](https://nginx.org/en/linux_packages.html#Ubuntu) +     [SLES](https://nginx.org/en/linux_packages.html#SLES) +     [Alpine](https://nginx.org/en/linux_packages.html#Alpine) +     [Amazon Linux](https://nginx.org/en/linux_packages.html#Amazon-Linux) +[Source Packages](https://nginx.org/en/linux_packages.html#sourcepackages) +[Dynamic Modules](https://nginx.org/en/linux_packages.html#dynmodules) +[Signatures](https://nginx.org/en/linux_packages.html#signatures) + +#### Supported distributions and versions + +nginx packages are available for the following Linux distributions and versions: + +[RHEL/CentOS](https://nginx.org/en/linux_packages.html#RHEL-CentOS) + +> | Version | Supported Platforms | +> | ------- | ---------------------------- | +> | 7.4+ | x86_64, aarch64/arm64 | +> | 8.x | x86_64, aarch64/arm64, s390x | +> | 9.x | x86_64, aarch64/arm64, s390x | + +[Debian](https://nginx.org/en/linux_packages.html#Debian) + +> | Version | Supported Platforms | +> | --------------- | --------------------------- | +> | 10.x “buster” | x86_64, i386, aarch64/arm64 | +> | 11.x “bullseye” | x86_64, aarch64/arm64 | + +[Ubuntu](https://nginx.org/en/linux_packages.html#Ubuntu) + +> | Version | Supported Platforms | +> | -------------- | ---------------------------- | +> | 18.04 “bionic” | x86_64, aarch64/arm64 | +> | 20.04 “focal” | x86_64, aarch64/arm64, s390x | +> | 22.04 “jammy” | x86_64, aarch64/arm64, s390x | + +[SLES](https://nginx.org/en/linux_packages.html#SLES) + +> | Version | Supported Platforms | +> | ------- | ------------------- | +> | 12 SP5+ | x86_64 | +> | 15 SP2+ | x86_64 | + +[Alpine](https://nginx.org/en/linux_packages.html#Alpine) + +> | Version | Supported platforms | +> | ------- | --------------------- | +> | 3.13 | x86_64, aarch64/arm64 | +> | 3.14 | x86_64, aarch64/arm64 | +> | 3.15 | x86_64, aarch64/arm64 | +> | 3.16 | x86_64, aarch64/arm64 | + +[Amazon Linux](https://nginx.org/en/linux_packages.html#Amazon-Linux) + +> | Version | Supported platforms | +> | ------- | --------------------- | +> | 2 (LTS) | x86_64, aarch64/arm64 | + +#### Installation instructions + +Before you install nginx for the first time on a new machine, you need to set up the nginx packages repository. Afterward, you can install and update nginx from the repository. + +#### RHEL/CentOS + +Install the prerequisites: + +> sudo yum install yum-utils + +To set up the yum repository, create the file named `/etc/yum.repos.d/nginx.repo` with the following contents: + +> [nginx-stable] +> name=nginx stable repo +> baseurl=http://nginx.org/packages/centos/$releasever/$basearch/ +> gpgcheck=1 +> enabled=1 +> gpgkey=https://nginx.org/keys/nginx_signing.key +> module_hotfixes=true +> [nginx-mainline] +> name=nginx mainline repo +> baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/ +> gpgcheck=1 +> enabled=0 +> gpgkey=https://nginx.org/keys/nginx_signing.key +> module_hotfixes=true + +By default, the repository for stable nginx packages is used. If you would like to use mainline nginx packages, run the following command: + +> sudo yum-config-manager --enable nginx-mainline + +To install nginx, run the following command: + +> sudo yum install nginx + +When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + +#### Debian + +Install the prerequisites: + +> sudo apt install curl gnupg2 ca-certificates lsb-release debian-archive-keyring + +Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key: + +> curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ +> | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null + +Verify that the downloaded file contains the proper key: + +> gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg + +The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: + +> pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] +> 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 +> uid nginx signing key + +If the fingerprint is different, remove the file. + +To set up the apt repository for stable nginx packages, run the following command: + +> echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ +> http://nginx.org/packages/debian `lsb_release -cs` nginx" \ +> | sudo tee /etc/apt/sources.list.d/nginx.list + +If you would like to use mainline nginx packages, run the following command instead: + +> echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ +> http://nginx.org/packages/mainline/debian `lsb_release -cs` nginx" \ +> | sudo tee /etc/apt/sources.list.d/nginx.list + +Set up repository pinning to prefer our packages over distribution-provided ones: + +> echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \ +> | sudo tee /etc/apt/preferences.d/99nginx + +To install nginx, run the following commands: + +> sudo apt update +> sudo apt install nginx + +#### Ubuntu + +Install the prerequisites: + +> sudo apt install curl gnupg2 ca-certificates lsb-release ubuntu-keyring + +Import an official nginx signing key so apt could verify the packages authenticity. Fetch the key: + +> curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor \ +> | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null + +Verify that the downloaded file contains the proper key: + +> gpg --dry-run --quiet --import --import-options import-show /usr/share/keyrings/nginx-archive-keyring.gpg + +The output should contain the full fingerprint `573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62` as follows: + +> pub rsa2048 2011-08-19 [SC] [expires: 2024-06-14] +> 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 +> uid nginx signing key + +If the fingerprint is different, remove the file. + +To set up the apt repository for stable nginx packages, run the following command: + +> echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ +> http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" \ +> | sudo tee /etc/apt/sources.list.d/nginx.list + +If you would like to use mainline nginx packages, run the following command instead: + +> echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] \ +> http://nginx.org/packages/mainline/ubuntu `lsb_release -cs` nginx" \ +> | sudo tee /etc/apt/sources.list.d/nginx.list + +Set up repository pinning to prefer our packages over distribution-provided ones: + +> echo -e "Package: *\nPin: origin nginx.org\nPin: release o=nginx\nPin-Priority: 900\n" \ +> | sudo tee /etc/apt/preferences.d/99nginx + +To install nginx, run the following commands: + +> sudo apt update +> sudo apt install nginx + +#### SLES + +Install the prerequisites: + +> sudo zypper install curl ca-certificates gpg2 + +To set up the zypper repository for stable nginx packages, run the following command: + +> sudo zypper addrepo --gpgcheck --type yum --refresh --check \ +> 'http://nginx.org/packages/sles/$releasever_major' nginx-stable + +If you would like to use mainline nginx packages, run the following command instead: + +> sudo zypper addrepo --gpgcheck --type yum --refresh --check \ +> 'http://nginx.org/packages/mainline/sles/$releasever_major' nginx-mainline + +Next, import an official nginx signing key so zypper/rpm could verify the packages authenticity. Fetch the key: + +> curl -o /tmp/nginx_signing.key https://nginx.org/keys/nginx_signing.key + +Verify that the downloaded file contains the proper key: + +> gpg --with-fingerprint /tmp/nginx_signing.key + +The output should contain the full fingerprint `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62` as follows: + +> pub 2048R/7BD9BF62 2011-08-19 [expires: 2024-06-14] +> Key fingerprint = 573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62 +> uid nginx signing key + +Finally, import the key to the rpm database: + +> sudo rpmkeys --import /tmp/nginx_signing.key + +To install nginx, run the following command: + +> sudo zypper install nginx + +#### Alpine + +Install the prerequisites: + +> sudo apk add openssl curl ca-certificates + +To set up the apk repository for stable nginx packages, run the following command: + +> printf "%s%s%s%s\n" \ +> "@nginx " \ +> "http://nginx.org/packages/alpine/v" \ +> `egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release` \ +> "/main" \ +> | sudo tee -a /etc/apk/repositories + +If you would like to use mainline nginx packages, run the following command instead: + +> printf "%s%s%s%s\n" \ +> "@nginx " \ +> "http://nginx.org/packages/mainline/alpine/v" \ +> `egrep -o '^[0-9]+\.[0-9]+' /etc/alpine-release` \ +> "/main" \ +> | sudo tee -a /etc/apk/repositories + +Next, import an official nginx signing key so apk could verify the packages authenticity. Fetch the key: + +> curl -o /tmp/nginx_signing.rsa.pub https://nginx.org/keys/nginx_signing.rsa.pub + +Verify that downloaded file contains the proper key: + +> openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -text -noout + +The output should contain the following modulus: + +> Public-Key: (2048 bit) +> Modulus: +> 00:fe:14:f6:0a:1a:b8:86:19:fe:cd:ab:02:9f:58: +> 2f:37:70:15:74:d6:06:9b:81:55:90:99:96:cc:70: +> 5c:de:5b:e8:4c:b2:0c:47:5b:a8:a2:98:3d:11:b1: +> f6:7d:a0:46:df:24:23:c6:d0:24:52:67:ba:69:ab: +> 9a:4a:6a:66:2c:db:e1:09:f1:0d:b2:b0:e1:47:1f: +> 0a:46:ac:0d:82:f3:3c:8d:02:ce:08:43:19:d9:64: +> 86:c4:4e:07:12:c0:5b:43:ba:7d:17:8a:a3:f0:3d: +> 98:32:b9:75:66:f4:f0:1b:2d:94:5b:7c:1c:e6:f3: +> 04:7f:dd:25:b2:82:a6:41:04:b7:50:93:94:c4:7c: +> 34:7e:12:7c:bf:33:54:55:47:8c:42:94:40:8e:34: +> 5f:54:04:1d:9e:8c:57:48:d4:b0:f8:e4:03:db:3f: +> 68:6c:37:fa:62:14:1c:94:d6:de:f2:2b:68:29:17: +> 24:6d:f7:b5:b3:18:79:fd:31:5e:7f:4c:be:c0:99: +> 13:cc:e2:97:2b:dc:96:9c:9a:d0:a7:c5:77:82:67: +> c9:cb:a9:e7:68:4a:e1:c5:ba:1c:32:0e:79:40:6e: +> ef:08:d7:a3:b9:5d:1a:df:ce:1a:c7:44:91:4c:d4: +> 99:c8:88:69:b3:66:2e:b3:06:f1:f4:22:d7:f2:5f: +> ab:6d +> Exponent: 65537 (0x10001) + +Finally, move the key to apk trusted keys storage: + +> sudo mv /tmp/nginx_signing.rsa.pub /etc/apk/keys/ + +To install nginx, run the following command: + +> sudo apk add nginx@nginx + +The `@nginx` tag should also be specified when installing packages with [dynamic modules](https://nginx.org/en/linux_packages.html#dynmodules): + +> sudo apk add nginx-module-image-filter@nginx nginx-module-njs@nginx + +#### Amazon Linux + +Install the prerequisites: + +> sudo yum install yum-utils + +To set up the yum repository, create the file named `/etc/yum.repos.d/nginx.repo` with the following contents: + +> [nginx-stable] +> name=nginx stable repo +> baseurl=http://nginx.org/packages/amzn2/$releasever/$basearch/ +> gpgcheck=1 +> enabled=1 +> gpgkey=https://nginx.org/keys/nginx_signing.key +> module_hotfixes=true +> [nginx-mainline] +> name=nginx mainline repo +> baseurl=http://nginx.org/packages/mainline/amzn2/$releasever/$basearch/ +> gpgcheck=1 +> enabled=0 +> gpgkey=https://nginx.org/keys/nginx_signing.key +> module_hotfixes=true + +By default, the repository for stable nginx packages is used. If you would like to use mainline nginx packages, run the following command: + +> sudo yum-config-manager --enable nginx-mainline + +To install nginx, run the following command: + +> sudo yum install nginx + +When prompted to accept the GPG key, verify that the fingerprint matches `573B FD6B 3D8F BC64 1079 A6AB ABF5 BD82 7BD9 BF62`, and if so, accept it. + +#### Source Packages + +Packaging sources can be found in the [packaging sources repository](http://hg.nginx.org/pkg-oss). + +The `default` branch holds packaging sources for the current mainline version, while `stable-*` branches contain latest sources for stable releases. To build binary packages, run `make` in `debian/` directory on Debian/Ubuntu, or in `rpm/SPECS/` on RHEL/CentOS/SLES/Amazon Linux, or in `alpine/` on Alpine. + +Packaging sources are distributed under the same [2-clause BSD-like license](https://nginx.org/LICENSE) used by nginx. + +#### Dynamic Modules + +Main nginx package is built with all modules that do not require additional libraries to avoid extra dependencies. Since version 1.9.11, nginx supports [dynamic modules](https://nginx.org/en/docs/ngx_core_module.html#load_module) and the following modules are built as dynamic and shipped as separate packages: + +> nginx-module-geoip +> nginx-module-image-filter +> nginx-module-njs +> nginx-module-perl +> nginx-module-xslt + +#### Signatures + +Since our [PGP keys](https://nginx.org/en/pgp_keys.html) and packages are located on the same server, they are equally trusted. It is highly advised to additionally verify the authenticity of the downloaded PGP key. PGP has the “Web of Trust” concept, when a key is signed by someone else’s key, that in turn is signed by another key and so on. It often makes possible to build a chain from an arbitrary key to someone’s key who you know and trust personally, thus verify the authenticity of the first key in a chain. This concept is described in details in [GPG Mini Howto](https://www.gnupg.org/howtos/en/GPGMiniHowto-1.html). Our keys have enough signatures, and their authenticity is relatively easy to check. diff --git a/source/notes/cpp_ref.md b/source/notes/cpp_ref.md new file mode 100644 index 0000000..e69de29 diff --git a/source/notes/index.md b/source/notes/index.md new file mode 100644 index 0000000..0345dec --- /dev/null +++ b/source/notes/index.md @@ -0,0 +1,4 @@ +title: 一些笔记 +date: 2022-03-08 12:40:19 +--- +> 这里是一些笔记,因为大部分内容网上已经有很多人写过了,所以我就不单独开文章去写这些东西了。 \ No newline at end of file diff --git a/source/tags/index.md b/source/tags/index.md new file mode 100644 index 0000000..abf1363 --- /dev/null +++ b/source/tags/index.md @@ -0,0 +1,3 @@ +title: tags +date: 2022-02-23 19:52:57 +--- diff --git a/source/teleport-public/index.md b/source/teleport-public/index.md new file mode 100644 index 0000000..ce69314 --- /dev/null +++ b/source/teleport-public/index.md @@ -0,0 +1,9 @@ +title: 传送点 +cover: https://res.ciduid.top/blog/covers/cover(8).jpg +date: 2022-03-08 21:18:03 +--- +这里放了一些链接,只是给自己跳转方便用的... + +- [lensfrex的小破站 | Trailblazer(预览版)](https://preview.ciduid.top) + +- [gitea](https://git.ciduid.top) \ No newline at end of file diff --git a/source/teleport/index.md b/source/teleport/index.md new file mode 100644 index 0000000..2325fa0 --- /dev/null +++ b/source/teleport/index.md @@ -0,0 +1,31 @@ +title: 传送点 +password: zzzz +abstract: 喵喵喵? +message: '[守门人 - Rind]:......' +wrong_pass_message: 喵喵喵? +wrong_hash_message: temp? +date: 2022-03-08 21:18:03 +--- +这里放了一些链接,只是给自己跳转方便用的... + +我知道前端加密用处不大...毕竟加密数据直接复制爆破密码就好了...这里只不过是防君子不防小人罢了... + +不过也没什么好防的,毕竟真要搞什么事情直接端口扫描就知道有这些东西了... + +说到底只是方便罢了 + +所以密码设得很简单 + +- [lensfrex的小破站 | Trailblazer](https://preview.ciduid.top) + +- [Hexo admin](https://preview.ciduid.top/admin/#) + +- [filebrowser](https://view-file.ciduid.top) + +- [v2rayA](https://v2.ciduid.top) + +- [qbittorrent web ui](https://qb.ciduid.top/qb) + +- [内网穿透](https://connect.ciduid.top) + +- [gitea](https://git.ciduid.top) \ No newline at end of file