save code

This commit is contained in:
Ubuntu
2026-02-10 10:09:24 +08:00
parent c93d8b7236
commit cf1cbbd597
10 changed files with 1060 additions and 7 deletions
Binary file not shown.
Binary file not shown.
+288
View File
@@ -0,0 +1,288 @@
nohup: ignoring input
* Serving Flask app 'app'
* Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on all addresses (0.0.0.0)
* Running on http://127.0.0.1:5000
* Running on http://172.21.0.6:5000
Press CTRL+C to quit
* Restarting with stat
* Debugger is active!
* Debugger PIN: 226-374-932
204.76.203.50 - - [05/Feb/2026 21:48:49] "GET http://azenv.net/ HTTP/1.1" 200 -
82.147.84.134 - - [06/Feb/2026 00:31:56] code 400, message Bad request syntax ('\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00')
82.147.84.134 - - [06/Feb/2026 00:31:56] "\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00" HTTPStatus.BAD_REQUEST -
47.236.106.109 - - [06/Feb/2026 00:45:16] code 400, message Bad request syntax ('{\x01\x00\x1613911391139ˬ\x01\x01\x13\x90{')
47.236.106.109 - - [06/Feb/2026 00:45:16] "{\x01\x00\x1613911391139ˬ\x01\x01\x13\x90{" HTTPStatus.BAD_REQUEST -
47.236.106.109 - - [06/Feb/2026 00:45:16] "GET / HTTP/1.1" 200 -
47.236.106.109 - - [06/Feb/2026 00:45:16] "GET /favicon.ico HTTP/1.1" 404 -
204.76.203.50 - - [06/Feb/2026 01:09:14] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.50 - - [06/Feb/2026 01:09:18] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
204.76.203.51 - - [06/Feb/2026 01:24:47] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [06/Feb/2026 01:24:49] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
20.46.235.137 - - [06/Feb/2026 02:32:24] "GET /v2/ HTTP/1.1" 404 -
147.185.132.189 - - [06/Feb/2026 03:46:17] "GET / HTTP/1.1" 200 -
204.76.203.50 - - [06/Feb/2026 04:31:11] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.50 - - [06/Feb/2026 07:52:33] "GET http://azenv.net/ HTTP/1.1" 200 -
172.236.228.86 - - [06/Feb/2026 08:19:06] "GET / HTTP/1.1" 200 -
204.76.203.51 - - [06/Feb/2026 09:28:33] "GET http://azenv.net/ HTTP/1.1" 200 -
178.159.37.112 - - [06/Feb/2026 09:47:37] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
178.159.37.112 - - [06/Feb/2026 09:47:37] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
178.159.37.112 - - [06/Feb/2026 11:11:28] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
178.159.37.112 - - [06/Feb/2026 11:11:28] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
204.76.203.50 - - [06/Feb/2026 11:13:23] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.50 - - [06/Feb/2026 11:13:24] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
147.185.132.75 - - [06/Feb/2026 12:44:06] "GET / HTTP/1.0" 200 -
93.123.109.160 - - [06/Feb/2026 12:58:25] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
93.123.109.160 - - [06/Feb/2026 12:58:25] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
184.105.247.196 - - [06/Feb/2026 13:11:52] "GET / HTTP/1.1" 200 -
184.105.247.196 - - [06/Feb/2026 13:12:31] "GET /favicon.ico HTTP/1.1" 404 -
204.76.203.51 - - [06/Feb/2026 13:29:41] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [06/Feb/2026 13:29:44] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
204.76.203.51 - - [06/Feb/2026 17:27:06] "GET http://azenv.net/ HTTP/1.1" 200 -
193.32.162.101 - - [06/Feb/2026 18:46:39] code 400, message Bad request syntax ('SSH-2.0-Go')
193.32.162.101 - - [06/Feb/2026 18:46:39] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
204.76.203.51 - - [07/Feb/2026 01:23:53] "GET http://azenv.net/ HTTP/1.1" 200 -
45.148.10.88 - - [07/Feb/2026 03:21:27] code 400, message Bad request syntax ('SSH-2.0-Go')
45.148.10.88 - - [07/Feb/2026 03:21:27] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
93.123.109.160 - - [07/Feb/2026 04:09:03] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
93.123.109.160 - - [07/Feb/2026 04:09:03] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
205.210.31.107 - - [07/Feb/2026 05:11:16] "GET / HTTP/1.0" 200 -
204.76.203.51 - - [07/Feb/2026 05:21:05] "GET http://azenv.net/ HTTP/1.1" 200 -
205.210.31.66 - - [07/Feb/2026 06:30:22] "GET / HTTP/1.1" 200 -
45.249.246.82 - - [07/Feb/2026 08:06:21] code 400, message Bad request syntax ('ÿ\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x03\x01NULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
45.249.246.82 - - [07/Feb/2026 08:06:21] "ÿ\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x03\x01NULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" HTTPStatus.BAD_REQUEST -
45.249.246.82 - - [07/Feb/2026 08:06:38] code 400, message Bad request syntax ('ÿ\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x03\x01NULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
45.249.246.82 - - [07/Feb/2026 08:06:38] "ÿ\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x03\x01NULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" HTTPStatus.BAD_REQUEST -
45.249.246.82 - - [07/Feb/2026 08:06:56] code 400, message Bad request syntax ('ÿ\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x03\x01NULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
45.249.246.82 - - [07/Feb/2026 08:06:56] "ÿ\x00\x00\x00\x00\x00\x00\x00\x00\x7f\x03\x01NULL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" HTTPStatus.BAD_REQUEST -
45.249.246.82 - - [07/Feb/2026 08:07:04] "GET / HTTP/1.1" 200 -
45.249.246.82 - - [07/Feb/2026 08:07:05] "GET / HTTP/1.1" 200 -
45.249.246.82 - - [07/Feb/2026 08:07:06] "GET /favicon.ico HTTP/1.1" 404 -
45.249.246.82 - - [07/Feb/2026 08:07:06] "GET /js/api.js HTTP/1.1" 200 -
82.147.84.129 - - [07/Feb/2026 08:50:15] code 400, message Bad request syntax ('\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00')
82.147.84.129 - - [07/Feb/2026 08:50:15] "\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00" HTTPStatus.BAD_REQUEST -
167.94.146.61 - - [07/Feb/2026 08:56:44] code 400, message Bad request version ('À\x14À')
167.94.146.61 - - [07/Feb/2026 08:56:44] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x036,h(fyíè\x96fÄß*\x98+t/\x94\x16Æø¢ä\x94Òà¸òa\x0e\x09N ´Ö"2v¶µ\x16"©übB.î\x91á\x18\x8f\x99\x19üñÏõ, -ÈåÇ_\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
167.94.146.61 - - [07/Feb/2026 08:56:48] "GET / HTTP/1.1" 200 -
167.94.146.61 - - [07/Feb/2026 08:56:52] code 400, message Bad HTTP/0.9 request type ('\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03')
167.94.146.61 - - [07/Feb/2026 08:56:52] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03\x09(ö%|ß" HTTPStatus.BAD_REQUEST -
167.94.146.61 - - [07/Feb/2026 08:56:52] "GET / HTTP/1.1" 200 -
167.94.146.61 - - [07/Feb/2026 08:56:53] code 505, message Invalid HTTP version (2.0)
167.94.146.61 - - [07/Feb/2026 08:56:53] "PRI * HTTP/2.0" HTTPStatus.HTTP_VERSION_NOT_SUPPORTED -
167.94.146.61 - - [07/Feb/2026 08:56:54] "GET /favicon.ico HTTP/1.1" 404 -
167.94.146.61 - - [07/Feb/2026 08:56:59] code 400, message Bad request version ('À\x14À')
167.94.146.61 - - [07/Feb/2026 08:56:59] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03@SJÃ\x04¨þ³.ÁiHж]\x0cèÐ\x93ÓþA8\x1cæÕñ\x0b]\x9d`ÿ \x7f?[§\x01¹O\x8aX§xõfN\x8c£\x89õ&\x0f¶ä\x867c\x05GéDMºú\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
167.94.146.61 - - [07/Feb/2026 08:57:00] "GET /robots.txt HTTP/1.1" 404 -
204.76.203.50 - - [07/Feb/2026 09:03:08] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.50 - - [07/Feb/2026 09:03:10] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
204.76.203.51 - - [07/Feb/2026 09:18:29] "GET http://azenv.net/ HTTP/1.1" 200 -
45.91.64.7 - - [07/Feb/2026 09:25:58] code 400, message Bad request version ("¯nãY»bhlÿ(=':©\x82ÙoÈ¢×\x93\x98´ï\x80å¹\x90\x00(À")
45.91.64.7 - - [07/Feb/2026 09:25:58] "\x16\x03\x02\x01o\x01\x00\x01k\x03\x02RHÅ\x1a#÷:Nßâ´\x82/ÿ\x09T\x9f§Äy°hÆ\x13\x8c¤\x1c="á\x1a\x98 \x84´,\x85¯nãY»bhlÿ(=':©\x82ÙoÈ¢×\x93\x98´ï\x80å¹\x90\x00(À" HTTPStatus.BAD_REQUEST -
45.91.64.6 - - [07/Feb/2026 09:50:32] code 400, message Bad request version ('Ï¿^à\x91\x19^\x135')
45.91.64.6 - - [07/Feb/2026 09:50:32] "\x16\x03\x01\x05¨\x01\x00\x05¤\x03\x03¶b\x7f\x912\x1a[\x85M2³k\x84Rù\x0dò\x97ÑÓÎÊ\x8boä^$\x9c0a"Ì Ï¿^à\x91\x19^\x135" HTTPStatus.BAD_REQUEST -
45.91.64.6 - - [07/Feb/2026 09:50:32] code 400, message Bad request version ('À\x13À')
45.91.64.6 - - [07/Feb/2026 09:50:32] "\x16\x03\x01\x05¨\x01\x00\x05¤\x03\x03\x02"µÉêtk,Ò4]Ë\x04îO´[û8\x805\x95/±*¸\x16\x01\x11ðÌî Éõ»\x1f\x1d\x95Þ\x9fçï\x8fç³ìRt\x8c\x97\x7f RÓ\x8dL»\x07\x86\x0f\x06ãà¯\x00\x1aÀ+À/À,À0̨̩À\x09À\x13À" HTTPStatus.BAD_REQUEST -
45.91.64.6 - - [07/Feb/2026 09:50:33] "GET /v2/_catalog HTTP/1.1" 404 -
45.91.64.6 - - [07/Feb/2026 09:50:33] "GET /v2/_catalog HTTP/1.1" 404 -
193.32.162.25 - - [07/Feb/2026 10:34:13] code 400, message Bad request syntax ('SSH-2.0-Go')
193.32.162.25 - - [07/Feb/2026 10:34:13] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
198.235.24.71 - - [07/Feb/2026 12:04:40] "GET / HTTP/1.1" 200 -
204.76.203.51 - - [07/Feb/2026 13:17:47] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [07/Feb/2026 13:17:50] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
65.49.1.142 - - [07/Feb/2026 15:41:57] "GET / HTTP/1.1" 200 -
65.49.1.150 - - [07/Feb/2026 15:42:12] "GET /favicon.ico HTTP/1.1" 404 -
204.76.203.51 - - [07/Feb/2026 17:13:44] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [07/Feb/2026 17:13:48] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
204.76.203.51 - - [07/Feb/2026 21:09:56] "GET http://azenv.net/ HTTP/1.1" 200 -
77.90.185.18 - - [07/Feb/2026 21:10:13] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
77.90.185.18 - - [07/Feb/2026 21:10:13] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
77.90.185.18 - - [07/Feb/2026 22:54:43] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
77.90.185.18 - - [07/Feb/2026 22:54:43] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
93.123.109.160 - - [08/Feb/2026 00:58:03] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
93.123.109.160 - - [08/Feb/2026 00:58:03] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
204.76.203.51 - - [08/Feb/2026 01:16:22] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [08/Feb/2026 05:15:34] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [08/Feb/2026 05:15:37] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
3.140.198.248 - - [08/Feb/2026 05:40:21] "GET / HTTP/1.1" 200 -
3.140.198.248 - - [08/Feb/2026 05:42:18] "GET / HTTP/1.1" 200 -
3.140.198.248 - - [08/Feb/2026 05:43:41] code 400, message Bad request syntax ('\x16\x03\x01\x00{\x01\x00\x00w\x03\x03\x0f½L>â\x05¤Zõ\x00?@Üå\x1b8')
3.140.198.248 - - [08/Feb/2026 05:43:41] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x03\x0f½L>â\x05¤Zõ\x00?@Üå\x1b8" HTTPStatus.BAD_REQUEST -
3.140.198.248 - - [08/Feb/2026 05:44:45] code 400, message Bad request syntax ('SSH-2.0-Go')
3.140.198.248 - - [08/Feb/2026 05:44:45] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
3.140.198.248 - - [08/Feb/2026 05:46:02] code 400, message Bad request version ('À\x14À')
3.140.198.248 - - [08/Feb/2026 05:46:02] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x03\x86cÛèꬩ/Þ{j\x04½¼v¾\x1c\x126î§;KÞi\x1e@\x14-w\x11{\x00\x00\x1aÀ/À+À\x11À\x07À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
3.135.20.78 - - [08/Feb/2026 05:46:10] "GET / HTTP/1.1" 200 -
3.135.20.78 - - [08/Feb/2026 05:49:33] code 400, message Bad request version ('À\x14À')
3.135.20.78 - - [08/Feb/2026 05:49:33] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x030}\x0eSĺ-e~\x1b\x1eÔX¹ºoñ\x00³Þ\x07ø¶ëz¡=G2\x17¹æ\x00\x00\x1aÀ/À+À\x11À\x07À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
3.135.20.78 - - [08/Feb/2026 05:51:04] code 400, message Bad request syntax ('SSH-2.0-Go')
3.135.20.78 - - [08/Feb/2026 05:51:04] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
3.135.20.78 - - [08/Feb/2026 05:52:41] code 400, message Bad request version ('À\x14À')
3.135.20.78 - - [08/Feb/2026 05:52:41] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x03x\x97\x18dSÎ\x0fOäúÈ\x97=>\x90Âäü\x02,«b\x93yO\x9d»\x85±È`´\x00\x00\x1aÀ/À+À\x11À\x07À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
18.97.5.10 - - [08/Feb/2026 07:16:52] code 400, message Bad request version ("z\x91H²Ëwc[\x7fLÕs\x01Üzá_þïÞ\x7fZk3LçÈ\x00V\x13\x02\x13\x03\x13\x01À,À0À+À/̨̩\x00\x9f\x00\x9e̪À¯À\xadÀ®À¬À$À(À#À'À")
18.97.5.10 - - [08/Feb/2026 07:16:52] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03\x8bI\x0d÷^gÞv\x84×CEW.\x169T¿\x14SãÍyè\x88d)²\x03ÁÂn \x11Fý"\x1ez\x91H²Ëwc[\x7fLÕs\x01Üzá_þïÞ\x7fZk3LçÈ\x00V\x13\x02\x13\x03\x13\x01À,À0À+À/̨̩\x00\x9f\x00\x9e̪À¯À­À®À¬À$À(À#À'À" HTTPStatus.BAD_REQUEST -
18.97.5.10 - - [08/Feb/2026 07:16:52] "GET / HTTP/1.1" 200 -
198.235.24.90 - - [08/Feb/2026 08:01:41] "GET / HTTP/1.0" 200 -
18.97.5.65 - - [08/Feb/2026 08:07:07] code 400, message Bad request syntax ('\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03Ô¹Céjì')
18.97.5.65 - - [08/Feb/2026 08:07:07] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03Ô¹Céjì" HTTPStatus.BAD_REQUEST -
18.97.5.65 - - [08/Feb/2026 08:07:07] "GET / HTTP/1.1" 200 -
65.49.20.69 - - [08/Feb/2026 09:31:52] "GET / HTTP/1.1" 200 -
65.49.20.69 - - [08/Feb/2026 09:32:15] "GET /favicon.ico HTTP/1.1" 404 -
167.94.138.184 - - [08/Feb/2026 10:01:18] code 400, message Bad request version ('À\x14À')
167.94.138.184 - - [08/Feb/2026 10:01:18] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03\x85yåÌ@\x87Ư\x1b«ÒZ\x0c\x98ÜÚ¦ñI\x14Ø\x8a\x09²û?OÜ÷÷\x80ª \x9dAürÕòp\x7f[ÇF©¸s&DU\x1d\x9eþ1\x1ekæ\x98}&@¤õ=­\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
167.94.138.184 - - [08/Feb/2026 10:01:18] "GET / HTTP/1.1" 200 -
167.94.138.184 - - [08/Feb/2026 10:01:19] code 505, message Invalid HTTP version (2.0)
167.94.138.184 - - [08/Feb/2026 10:01:19] "PRI * HTTP/2.0" HTTPStatus.HTTP_VERSION_NOT_SUPPORTED -
167.94.138.184 - - [08/Feb/2026 10:01:21] "GET /favicon.ico HTTP/1.1" 404 -
167.94.138.184 - - [08/Feb/2026 10:01:37] code 400, message Bad request version ('À\x14À')
167.94.138.184 - - [08/Feb/2026 10:01:37] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03ø\x17Ò\x15_\x95ê\x11J7ZD\x10Ï\\x²¢B`\x988õ\x7f\x0e\x13²\x85Æ)µ# ì®Õ\x8b/ÛFéQî\x12DI¤_*dÔÑß½\x0b³e92Ä&\x94køP\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
167.94.138.184 - - [08/Feb/2026 10:01:38] "GET /.well-known/security.txt HTTP/1.1" 404 -
123.58.196.49 - - [08/Feb/2026 10:10:14] code 400, message Bad request version ('\x00\x9ę̪\x003\x00=\x00\x16À')
123.58.196.49 - - [08/Feb/2026 10:10:14] "\x16\x03\x01\x00ü\x01\x00\x00ø\x03\x03#Õ\x01É\x8fµ\x16Ø\x15\x9f\x82.£\x94^\x80»Hô­\x05$ 7ÊÝÂ\x1c\x84\x8f ; ÚÅÂâ\x07^¼uYì]Vït\x85çêl©±\x89ooÕ§ðW\x8anËD\x18\x004̨̩À/À0À+À,À\x09\x00\x9ę̪\x003\x00=\x00\x16À" HTTPStatus.BAD_REQUEST -
123.58.196.49 - - [08/Feb/2026 10:10:25] "GET / HTTP/1.1" 200 -
123.58.196.49 - - [08/Feb/2026 10:10:26] "GET /favicon.ico HTTP/1.1" 404 -
123.58.196.49 - - [08/Feb/2026 10:10:26] "GET /robots.txt HTTP/1.1" 404 -
123.58.196.49 - - [08/Feb/2026 10:10:27] "GET /sitemap.xml HTTP/1.1" 404 -
123.58.196.49 - - [08/Feb/2026 10:10:28] "GET /js/main.js HTTP/1.1" 200 -
123.58.196.49 - - [08/Feb/2026 10:10:28] "GET /js/api.js HTTP/1.1" 200 -
123.58.196.49 - - [08/Feb/2026 10:10:28] "GET /config.json HTTP/1.1" 404 -
178.159.37.112 - - [08/Feb/2026 10:18:36] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
178.159.37.112 - - [08/Feb/2026 10:18:36] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
198.235.24.214 - - [08/Feb/2026 10:36:31] "GET / HTTP/1.1" 200 -
143.198.48.172 - - [08/Feb/2026 10:57:36] "GET / HTTP/1.1" 200 -
143.198.48.172 - - [08/Feb/2026 10:57:37] "GET /favicon.ico HTTP/1.1" 404 -
178.159.37.112 - - [08/Feb/2026 11:03:51] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
178.159.37.112 - - [08/Feb/2026 11:03:51] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
178.159.37.112 - - [08/Feb/2026 11:41:49] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
178.159.37.112 - - [08/Feb/2026 11:41:49] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
198.235.24.86 - - [08/Feb/2026 12:32:36] "GET /.well-known/security.txt HTTP/1.1" 404 -
91.231.89.229 - - [08/Feb/2026 16:09:09] code 400, message Bad request version ("ñ'")
91.231.89.229 - - [08/Feb/2026 16:09:09] "\x16\x03\x03\x01¦\x01\x00\x01¢\x03\x03À3\x93Û£GCæÑìp:\x0dØú¼sÏÙ£3K=³·I|p\x1dÿ{¯ ñ'" HTTPStatus.BAD_REQUEST -
91.231.89.73 - - [08/Feb/2026 16:09:13] "GET / HTTP/1.1" 200 -
91.231.89.73 - - [08/Feb/2026 16:11:09] "GET /favicon.ico HTTP/1.1" 404 -
205.210.31.75 - - [08/Feb/2026 16:49:22] "GET /.well-known/security.txt HTTP/1.1" 404 -
204.76.203.51 - - [08/Feb/2026 16:54:53] "GET http://azenv.net/ HTTP/1.1" 200 -
104.244.79.113 - - [08/Feb/2026 18:18:33] code 400, message Bad request version ('À\x13À')
104.244.79.113 - - [08/Feb/2026 18:18:33] "\x16\x03\x01\x05¨\x01\x00\x05¤\x03\x03\x00\x8a/\\Ä\x0fãC»I[\x9f\x11¦Ü\x80\x96\x80±\x94\x97Ï\x9fô\x15ú\x81'\x10mô\\ E\x94ºÏ\x05\x0cp\x06(\x1bËV\x13x\x0d\x8a\x94´Æ%ÊhdÓÁ:RÐõMtû\x00\x1aÀ+À/À,À0̨̩À\x09À\x13À" HTTPStatus.BAD_REQUEST -
135.119.97.71 - - [08/Feb/2026 19:31:16] "GET /v2/ HTTP/1.1" 404 -
199.45.155.70 - - [08/Feb/2026 20:43:27] "GET / HTTP/1.1" 200 -
199.45.155.70 - - [08/Feb/2026 20:43:35] code 400, message Bad request version ('À\x14À')
199.45.155.70 - - [08/Feb/2026 20:43:35] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03W¯{X\x8e¨_ø96\x18bø¹è\x0cý¼åpSV\\\x19)/ãaP¼\x11\x0c ¾/g©8ã¶F\x0f\x83u°6Àc\x816Cë\x08AËLï\\\x1fØ~Ò\x12ÀQ\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
199.45.155.70 - - [08/Feb/2026 20:43:37] "GET / HTTP/1.1" 200 -
199.45.155.70 - - [08/Feb/2026 20:43:39] code 505, message Invalid HTTP version (2.0)
199.45.155.70 - - [08/Feb/2026 20:43:39] "PRI * HTTP/2.0" HTTPStatus.HTTP_VERSION_NOT_SUPPORTED -
199.45.155.70 - - [08/Feb/2026 20:43:42] "GET /favicon.ico HTTP/1.1" 404 -
199.45.155.70 - - [08/Feb/2026 20:44:04] code 400, message Bad HTTP/0.9 request type ('\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03\x9c\x13fÍÀ')
199.45.155.70 - - [08/Feb/2026 20:44:04] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03\x9c\x13fÍÀ\x0d½\x88=\x1aÝl#µ¡" HTTPStatus.BAD_REQUEST -
199.45.155.70 - - [08/Feb/2026 20:44:08] "GET /sitemap.xml HTTP/1.1" 404 -
204.76.203.51 - - [08/Feb/2026 20:51:12] "GET http://azenv.net/ HTTP/1.1" 200 -
82.147.84.134 - - [08/Feb/2026 23:14:21] code 400, message Bad request syntax ('\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00')
82.147.84.134 - - [08/Feb/2026 23:14:21] "\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00" HTTPStatus.BAD_REQUEST -
204.76.203.51 - - [09/Feb/2026 00:47:03] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 00:47:04] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
93.123.109.160 - - [09/Feb/2026 01:02:18] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
93.123.109.160 - - [09/Feb/2026 01:02:18] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
204.76.203.51 - - [09/Feb/2026 04:45:23] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 04:45:27] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
176.65.149.182 - - [09/Feb/2026 05:34:02] "CONNECT ipv4-internet.yandex.net:443 HTTP/1.1" 405 -
205.210.31.49 - - [09/Feb/2026 06:41:48] "GET / HTTP/1.0" 200 -
164.92.251.121 - - [09/Feb/2026 07:34:32] "GET / HTTP/1.0" 200 -
204.76.203.51 - - [09/Feb/2026 08:42:53] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 08:42:55] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
111.33.154.219 - - [09/Feb/2026 08:48:21] "HEAD / HTTP/1.1" 200 -
205.210.31.241 - - [09/Feb/2026 10:04:58] "GET / HTTP/1.1" 200 -
43.247.4.40 - - [09/Feb/2026 12:02:02] "HEAD / HTTP/1.1" 200 -
180.101.244.14 - - [09/Feb/2026 12:09:55] "GET / HTTP/1.1" 200 -
159.75.198.125 - - [09/Feb/2026 12:09:55] "GET /js/api.js HTTP/1.1" 200 -
180.101.245.252 - - [09/Feb/2026 12:10:59] "GET / HTTP/1.1" 200 -
159.75.198.232 - - [09/Feb/2026 12:11:00] "GET /js/api.js HTTP/1.1" 200 -
220.196.160.61 - - [09/Feb/2026 12:11:00] "GET / HTTP/1.1" 200 -
220.196.160.61 - - [09/Feb/2026 12:11:00] "GET /css/style.css HTTP/1.1" 200 -
220.196.160.61 - - [09/Feb/2026 12:11:00] "GET /js/api.js HTTP/1.1" 200 -
220.196.160.61 - - [09/Feb/2026 12:11:00] "GET /js/main.js HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 12:38:49] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 12:38:52] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
93.123.109.160 - - [09/Feb/2026 14:57:32] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
93.123.109.160 - - [09/Feb/2026 14:57:32] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
206.168.34.117 - - [09/Feb/2026 15:08:19] code 400, message Bad request version ('À\x14À')
206.168.34.117 - - [09/Feb/2026 15:08:19] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03¹ÕHÎç:ßW\x10:Î\x8dênrUN`\x93Ò\x0fÕuËQLM\x0f(Ì\x9cZ ¦3\x9d\x8b-È\x8dÜD\x86xà\x04X ©£Ú'\\ìÄÆÞ\x8abñ\x9eÉ=3Á\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
206.168.34.117 - - [09/Feb/2026 15:08:26] "GET / HTTP/1.1" 200 -
206.168.34.117 - - [09/Feb/2026 15:08:36] code 400, message Bad request version ('À\x14À')
206.168.34.117 - - [09/Feb/2026 15:08:36] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03¹\x8fÐBuÇ\x9fæ\x0f\x17óä\x0fÉ\x16p6\\,Å\x94É|Ãù\x82[\x0c\x80¿\x9dW ¸²¿Úïe¦qÊ* 0\x920\x17\x9202\x07åw^­£§ª<\x10L®CÓ\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
206.168.34.117 - - [09/Feb/2026 15:08:39] "GET / HTTP/1.1" 200 -
206.168.34.117 - - [09/Feb/2026 15:08:41] code 505, message Invalid HTTP version (2.0)
206.168.34.117 - - [09/Feb/2026 15:08:41] "PRI * HTTP/2.0" HTTPStatus.HTTP_VERSION_NOT_SUPPORTED -
206.168.34.117 - - [09/Feb/2026 15:08:55] code 400, message Bad request version ('À\x14À')
206.168.34.117 - - [09/Feb/2026 15:08:55] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03\\\x94ø\x80\x8b|<EØ¡Á\x9d\x1a\x80à\x1fï¹î\x936(¬ä¯ê¶ìåxlv ÔÃÓvʦ\x19\x81ù\x9a>\x84 j\x16¢·MVL\x94°%g\x8ciù®mRó±\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
206.168.34.117 - - [09/Feb/2026 15:08:57] "GET /.well-known/security.txt HTTP/1.1" 404 -
193.32.162.101 - - [09/Feb/2026 15:32:23] code 400, message Bad request syntax ('SSH-2.0-Go')
193.32.162.101 - - [09/Feb/2026 15:32:23] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
193.32.162.25 - - [09/Feb/2026 15:36:19] code 400, message Bad request syntax ('SSH-2.0-Go')
193.32.162.25 - - [09/Feb/2026 15:36:19] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
18.219.245.162 - - [09/Feb/2026 16:26:57] "GET / HTTP/1.1" 200 -
18.219.245.162 - - [09/Feb/2026 16:28:45] "GET / HTTP/1.1" 200 -
18.219.245.162 - - [09/Feb/2026 16:29:19] code 400, message Bad request version ('À\x14À')
18.219.245.162 - - [09/Feb/2026 16:29:19] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x03^\\ßó½w\x02¼\x97Í×\x9aÄ@a\x1e´9ÕÊ¿º\x87ÆëÏ\x1d<Ñ­\x09m\x00\x00\x1aÀ/À+À\x11À\x07À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
18.219.245.162 - - [09/Feb/2026 16:30:27] code 400, message Bad request syntax ('SSH-2.0-Go')
18.219.245.162 - - [09/Feb/2026 16:30:27] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
18.219.245.162 - - [09/Feb/2026 16:31:36] code 400, message Bad request version ('À\x14À')
18.219.245.162 - - [09/Feb/2026 16:31:36] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x03³\x97ïtá\x08\\Ò\x1b\x86Ê\x0d¹wÎ3Ho'Ü@Y\x1a^Ô\x95\x00½\x00\x04ÖÕ\x00\x00\x1aÀ/À+À\x11À\x07À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
204.76.203.51 - - [09/Feb/2026 16:34:40] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 16:34:41] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
111.33.154.219 - - [09/Feb/2026 19:29:07] "HEAD / HTTP/1.1" 200 -
221.238.131.250 - - [09/Feb/2026 20:30:19] "HEAD / HTTP/1.1" 200 -
204.76.203.51 - - [09/Feb/2026 21:45:17] "GET http://azenv.net/ HTTP/1.1" 200 -
82.147.84.53 - - [09/Feb/2026 21:52:52] code 400, message Bad request syntax ('\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00')
82.147.84.53 - - [09/Feb/2026 21:52:52] "\x03\x00\x00\x13\x0eà\x00\x00\x00\x00\x00\x01\x00\x08\x00\x02\x00\x00\x00" HTTPStatus.BAD_REQUEST -
163.172.113.209 - - [09/Feb/2026 22:19:27] "GET / HTTP/1.1" 200 -
163.172.113.209 - - [09/Feb/2026 22:19:28] "GET /favicon.ico HTTP/1.1" 404 -
163.172.113.209 - - [09/Feb/2026 22:19:29] "GET /HNAP1 HTTP/1.1" 404 -
163.172.113.209 - - [09/Feb/2026 22:19:29] "POST /onvif/device_service HTTP/1.1" 405 -
163.172.113.209 - - [09/Feb/2026 22:19:30] "GET /PSIA/index HTTP/1.1" 404 -
204.76.203.51 - - [09/Feb/2026 22:57:41] "GET http://azenv.net/ HTTP/1.1" 200 -
93.123.109.160 - - [10/Feb/2026 02:36:38] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
93.123.109.160 - - [10/Feb/2026 02:36:38] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
204.76.203.51 - - [10/Feb/2026 02:54:48] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [10/Feb/2026 02:54:51] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
147.185.132.103 - - [10/Feb/2026 04:05:12] "GET / HTTP/1.1" 200 -
204.76.203.51 - - [10/Feb/2026 06:51:58] "GET http://azenv.net/ HTTP/1.1" 200 -
204.76.203.51 - - [10/Feb/2026 06:52:00] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
111.7.96.146 - - [10/Feb/2026 07:08:11] code 400, message Bad request version ('RTSP/1.0')
111.7.96.146 - - [10/Feb/2026 07:08:11] "OPTIONS / RTSP/1.0" HTTPStatus.BAD_REQUEST -
111.7.96.146 - - [10/Feb/2026 07:08:34] code 400, message Bad request version ('À\x13À')
111.7.96.146 - - [10/Feb/2026 07:08:34] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03I\x06²ù¼\x99iÀYûøºe-\x83Ud]\x0e\x8d·b8´gÆÝ9dZ8f gÁ\x81i³öò˰©\x19NÖ½\x95g|püé<Z¡\x90T·é¥8'O;\x00&À+À/À,À0̨̩À\x09À\x13À" HTTPStatus.BAD_REQUEST -
111.7.96.146 - - [10/Feb/2026 07:08:44] "GET / HTTP/1.1" 200 -
123.160.223.72 - - [10/Feb/2026 07:08:52] "GET / HTTP/1.1" 200 -
123.160.223.75 - - [10/Feb/2026 07:08:52] "GET / HTTP/1.1" 200 -
123.160.223.72 - - [10/Feb/2026 07:08:53] "GET / HTTP/1.1" 200 -
123.160.223.72 - - [10/Feb/2026 07:08:54] "GET /js/api.js HTTP/1.1" 200 -
123.160.223.73 - - [10/Feb/2026 07:08:54] "GET /js/main.js HTTP/1.1" 200 -
123.160.223.74 - - [10/Feb/2026 07:08:55] "GET / HTTP/1.1" 200 -
123.160.223.75 - - [10/Feb/2026 07:08:55] "GET /js/main.js HTTP/1.1" 200 -
123.160.223.74 - - [10/Feb/2026 07:08:55] "GET /js/api.js HTTP/1.1" 200 -
123.160.223.72 - - [10/Feb/2026 07:09:00] "GET /favicon.ico HTTP/1.1" 404 -
123.160.223.73 - - [10/Feb/2026 07:09:02] "GET /favicon.ico HTTP/1.1" 404 -
36.41.69.228 - - [10/Feb/2026 07:21:52] "GET / HTTP/1.1" 200 -
36.41.69.228 - - [10/Feb/2026 07:21:52] "GET / HTTP/1.1" 200 -
36.41.69.228 - - [10/Feb/2026 07:21:53] "GET /js/main.js HTTP/1.1" 200 -
36.41.69.228 - - [10/Feb/2026 07:21:53] "GET /js/api.js HTTP/1.1" 200 -
36.41.69.228 - - [10/Feb/2026 07:21:57] "GET /favicon.ico HTTP/1.1" 404 -
220.196.160.101 - - [10/Feb/2026 07:30:12] "GET / HTTP/1.1" 200 -
220.196.160.61 - - [10/Feb/2026 07:30:13] "GET / HTTP/1.1" 200 -
43.144.106.92 - - [10/Feb/2026 07:30:13] "GET /js/api.js HTTP/1.1" 200 -
159.75.198.97 - - [10/Feb/2026 07:30:13] "GET /js/api.js HTTP/1.1" 200 -
129.211.166.123 - - [10/Feb/2026 07:30:14] "GET / HTTP/1.1" 200 -
129.211.166.142 - - [10/Feb/2026 07:30:14] "GET /css/style.css HTTP/1.1" 200 -
129.211.166.142 - - [10/Feb/2026 07:30:14] "GET /js/api.js HTTP/1.1" 200 -
129.211.166.134 - - [10/Feb/2026 07:30:14] "GET /js/main.js HTTP/1.1" 200 -
205.210.31.220 - - [10/Feb/2026 07:52:09] "GET / HTTP/1.0" 200 -
192.155.90.118 - - [10/Feb/2026 08:15:27] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [10/Feb/2026 09:57:02] "GET /api/hairstyles HTTP/1.1" 200 -
127.0.0.1 - - [10/Feb/2026 09:57:10] "GET /api/hairstyles HTTP/1.1" 200 -
127.0.0.1 - - [10/Feb/2026 09:57:18] "GET /api/hairstyles HTTP/1.1" 200 -
127.0.0.1 - - [10/Feb/2026 09:57:27] "GET /api/hairstyles HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:00:20] "GET /api/hairstyles HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:06:52] "GET /api/hairstyles HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /api/hairstyles HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:35] "POST /api/change-hair HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:08:15] "POST /api/change-hair-color HTTP/1.1" 200 -
+132
View File
@@ -0,0 +1,132 @@
[2026-01-18 22:55:21 +0800] [2697807] [INFO] Starting gunicorn 20.1.0
[2026-01-18 22:55:21 +0800] [2697807] [INFO] Listening at: http://0.0.0.0:48080 (2697807)
[2026-01-18 22:55:21 +0800] [2697807] [INFO] Using worker: sync
[2026-01-18 22:55:21 +0800] [2697811] [INFO] Booting worker with pid: 2697811
[2026-01-18 22:55:28 +0800] [2697807] [INFO] Handling signal: hup
[2026-01-18 22:55:28 +0800] [2697807] [INFO] Hang up: Master
[2026-01-18 22:55:28 +0800] [2697807] [WARNING] Worker with pid 2697811 was terminated due to signal 1
[2026-01-18 22:55:28 +0800] [2698116] [INFO] Booting worker with pid: 2698116
[2026-01-19 10:19:06 +0800] [2874124] [INFO] Starting gunicorn 20.1.0
[2026-01-19 10:19:06 +0800] [2874124] [ERROR] Connection in use: ('0.0.0.0', 48080)
[2026-01-19 10:19:06 +0800] [2874124] [ERROR] Retrying in 1 second.
[2026-01-19 10:19:07 +0800] [2874124] [ERROR] Connection in use: ('0.0.0.0', 48080)
[2026-01-19 10:19:07 +0800] [2874124] [ERROR] Retrying in 1 second.
[2026-01-19 10:19:08 +0800] [2874124] [ERROR] Connection in use: ('0.0.0.0', 48080)
[2026-01-19 10:19:08 +0800] [2874124] [ERROR] Retrying in 1 second.
[2026-01-19 10:19:09 +0800] [2874124] [ERROR] Connection in use: ('0.0.0.0', 48080)
[2026-01-19 10:19:09 +0800] [2874124] [ERROR] Retrying in 1 second.
[2026-01-19 10:19:10 +0800] [2874124] [ERROR] Connection in use: ('0.0.0.0', 48080)
[2026-01-19 10:19:10 +0800] [2874124] [ERROR] Retrying in 1 second.
[2026-01-19 10:19:11 +0800] [2874124] [ERROR] Can't connect to ('0.0.0.0', 48080)
[2026-01-22 09:38:01 +0800] [2697807] [CRITICAL] WORKER TIMEOUT (pid:2698116)
[2026-01-22 09:38:01 +0800] [2698116] [INFO] Worker exiting (pid: 2698116)
=== 调用远程头发颜色更换API参数 ===
userId: 18701620166
rgb: [255, 106, 0]
ratio: 0.6
output_format: base64
img 长度: 1970439
img 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/hairColor/v2
响应状态码: 200
响应内容长度: 698357
响应内容: {"msg":"success","result":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGB...
远程API调用成功: success
远程API调用成功,返回处理后的图片
=== 调用远程头发颜色更换API参数 ===
userId: 18701620166
rgb: [254, 203, 62]
ratio: 0.1
output_format: base64
img 长度: 1970439
img 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/hairColor/v2
响应状态码: 200
响应内容长度: 701445
响应内容: {"msg":"success","result":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGB...
远程API调用成功: success
远程API调用成功,返回处理后的图片
=== 调用远程头发颜色更换API参数 ===
userId: 18701620166
rgb: [254, 203, 62]
ratio: 0.3
output_format: base64
img 长度: 1970439
img 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/hairColor/v2
响应状态码: 200
响应内容长度: 698277
响应内容: {"msg":"success","result":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGB...
远程API调用成功: success
远程API调用成功,返回处理后的图片
=== 调用远程头发颜色更换API参数 ===
userId: 18701620166
rgb: [255, 249, 148]
ratio: 0.3
output_format: base64
img 长度: 1970439
img 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/hairColor/v2
响应状态码: 200
响应内容长度: 694837
响应内容: {"msg":"success","result":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGB...
远程API调用成功: success
远程API调用成功,返回处理后的图片
=== 调用远程API参数 ===
hair_id: 1980368205752082434
task_id: task_1768832582
is_hr: false
output_format: base64
user_img_path 长度: 1315019
user_img_path 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/api/swapHair/v1
响应状态码: 200
响应内容长度: 1081818
响应内容: {"data":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwY...
远程API调用成功: success
远程API调用成功,返回处理后的图片
=== 调用远程头发颜色更换API参数 ===
userId: 18701620166
rgb: [255, 134, 72]
ratio: 0.4
output_format: base64
img 长度: 816191
img 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/hairColor/v2
响应状态码: 200
响应内容长度: 520765
响应内容: {"msg":"success","result":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGB...
远程API调用成功: success
远程API调用成功,返回处理后的图片
=== 调用远程头发颜色更换API参数 ===
userId: 18701620166
rgb: [255, 134, 72]
ratio: 0.1
output_format: base64
img 长度: 816191
img 前缀: data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD...
====================
发送请求到: http://xiangsilian.com:18801/hairColor/v2
响应状态码: 200
响应内容长度: 519245
响应内容: {"msg":"success","result":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGB...
远程API调用成功: success
远程API调用成功,返回处理后的图片
[2026-01-22 09:38:01 +0800] [3894695] [INFO] Booting worker with pid: 3894695
[2026-01-22 12:51:41 +0800] [2697807] [CRITICAL] WORKER TIMEOUT (pid:3894695)
[2026-01-22 12:51:41 +0800] [3894695] [INFO] Worker exiting (pid: 3894695)
[2026-01-22 12:51:41 +0800] [3940567] [INFO] Booting worker with pid: 3940567
[2026-02-05 18:07:06 +0800] [2697807] [CRITICAL] WORKER TIMEOUT (pid:3940567)
[2026-02-05 18:07:06 +0800] [3940567] [INFO] Worker exiting (pid: 3940567)
[2026-02-05 18:07:06 +0800] [444969] [INFO] Booting worker with pid: 444969
[2026-02-05 18:22:01 +0800] [444969] [INFO] Worker exiting (pid: 444969)
[2026-02-05 18:22:01 +0800] [461640] [INFO] Booting worker with pid: 461640
[2026-02-05 18:22:10 +0800] [2697807] [INFO] Handling signal: term
[2026-02-05 18:22:10 +0800] [461640] [INFO] Worker exiting (pid: 461640)
[2026-02-05 18:22:10 +0800] [2697807] [INFO] Shutting down: Master
+556
View File
@@ -0,0 +1,556 @@
# 发型更换H5项目 — 完整项目分析文档
> 分析日期:2026-02-10
> 分析范围:项目架构、前端、后端、API、数据、测试、部署及问题汇总
---
## 目录
1. [项目概览](#1-项目概览)
2. [项目结构](#2-项目结构)
3. [技术栈总览](#3-技术栈总览)
4. [后端分析](#4-后端分析)
5. [前端分析](#5-前端分析)
6. [API 接口分析](#6-api-接口分析)
7. [数据流分析](#7-数据流分析)
8. [第三方依赖与外部服务](#8-第三方依赖与外部服务)
9. [测试分析](#9-测试分析)
10. [部署现状](#10-部署现状)
11. [已有文档评估](#11-已有文档评估)
12. [存在的问题与风险](#12-存在的问题与风险)
13. [优化建议](#13-优化建议)
14. [总结](#14-总结)
---
## 1. 项目概览
### 1.1 产品定位
这是一个基于 H5 的 **AI 发型更换与发色更换应用**,用户可以:
- **上传照片** → **选择发型** → 获取 AI 换发型后的效果图
- **上传照片** → **选择颜色和强度** → 获取 AI 换发色后的效果图
核心价值:帮助用户在剪发/染发前,直观预览不同发型和发色效果。
### 1.2 功能模块
| 模块 | 功能 | 状态 |
|------|------|------|
| 图片上传 | 支持上传本地照片 | ✅ 已实现 |
| 发型更换 | 从发型库选择发型,AI 替换 | ✅ 已实现 |
| 发色更换 | 通过颜色选择器选色,AI 替换发色 | ✅ 已实现 |
| 结果预览 | 查看效果图,支持保存下载 | ✅ 已实现 |
| 拍照功能 | 移动端拍照 | ❌ PRD中提及但未实现 |
| 性别分类 | 按男/女分类发型 | ❌ PRD中提及但未实现 |
| 分享功能 | 社交分享 | ❌ PRD中提及但未实现 |
---
## 2. 项目结构
```
hair_change_color/
├── backend/ # 后端 Python/Flask 服务
│ ├── app.py # Flask 主应用(391行)- 路由、API、业务逻辑
│ ├── config.py # 配置文件(20行)- API URL、超时、文件限制
│ ├── data/
│ │ └── hairstyles.json # 发型数据(实际未使用,数据从 hairId2url.txt 加载)
│ ├── requirements.txt # Python 依赖(Flask, Flask-CORS, requests
│ ├── app.log # Gunicorn 日志
│ └── nohup.out # 开发服务器日志
├── frontend/ # 前端 H5 页面
│ ├── index.html # 主页面(142行)- 单页应用
│ ├── css/
│ │ └── style.css # 样式文件(393行)- 响应式设计
│ ├── js/
│ │ ├── main.js # 主逻辑(452行)- 状态管理、交互、API调用
│ │ └── api.js # API封装(32行)- 实际未被引用
│ └── frontend.log # 前端日志
├── docs/ # 项目文档
│ ├── PRD.md # 产品需求文档
│ ├── ARCHITECTURE.md # 系统架构文档
│ ├── API.md # API接口文档
│ └── DEPLOYMENT.md # 部署文档
├── test/ # 测试目录
│ ├── test_hair.py # 发型更换API压测脚本
│ └── wertwert.jpg # 测试用图片
└── hairId2url.txt # 发型ID到OSS URL的映射文件(60条记录)
```
---
## 3. 技术栈总览
### 3.1 前端
| 技术 | 用途 |
|------|------|
| HTML5 | 页面结构,单页应用 |
| CSS3 | 响应式布局、动画、Flexbox/Grid |
| JavaScript (ES6+) | 交互逻辑、DOM操作 |
| Axios (CDN) | HTTP 请求 |
| FileReader API | 本地图片读取预览 |
### 3.2 后端
| 技术 | 用途 |
|------|------|
| Python 3.8+ | 核心语言 |
| Flask | Web 框架 |
| Flask-CORS | 跨域支持 |
| requests | 远程 API 调用 |
| Gunicorn | 生产部署 WSGI 服务器 |
### 3.3 外部服务
| 服务 | 地址 | 用途 |
|------|------|------|
| 发型替换 API | `http://xiangsilian.com:18801/api/swapHair/v1` | AI 发型替换 |
| 发色替换 API | `http://xiangsilian.com:18801/hairColor/v2` | AI 发色替换 |
| 阿里云 OSS | `xiangsilian.oss-cn-beijing.aliyuncs.com` | 发型图片存储 |
---
## 4. 后端分析
### 4.1 应用入口 (`app.py`)
Flask 应用作为 **API 网关/代理层**,主要职责:
1. 管理发型数据,向前端提供发型列表
2. 接收用户上传的图片,转发给远程 AI API 处理
3. 将处理结果(base64图片)返回前端
4. 开发模式下提供前端静态文件
### 4.2 配置管理 (`config.py`)
```python
APP_NAME = "Hair Change Color"
REMOTE_API_URL = "http://xiangsilian.com:18801/api/swapHair/v1"
REMOTE_HAIR_COLOR_API_URL = "http://xiangsilian.com:18801/hairColor/v2"
API_TIMEOUT = 120 # 超时120秒(远程AI处理耗时较长)
MAX_CONTENT_LENGTH = 16MB # 上传文件限制
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
DEBUG = True
```
### 4.3 数据加载机制
- 启动时从 `../hairId2url.txt` 读取发型 ID 与 OSS URL 的映射
- 解析规则:`文件名.jpg -> OSS URL`,提取文件名作为 ID
- 自动生成发型名称:`发型{ID后4位}`
-**60 个发型** 可供选择
- **注意**`data/hairstyles.json` 文件存在但实际未被使用
### 4.4 核心处理流程
#### 发型更换流程
```
用户上传图片 + 选择发型ID
后端接收 (POST /api/change-hair)
验证文件类型和参数
图片转 base64
调用远程 API (swapHair/v1)
- 参数: hair_id, task_id, user_img_path(base64), is_hr, output_format
解析响应,提取处理后的图片
返回 base64 data URL 给前端
```
#### 发色更换流程
```
用户上传图片 + 选择RGB颜色 + 设置强度(ratio)
后端接收 (POST /api/change-hair-color)
验证文件类型和参数
图片转 base64,解析 RGB 数组
调用远程 API (hairColor/v2)
- 参数: img(base64), userId, rgb, ratio, output_format
解析响应,提取处理后的图片
返回 base64 data URL 给前端
```
### 4.5 错误处理策略
| 类型 | 状态码 | 处理方式 |
|------|--------|----------|
| 缺少图片/参数 | 400 | 返回中文错误消息 |
| 文件类型不合法 | 400 | 返回错误消息 |
| 远程API失败 | 500 | 返回原图作为降级方案 |
| 其他异常 | 500 | 返回通用错误消息 |
---
## 5. 前端分析
### 5.1 页面结构(单页应用)
采用 **手动页面切换** 的单页应用模式(无路由库):
| 页面 | DOM ID | 功能 |
|------|--------|------|
| 首页 | `homePage` | 图片上传 + 功能入口(换发型/换发色) |
| 发型选择页 | `hairstylePage` | 发型网格列表,点击选择 |
| 发色选择页 | `hairColorPage` | 颜色选择器 + 强度滑块 |
| 结果预览页 | `resultPage` | 结果展示 + 重选/保存操作 |
### 5.2 状态管理
使用全局变量管理状态:
```javascript
uploadedImage // 上传的文件对象
selectedHairstyle // 选中的发型ID
hairstylesData // 缓存的发型列表
selectedColor // 选中的颜色(hex
selectedRatio // 颜色强度(0-1
currentFunction // 当前模式:'hairstyle' | 'color'
```
### 5.3 用户交互流程
```
首页
├── 上传图片 → 显示预览
├── 点击"更换发型" → 发型选择页
│ ├── 选择发型 → 高亮反馈
│ └── 确认 → Loading → 结果页
└── 点击"更换头发颜色" → 发色选择页
├── 选择颜色 → 实时预览RGB值
├── 调节强度 → 滑块
└── 确认 → Loading → 结果页
结果页
├── 重新选择发型/颜色
├── 重新上传图片
└── 保存结果(下载图片)
```
### 5.4 UI设计
- **设计风格**:现代简约,蓝色(#4A90E2)为主色调,青色(#50E3C2)为辅色
- **响应式**:三个断点(移动端 < 768px / 平板 768-1024px / PC > 1024px
- **交互效果**:悬停阴影、选中高亮边框、加载动画
- **导航**:顶部固定导航栏 + 返回按钮
### 5.5 关键工具函数
| 函数 | 功能 |
|------|------|
| `hexToRgb()` | 将 hex 颜色值转换为 RGB 对象 |
| `showPage()` | 管理页面可见性切换 |
| `showLoading()` / `hideLoading()` | 全屏加载遮罩控制 |
| `getHairstyles()` | 获取发型列表 |
| `changeHair()` | 调用发型更换 API |
| `changeHairColor()` | 调用发色更换 API |
---
## 6. API 接口分析
### 6.1 接口总览
| 接口 | 方法 | 功能 | 认证 |
|------|------|------|------|
| `/api/hairstyles` | GET | 获取发型列表 | 无 |
| `/api/change-hair` | POST | AI 发型替换 | 无 |
| `/api/change-hair-color` | POST | AI 发色替换 | 无 |
| `/``/<path>` | GET | 静态文件服务 | 无 |
### 6.2 接口详情
#### GET `/api/hairstyles`
**响应示例:**
```json
{
"success": true,
"data": {
"hairstyles": [
{
"id": "1953267161121464322",
"name": "发型4322",
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267161121464322.jpg"
}
]
}
}
```
#### POST `/api/change-hair`
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `image` | File | 是 | 用户照片 |
| `hairstyle_id` | String | 是 | 发型 ID |
**响应:** `{ "success": true, "data": { "result_image": "data:image/jpeg;base64,..." } }`
#### POST `/api/change-hair-color`
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `image` | File | 是 | 用户照片 |
| `rgb` | String | 是 | RGB 数组字符串,如 `"[255, 106, 0]"` |
| `ratio` | String | 是 | 替换强度 0.0-1.0 |
**响应:** `{ "success": true, "data": { "result_image": "data:image/jpeg;base64,..." } }`
### 6.3 API 文档与实现差异
| 项目 | 文档描述 | 实际实现 |
|------|----------|----------|
| `/api/change-hair-color` | 文档中 **未记录** | 已实现 |
| 发型数据源 | `data/hairstyles.json` | 实际从 `hairId2url.txt` 加载 |
| 性别分类 | 文档描述有 `gender` 字段 | 未实现 |
| 响应格式 | 统一 `message` 字段 | 部分接口缺少 `message` 字段 |
---
## 7. 数据流分析
```
┌──────────────┐ HTTP ┌──────────────┐ HTTP ┌──────────────────┐
│ 前端 H5 │ ◄──────────► │ Flask 后端 │ ◄──────────► │ 远程 AI API │
│ (浏览器) │ JSON/Base64 │ (代理层) │ JSON/Base64 │ xiangsilian.com │
└──────────────┘ └──────────────┘ └──────────────────┘
│ │ │
│ 1. 上传图片+参数 │ │
│ ─────────────────────────► │ │
│ │ 2. base64编码+转发 │
│ │ ────────────────────────────► │
│ │ │
│ │ 3. AI处理结果(base64) │
│ │ ◄──────────────────────────── │
│ 4. 返回结果图片 │ │
│ ◄───────────────────────── │ │
│ │ │
│ 发型图片 │ │
│ ◄─────────────────────────────────── 阿里云 OSS ─────────┘
```
**数据传输特点:**
- 图片全程使用 **base64 编码** 传输,不存储在服务器文件系统
- 远程 API 超时设置为 **120秒**AI 处理耗时较长)
- 发型缩略图直接从 **阿里云 OSS** CDN 加载
---
## 8. 第三方依赖与外部服务
### 8.1 Python 依赖
| 包名 | 用途 | 风险评估 |
|------|------|----------|
| Flask | Web 框架 | 低 - 成熟稳定 |
| Flask-CORS | 跨域支持 | 低 |
| requests | HTTP 客户端 | 低 |
### 8.2 前端依赖
| 库 | 来源 | 用途 |
|----|------|------|
| Axios | CDN (jsdelivr) | HTTP 请求 |
### 8.3 外部服务依赖
| 服务 | 可控性 | 风险 |
|------|--------|------|
| AI API (xiangsilian.com:18801) | **不可控** | 高 - 服务不可用则核心功能失效 |
| 阿里云 OSS | 可控 | 中 - 影响发型图片展示 |
---
## 9. 测试分析
### 9.1 现有测试
项目仅有一个测试文件 `test/test_hair.py`,功能为:
- **压力测试脚本**:多线程并发请求发型更换 API
- 将本地图片编码为 base64 发送请求
- 记录 QPS 和总耗时
- 保存 API 返回的结果图片
### 9.2 测试覆盖不足
| 测试类型 | 状态 |
|----------|------|
| 单元测试 | ❌ 无 |
| 接口测试 | ❌ 无(仅有手动压测脚本) |
| 前端测试 | ❌ 无 |
| 端到端测试 | ❌ 无 |
| 发色更换测试 | ❌ 无 |
| 错误场景测试 | ❌ 无 |
---
## 10. 部署现状
### 10.1 当前部署方式
根据日志文件分析:
| 组件 | 部署方式 | 端口 |
|------|----------|------|
| 后端 | Gunicorn (生产) / Flask dev server (开发) | 48080 / 5000 |
| 前端 | 由后端 Flask 提供静态文件 | 同后端 |
### 10.2 存在的问题
- 日志显示 **Gunicorn worker 超时**,表明远程 API 响应慢导致请求阻塞
- 日志中有大量 **非法 HTTP 请求**,可能是扫描/攻击流量
- `DEBUG = True` 在生产环境中仍然开启
- 使用 **HTTP**(非 HTTPS)暴露在公网
---
## 11. 已有文档评估
| 文档 | 文件 | 完整性 | 准确性 | 备注 |
|------|------|--------|--------|------|
| 产品需求文档 | `docs/PRD.md` | ⭐⭐⭐ | ⭐⭐ | 缺少发色更换功能描述,部分功能未实现 |
| 架构文档 | `docs/ARCHITECTURE.md` | ⭐⭐⭐ | ⭐⭐ | 缺少发色更换 API 描述,数据源描述与实际不符 |
| API 文档 | `docs/API.md` | ⭐⭐ | ⭐⭐ | 缺少 `/api/change-hair-color` 接口 |
| 部署文档 | `docs/DEPLOYMENT.md` | ⭐⭐⭐⭐ | ⭐⭐⭐ | 较为完整但缺少实际端口配置 |
**总体评估**:文档在项目初期创建,后续代码演进(新增发色更换功能、数据源更改等)后 **未同步更新**
---
## 12. 存在的问题与风险
### 12.1 代码质量问题
| 严重度 | 问题 | 位置 | 说明 |
|--------|------|------|------|
| 🔴 高 | `api.js` 未被引用 | `frontend/js/api.js` | 使用 ES6 export 但 main.js 未 importAPI 函数在 main.js 中重复定义 |
| 🔴 高 | `userId` 硬编码 | `backend/app.py` | 发色 API 中 userId 硬编码为 `"18701620166"` |
| 🟡 中 | 拼写错误 | `frontend/js/main.js` | `disabled` 拼写为 `disbled` |
| 🟡 中 | `hairstyles.json` 未使用 | `backend/data/` | 存在但不被加载,容易误导 |
| 🟡 中 | 无环境变量支持 | `backend/config.py` | 所有配置硬编码,无法按环境切换 |
| 🟢 低 | 代码重复 | `backend/app.py` | `change_hair``change_hair_color` 有大量重复逻辑 |
### 12.2 安全问题
| 严重度 | 问题 | 说明 |
|--------|------|------|
| 🔴 高 | 无认证机制 | 所有 API 完全公开,无任何访问控制 |
| 🔴 高 | 无限流保护 | 无 Rate Limiting,可被恶意调用 |
| 🔴 高 | DEBUG 模式生产环境开启 | 可能泄露敏感信息 |
| 🔴 高 | HTTP 明文传输 | 未使用 HTTPS |
| 🟡 中 | CORS 全开 | 允许所有来源跨域请求 |
| 🟡 中 | 无请求体大小验证 | 虽配置了 16MB 限制,但缺少前端校验 |
### 12.3 可靠性问题
| 严重度 | 问题 | 说明 |
|--------|------|------|
| 🔴 高 | 远程 API 单点依赖 | 远程 AI API 不可用则核心功能全部失效 |
| 🔴 高 | 同步阻塞处理 | 请求阻塞最长120秒,占用 worker 进程 |
| 🟡 中 | 无重试机制 | 远程 API 调用失败不会重试 |
| 🟡 中 | 错误降级返回原图 | 用户可能不知道处理失败 |
| 🟡 中 | Worker 超时 | Gunicorn 日志显示频繁 worker timeout |
### 12.4 文档与代码不一致
| 问题 | 说明 |
|------|------|
| 发色更换 API 未记录 | 已实现的 `/api/change-hair-color` 未出现在 API 文档中 |
| 数据源不一致 | 文档说使用 `hairstyles.json`,实际使用 `hairId2url.txt` |
| 目录结构过时 | 文档中的目录结构缺少 `test/``hairId2url.txt` 等 |
| PRD 与实现偏差 | 性别分类、拍照功能、分享功能均未实现 |
---
## 13. 优化建议
### 13.1 优先级高(建议立即修复)
1. **关闭生产环境 DEBUG 模式**
- `config.py``DEBUG = True` 改为通过环境变量控制
2. **添加基础安全防护**
- 添加 Rate Limiting(如 `flask-limiter`
- 配置 CORS 白名单,而非允许所有来源
- 启用 HTTPS
3. **修复代码缺陷**
- 修复 `main.js` 中的拼写错误
- 移除或整合未使用的 `api.js`
- 清理未使用的 `hairstyles.json`
4. **同步更新文档**
- API 文档补充 `/api/change-hair-color` 接口
- 更新架构文档中的数据源描述
### 13.2 优先级中(建议近期优化)
5. **引入环境变量配置**
```python
import os
REMOTE_API_URL = os.getenv('REMOTE_API_URL', 'http://...')
DEBUG = os.getenv('FLASK_DEBUG', 'false').lower() == 'true'
```
6. **异步处理优化**
- 使用 `gevent` 或 `asyncio` 替代同步阻塞
- 或使用任务队列(如 Celery)处理长耗时请求
7. **增加错误提示**
- 远程 API 失败时明确告知用户"处理失败",而非默默返回原图
8. **添加基础测试**
- 编写 API 接口单元测试
- 添加参数校验边界测试
### 13.3 优先级低(长期改进)
9. **前端重构**
- 考虑使用 Vue/React 等框架重构
- 引入前端构建工具(Vite 等)
10. **添加缓存层**
- 对相同图片+相同发型的请求结果进行缓存
11. **完善监控**
- 引入结构化日志
- 添加 API 调用指标监控
12. **实现 PRD 中未完成的功能**
- 性别分类筛选
- 移动端拍照
- 社交分享
---
## 14. 总结
### 14.1 项目整体评价
| 维度 | 评分 | 说明 |
|------|------|------|
| 功能完成度 | ⭐⭐⭐ | 核心功能(换发型+换发色)已实现,部分 PRD 功能未实现 |
| 代码质量 | ⭐⭐ | 结构清晰但存在代码重复、未使用文件、拼写错误等问题 |
| 架构设计 | ⭐⭐⭐ | 前后端分离合理,代理模式设计得当 |
| 安全性 | ⭐ | 缺少认证、限流、HTTPS 等基本安全措施 |
| 可维护性 | ⭐⭐ | 文档与代码不同步,缺少测试覆盖 |
| 可扩展性 | ⭐⭐⭐ | 架构简单,扩展方便 |
| 部署运维 | ⭐⭐ | 有基础部署但缺少监控和自动化 |
### 14.2 一句话总结
> 这是一个功能可用的 **AI 发型/发色更换 H5 应用**,采用经典的 Flask 代理 + 原生前端架构,核心业务逻辑依赖远程 AI API。项目已具备基本功能但在 **安全防护、测试覆盖、文档维护** 方面存在明显不足,建议优先解决安全问题和文档同步,再逐步优化架构和代码质量。
+70
View File
@@ -0,0 +1,70 @@
nohup: ignoring input
212.73.148.13 - - [05/Feb/2026 18:50:49] "GET / HTTP/1.1" 200 -
212.73.148.13 - - [05/Feb/2026 18:50:51] code 404, message File not found
212.73.148.13 - - [05/Feb/2026 18:50:51] "GET /favicon.ico HTTP/1.1" 404 -
111.172.7.26 - - [05/Feb/2026 19:02:15] "GET / HTTP/1.1" 200 -
111.172.7.26 - - [05/Feb/2026 19:02:15] "GET /css/style.css HTTP/1.1" 200 -
111.172.7.26 - - [05/Feb/2026 19:02:15] "GET /js/api.js HTTP/1.1" 200 -
111.172.7.26 - - [05/Feb/2026 19:02:16] "GET /js/main.js HTTP/1.1" 200 -
111.172.7.26 - - [05/Feb/2026 19:02:29] code 400, message Bad request version ('\\x00\\x12\\x00\\x10\\x04\\x03\\x08\\x04\\x04\\x01\\x05\\x03\\x08\\x05\\x05\\x01\\x08\\x06\\x06\\x01\\x00-\\x00\\x02\\x01\\x01\\x00')
111.172.7.26 - - [05/Feb/2026 19:02:29] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03F]|K\x1b\x8d\x0bh\x981\x09¢B\x82\x81e\x9b\x06¡\x98ñ¾\x0e\x81ʤ0@o°M© ×d°rÁ½$=ël\x0f\x1afÀÓc¿q£\x13\x0b\x9e|\x7fT;\x7fKàs\x96ö\x00 **\x13\x01\x13\x02\x13\x03À+À/À,À0̨̩À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93::\x00\x00\x00\x1b\x00\x03\x02\x00\x02\x00#\x00\x00\x00\x0b\x00\x02\x01\x00\x00\x10\x00\x0e\x00\x0c\x02h2\x08http/1.1\x003\x00+\x00)\x9a\x9a\x00\x01\x00\x00\x1d\x00 Ô\x80Nr!;Ý\x13Ð\x1a\x1e\x8fZ\x98xÝ\x84Î:\x914\x8bú)k«\x877\x9df&F\x00\x00\x00\x14\x00\x12\x00\x00\x0fxiangsilian.com\x00+\x00\x07\x06êê\x03\x04\x03\x03ÿ\x01\x00\x01\x00\x00\x12\x00\x00Di\x00\x05\x00\x03\x02h2\x00\x17\x00\x00\x00\x0d\x00\x12\x00\x10\x04\x03\x08\x04\x04\x01\x05\x03\x08\x05\x05\x01\x08\x06\x06\x01\x00-\x00\x02\x01\x01\x00" 400 -
111.172.7.26 - - [05/Feb/2026 19:02:30] code 400, message Bad request version ('\\x00\\x02\\x01\\x00\\x00+\\x00\\x07\\x06JJ\\x03\\x04\\x03\\x03\\x00\\x1b\\x00\\x03\\x02\\x00\\x02\\x00\\x12\\x00\\x00\\x00')
111.172.7.26 - - [05/Feb/2026 19:02:30] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03\x10\x86\\-\x92\x1fÄ~¨ó\x1fÆ:¤IÈÐØ\x1f´ðè\x18\x97f¾kbP\x96;± ð_g\x14\x97\x85÷\x9co\x07ó$ 6\x97\x9c]×Ì\x1b\x9dÛ!D9»?³©qeñ\x00 ÚÚ\x13\x01\x13\x02\x13\x03À+À/À,À0̨̩À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93\x8a\x8a\x00\x00\x00-\x00\x02\x01\x01\x003\x00+\x00)jj\x00\x01\x00\x00\x1d\x00 \x8cW^\x06\x18Zîdè\x86æg±2«è+\x00f[NÝÅ®u\x9fïÊ\x18R\x17FDi\x00\x05\x00\x03\x02h2\x00\x10\x00\x0e\x00\x0c\x02h2\x08http/1.1\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x17\x00\x00ÿ\x01\x00\x01\x00\x00\x0b\x00\x02\x01\x00\x00+\x00\x07\x06JJ\x03\x04\x03\x03\x00\x1b\x00\x03\x02\x00\x02\x00\x12\x00\x00\x00" 400 -
111.172.7.26 - - [05/Feb/2026 19:02:33] code 400, message Bad request version ('\\x02h2\\x08http/1.1\\x00')
111.172.7.26 - - [05/Feb/2026 19:02:33] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03@ ¬\x9e\x0b²\x87\x0d\x0b1ÖêBkC`s.ºhûùø²fìø]IÝ|à vtÀ£\x15:éGúº,\x94¦§-Ðp¾\x8f[\x1c-ú\x0b»­4ûÖSÃ=\x00 ºº\x13\x01\x13\x02\x13\x03À+À/À,À0̨̩À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93ÚÚ\x00\x00\x00+\x00\x07\x06êê\x03\x04\x03\x03\x003\x00+\x00)zz\x00\x01\x00\x00\x1d\x00 <0\x90(]¶ä±òü\x0e4_\x83¿Õoü¯\x95ÙYÇ&\x00AÇnä¬\x8e<\x00\x00\x00\x14\x00\x12\x00\x00\x0fxiangsilian.com\x00\x05\x00\x05\x01\x00\x00\x00\x00\x00\x0b\x00\x02\x01\x00\x00#\x00\x00Di\x00\x05\x00\x03\x02h2\x00-\x00\x02\x01\x01\x00\x17\x00\x00\x00\x10\x00\x0e\x00\x0c\x02h2\x08http/1.1\x00" 400 -
111.172.7.26 - - [05/Feb/2026 19:02:34] code 400, message Bad request version ('¦¼\\x9b%\\x00\\x05\\x00\\x05\\x01\\x00\\x00\\x00\\x00ÿ\\x01\\x00\\x01\\x00\\x00\\x00\\x00\\x14\\x00\\x12\\x00\\x00\\x0fxiangsilian.comDi\\x00\\x05\\x00\\x03\\x02h2\\x00\\x12\\x00\\x00\\x00\\x1b\\x00\\x03\\x02\\x00\\x02\\x00')
111.172.7.26 - - [05/Feb/2026 19:02:34] "\x16\x03\x01\x02\x00\x01\x00\x01ü\x03\x03=\x8d&AK1XG\x15£ÏÍ\x12#\x97\x09ÝèG\x09üÔÂ\x96ý\x1cÆ\x82\x19«3Ö PÌĪ\x91Í\x12\x0dÀ§ë:\x8fÓª9\x9fÓâét\x82$â\x9c,qý@Ä3~\x00 ::\x13\x01\x13\x02\x13\x03À+À/À,À0̨̩À\x13À\x14\x00\x9c\x00\x9d\x00/\x005\x01\x00\x01\x93\x9a\x9a\x00\x00\x00\x0b\x00\x02\x01\x00\x00#\x00\x00\x00+\x00\x07\x06ÊÊ\x03\x04\x03\x03\x003\x00+\x00)\x8a\x8a\x00\x01\x00\x00\x1d\x00 üt\x18\x16"¬­ërÐsm&®p\x81*N\x08\x87-þ\x0f\x8cû>ü ¦¼\x9b%\x00\x05\x00\x05\x01\x00\x00\x00\x00ÿ\x01\x00\x01\x00\x00\x00\x00\x14\x00\x12\x00\x00\x0fxiangsilian.comDi\x00\x05\x00\x03\x02h2\x00\x12\x00\x00\x00\x1b\x00\x03\x02\x00\x02\x00" 400 -
85.217.140.7 - - [07/Feb/2026 19:16:34] "GET / HTTP/1.1" 200 -
85.217.140.7 - - [07/Feb/2026 19:16:34] code 404, message File not found
85.217.140.7 - - [07/Feb/2026 19:16:34] "GET /favicon.ico HTTP/1.1" 404 -
91.202.233.23 - - [09/Feb/2026 17:03:25] code 400, message Bad HTTP/0.9 request type ('\\x03\\x00\\x00/*à\\x00\\x00\\x00\\x00\\x00Cookie:')
91.202.233.23 - - [09/Feb/2026 17:03:25] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" 400 -
31.14.32.5 - - [09/Feb/2026 22:09:06] "GET / HTTP/1.1" 200 -
31.14.32.5 - - [09/Feb/2026 22:09:07] code 404, message File not found
31.14.32.5 - - [09/Feb/2026 22:09:07] "GET /favicon.ico HTTP/1.1" 404 -
1.202.76.38 - - [10/Feb/2026 09:35:39] "GET / HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 09:35:39] "GET /css/style.css HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 09:35:39] "GET /js/main.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 09:35:39] "GET /js/api.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 09:35:54] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 09:35:54] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [10/Feb/2026 09:57:02] code 404, message File not found
127.0.0.1 - - [10/Feb/2026 09:57:02] "GET /api/hairstyles HTTP/1.1" 404 -
1.202.76.38 - - [10/Feb/2026 09:57:54] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 09:57:54] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [10/Feb/2026 09:59:53] code 404, message File not found
127.0.0.1 - - [10/Feb/2026 09:59:53] "GET /api/hairstyles HTTP/1.1" 404 -
118.89.233.55 - - [10/Feb/2026 09:59:54] code 404, message File not found
118.89.233.55 - - [10/Feb/2026 09:59:54] "GET /api/hairstyles HTTP/1.1" 404 -
127.0.0.1 - - [10/Feb/2026 10:00:06] "GET / HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:15] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 10:01:15] "GET /favicon.ico HTTP/1.1" 404 -
1.202.76.38 - - [10/Feb/2026 10:01:51] "GET / HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:51] "GET /css/style.css HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:51] "GET /js/api.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:51] "GET /js/main.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:55] "GET / HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:55] "GET /js/api.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:55] "GET /css/style.css HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:01:55] "GET /js/main.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:02:00] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 10:02:00] "GET /favicon.ico HTTP/1.1" 404 -
1.202.76.38 - - [10/Feb/2026 10:02:27] "GET /js/main.js HTTP/1.1" 304 -
1.202.76.38 - - [10/Feb/2026 10:02:40] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 10:02:40] "GET /favicon.ico HTTP/1.1" 404 -
118.89.233.55 - - [10/Feb/2026 10:04:45] "GET /js/axios.min.js HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:04:45] "GET / HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:05:07] "GET /js/main.js HTTP/1.1" 304 -
127.0.0.1 - - [10/Feb/2026 10:06:37] "GET / HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:06:52] "GET / HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:06:52] "HEAD /js/axios.min.js HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:06:52] "GET / HTTP/1.1" 200 -
118.89.233.55 - - [10/Feb/2026 10:06:52] "GET /js/main.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET / HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /js/axios.min.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /js/main.js HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /css/style.css HTTP/1.1" 200 -
1.202.76.38 - - [10/Feb/2026 10:07:15] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /js/axios.min.js.map HTTP/1.1" 404 -
1.202.76.38 - - [10/Feb/2026 10:07:25] code 404, message File not found
1.202.76.38 - - [10/Feb/2026 10:07:25] "GET /favicon.ico HTTP/1.1" 404 -
+2 -3
View File
@@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>发型更换</title>
<link rel="stylesheet" href="css/style.css">
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<script src="js/axios.min.js"></script>
</head>
<body>
<div id="app">
@@ -25,7 +25,7 @@
<div class="upload-placeholder">
<div class="upload-icon">📷</div>
<p>点击上传图片或拍摄照片</p>
<input type="file" id="imageUpload" accept="image/*" capture="camera">
<input type="file" id="imageUpload" accept="image/*">
</div>
</div>
</div>
@@ -136,7 +136,6 @@
</div>
</div>
<script src="js/api.js"></script>
<script src="js/main.js"></script>
</body>
</html>
+1 -1
View File
@@ -1,5 +1,5 @@
// API调用封装
const API_BASE_URL = '/api';
const API_BASE_URL = 'http://localhost:5000/api';
// 获取发型列表
export async function getHairstyles() {
+5
View File
File diff suppressed because one or more lines are too long
+6 -3
View File
@@ -1,7 +1,10 @@
// API基础URL
const API_BASE_URL = 'http://xiangsilian.com:5000/api';
// API调用函数
async function getHairstyles() {
try {
const response = await axios.get('/api/hairstyles');
const response = await axios.get(`${API_BASE_URL}/hairstyles`);
return response.data;
} catch (error) {
console.error('获取发型列表失败:', error);
@@ -15,7 +18,7 @@ async function changeHair(imageFile, hairstyleId) {
formData.append('image', imageFile);
formData.append('hairstyle_id', hairstyleId);
const response = await axios.post('/api/change-hair', formData, {
const response = await axios.post(`${API_BASE_URL}/change-hair`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
@@ -34,7 +37,7 @@ async function changeHairColor(imageFile, rgb, ratio) {
formData.append('rgb', rgb);
formData.append('ratio', ratio);
const response = await axios.post('/api/change-hair-color', formData, {
const response = await axios.post(`${API_BASE_URL}/change-hair-color`, formData, {
headers: {
'Content-Type': 'multipart/form-data'
}