{"id":31426,"date":"2025-04-21T13:46:01","date_gmt":"2025-04-21T05:46:01","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/31426.html"},"modified":"2025-04-21T13:46:01","modified_gmt":"2025-04-21T05:46:01","slug":"%ef%bc%9c%e9%a1%b9%e7%9b%ae%ef%bc%9e-%e9%ab%98%e5%b9%b6%e5%8f%91%e6%9c%8d%e5%8a%a1%e5%99%a8%e7%9a%84http%e5%8d%8f%e8%ae%ae%e6%94%af%e6%8c%81","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/31426.html","title":{"rendered":"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301"},"content":{"rendered":"<p id=\"main-toc\">\u76ee\u5f55<\/p>\n<p id=\"HTTP%E6%A8%A1%E5%9D%97-toc\" style=\"margin-left:40px\">HTTP\u6a21\u5757<\/p>\n<p id=\"%E6%A8%A1%E5%9D%97%E5%88%92%E5%88%86%E4%B8%8E%E4%BB%8B%E7%BB%8D-toc\" style=\"margin-left:80px\">\u6a21\u5757\u5212\u5206\u4e0e\u4ecb\u7ecd<\/p>\n<p id=\"%E6%A8%A1%E5%9D%97%E5%AE%9E%E7%8E%B0-toc\" style=\"margin-left:80px\">\u6a21\u5757\u5b9e\u73b0<\/p>\n<p id=\"Util%E6%A8%A1%E5%9D%97-toc\" style=\"margin-left:120px\">Util\u6a21\u5757<\/p>\n<p id=\"HTTPRequest%E6%A8%A1%E5%9D%97-toc\" style=\"margin-left:120px\">HTTPRequest\u6a21\u5757<\/p>\n<p id=\"HTTPResponse%E6%A8%A1%E5%9D%97-toc\" style=\"margin-left:120px\">HTTPResponse\u6a21\u5757<\/p>\n<p id=\"%E4%B8%8A%E4%B8%8B%E6%96%87-toc\" style=\"margin-left:120px\">HTTPContext\u6a21\u5757<\/p>\n<p id=\"ParseHttpLine-toc\" style=\"margin-left:160px\">ParseHttpLine<\/p>\n<p id=\"RecvHttpLine-toc\" style=\"margin-left:160px\">RecvHttpLine<\/p>\n<p id=\"RecvHttpHead-toc\" style=\"margin-left:160px\">RecvHttpHead<\/p>\n<p id=\"%C2%A0ParseHttpHead-toc\" style=\"margin-left:160px\">\u00a0ParseHttpHead<\/p>\n<p id=\"%C2%A0RecvHttpBody-toc\" style=\"margin-left:160px\">\u00a0RecvHttpBody<\/p>\n<p id=\"%E5%AF%B9%E5%A4%96%E6%8E%A5%E5%8F%A3%C2%A0-toc\" style=\"margin-left:160px\">\u5bf9\u5916\u63a5\u53e3\u00a0<\/p>\n<p id=\"%C2%A0HttpServer%E6%A8%A1%E5%9D%97-toc\" style=\"margin-left:120px\">\u00a0HttpServer\u6a21\u5757<\/p>\n<p id=\"OnConnected-toc\" style=\"margin-left:160px\">OnConnected<\/p>\n<p id=\"OnMessage%C2%A0%C2%A0-toc\" style=\"margin-left:160px\">OnMessage\u00a0\u00a0<\/p>\n<p id=\"Route-toc\" style=\"margin-left:160px\">Route<\/p>\n<p id=\"IsFileHandler-toc\" style=\"margin-left:160px\">IsFileHandler<\/p>\n<p id=\"FileHandler-toc\" style=\"margin-left:160px\">FileHandler<\/p>\n<p id=\"Dispatcher%C2%A0-toc\" style=\"margin-left:160px\">Dispatcher\u00a0<\/p>\n<p id=\"%C2%A0WriteReponse-toc\" style=\"margin-left:160px\">\u00a0WriteReponse<\/p>\n<p id=\"ErrorHandler-toc\" style=\"margin-left:160px\">ErrorHandler<\/p>\n<p id=\"%E5%AF%B9%E5%A4%96%E6%8E%A5%E5%8F%A3-toc\" style=\"margin-left:160px\">\u5bf9\u5916\u63a5\u53e3<\/p>\n<p id=\"%E6%B5%8B%E8%AF%95-toc\" style=\"margin-left:40px\">\u6d4b\u8bd5<\/p>\n<p id=\"%E5%8A%9F%E8%83%BD%E6%B5%8B%E8%AF%95-toc\" style=\"margin-left:80px\">\u529f\u80fd\u6d4b\u8bd5<\/p>\n<p id=\"%E6%B5%8B%E8%AF%954-toc\" style=\"margin-left:120px\">\u6d4b\u8bd54<\/p>\n<p id=\"%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95-toc\" style=\"margin-left:80px\">\u538b\u529b\u6d4b\u8bd5<\/p>\n<hr \/>\n<p><span style=\"color:#7b7f82\">\u5b9e\u73b0\u4e86\u57fa\u4e8e\u4e8b\u4ef6\u9a71\u52a8\u7684epoll\u7684\u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u4e4b\u540e&#xff0c;\u6211\u4eec\u9700\u8981\u4e3a\u7528\u6237\u63d0\u4f9b\u4e00\u4e9b\u534f\u8bae\u652f\u6301&#xff0c;\u65b9\u4fbf\u7528\u6237\u4f7f\u7528\u9ad8\u5e76\u53d1\u670d\u52a1\u5668&#xff0c;\u90a3\u4e48\u6211\u4eec\u76f4\u63a5\u652f\u6301\u5e94\u7528\u5c42\u8fd0\u7528\u6700\u5e7f\u6cdb\u7684\u8d85\u6587\u672c\u4f20\u8f93\u534f\u8baeHTTP<\/span><\/p>\n<h3 id=\"HTTP%E6%A8%A1%E5%9D%97\">HTTP\u6a21\u5757<\/h3>\n<h4 id=\"%E6%A8%A1%E5%9D%97%E5%88%92%E5%88%86%E4%B8%8E%E4%BB%8B%E7%BB%8D\">\u6a21\u5757\u5212\u5206\u4e0e\u4ecb\u7ecd<\/h4>\n<p><span style=\"color:#7b7f82\">HTTP\u534f\u8bae\u7684\u652f\u6301\u6211\u4eec\u5206\u7c7b\u4e3a\u4e94\u4e2a\u6a21\u5757&#xff1a;<\/span><\/p>\n<p><span style=\"color:#7b7f82\">Util\u5de5\u5177\u96c6\u6a21\u5757\u00a0\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a;\u5b9e\u73b0\u4e00\u4e9b\u96f6\u788e\u7684\u9891\u7e41\u8c03\u7528\u7684\u529f\u80fd\u6027\u5de5\u5177\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5411\u6587\u4ef6\u8bfb\u53d6\u5185\u5bb9<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5411\u6587\u4ef6\u5199\u5165\u5185\u5bb9<\/span><\/li>\n<li><span style=\"color:#7b7f82\">URL\u7684\u7f16\u7801\u3001\u89e3\u7801<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u901a\u8fc7HTTP\u72b6\u6001\u7801\u83b7\u53d6\u5bf9\u5e94\u63cf\u8ff0\u4fe1\u606f<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u901a\u8fc7\u6587\u4ef6\u540e\u7f00\u540d\u83b7\u53d6content-type<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5224\u65ad\u6587\u4ef6\u7c7b\u578b<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5224\u65adHTTP\u8bf7\u6c42\u8d44\u6e90\u8def\u5f84\u662f\u5426\u5408\u6cd5<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;\u5728\u534f\u8bae\u652f\u6301\u6a21\u5757\u4e2d&#xff0c;\u4fbf\u4e8e\u4f7f\u7528&#xff0c;\u4e0d\u9700\u8981\u9891\u7e41\u7f16\u5199<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u00a0HTTPRequest\u6a21\u5757\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a;\u8d1f\u8d23HTTP\u8bf7\u6c42\u7684\u62a5\u6587\u53cd\u5e8f\u5217\u540e\u7684\u5b57\u6bb5\u5b58\u50a8\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;HTTP\u8bf7\u6c42\u53cd\u5e8f\u5217\u5316\u89e3\u6790\u540e&#xff0c;\u4fbf\u4e8e\u8bf7\u6c42\u4fe1\u606f\u7684\u83b7\u53d6\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6210\u5458&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u8bf7\u6c42\u65b9\u6cd5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bf7\u6c42\u8d44\u6e90\u8def\u5f84<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u67e5\u8be2\u5b57\u7b26\u4e32<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u534f\u8bae\u7248\u672c<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u67e5\u8be2\u5b57\u7b26\u4e32\u7684\u63d2\u5165\u548c\u83b7\u53d6<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5\u7684\u63d2\u5165\u548c\u83b7\u53d6<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587\u957f\u5ea6\u7684\u83b7\u53d6<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u957f\u77ed\u8fde\u63a5\u7684\u5224\u65ad<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">HTTPResponse\u6a21\u5757\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a; \u8d1f\u8d23HTTP\u54cd\u5e94\u62a5\u6587\u7684\u4fe1\u606f\u5b58\u50a8\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;\u4fbf\u4e8e\u540e\u7eed\u6784\u5efaHTTP\u54cd\u5e94\u62a5\u6587\u65f6&#xff0c;\u83b7\u53d6\u5404\u4e2a\u62a5\u6587\u5b57\u6bb5\u4fe1\u606f\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6210\u5458&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u534f\u8bae\u7248\u672c<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u72b6\u6001\u7801\u63cf\u8ff0\u4fe1\u606f<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5\u7684\u63d2\u5165\u3001\u83b7\u53d6\u4ee5\u53ca\u662f\u5426\u5b58\u5728<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587\u7684\u8bbe\u7f6e<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u957f\u77ed\u8fde\u63a5\u7684\u5224\u65ad<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">HTTPContext\u6a21\u5757\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a;\u8bb0\u5f55HTTP\u8bf7\u6c42\u7684\u63a5\u6536\u548c\u5904\u7406\u8fdb\u5ea6\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;\u670d\u52a1\u7aef\u7684\u4e00\u4e2a\u8fde\u63a5\u8bfb\u4e8b\u4ef6\u5c31\u7eea\u540e&#xff0c;\u4f1a\u8c03\u7528\u8be5\u8fde\u63a5\u7684\u8bfb\u56de\u8c03\u51fd\u6570&#xff0c;\u6b64\u65f6\u8bfb\u4e0a\u6765\u7684\u6570\u636e\u53ef\u80fd\u5e76\u4e0d\u662f\u4e00\u4e2a\u5b8c\u6574\u7684HTTP\u8bf7\u6c42\u62a5\u6587&#xff08;\u56e0\u4e3aTCP\u9762\u5411\u5b57\u8282\u6d41&#xff09;&#xff0c;\u6240\u4ee5\u4e0a\u5c42\u4e1a\u52a1\u5904\u7406&#xff08;\u5bf9HTTP\u8bf7\u6c42\u62a5\u6587\u7684\u89e3\u6790&#xff09;\u5c31\u4f1a\u5931\u8d25&#xff0c;\u9700\u8981\u6536\u5230\u5269\u4f59\u7684HTTP\u8bf7\u6c42\u62a5\u6587\u6570\u636e\u624d\u80fd\u5b8c\u6210HTTP\u8bf7\u6c42\u62a5\u6587\u7684\u53cd\u5e8f\u5217\u5316\u5de5\u4f5c&#xff0c;\u56e0\u6b64\u6bcf\u6b21\u5728\u4e00\u4e2a\u8fde\u63a5\u7684\u8bf7\u6c42\u62a5\u6587\u5904\u7406\u7684\u65f6\u5019&#xff0c;\u9700\u8981\u5c06\u5904\u7406\u8fdb\u5ea6\u8bb0\u5f55&#xff0c;\u4ee5\u4fbf\u4e8e\u4e0b\u6b21\u5904\u7406\u65f6\u7ee7\u7eed\u4ece\u4e0a\u6b21\u7684\u8fdb\u5ea6\u5411\u4e0b\u5904\u7406\u3002\u6211\u4eec\u5728\u670d\u52a1\u5668\u6a21\u5757\u5df2\u7ecf\u5bf9\u4e00\u4e2a\u8fde\u63a5\u7684Connection\u5bf9\u8c61\u6dfb\u52a0\u4e86Any\u7c7b\u578b\u7684context\u6210\u5458&#xff0c;\u8fd9\u4e2acontext\u6210\u5458\u5c31\u662f\u7528\u6765\u63a5\u6536HTTPContext\u5bf9\u8c61\u7684&#xff0c;\u6240\u4ee5\u4e4b\u540e\u6bcf\u6b21\u5904\u7406\u8bf7\u6c42\u62a5\u6587\u65f6\u53ef\u4ee5\u6839\u636eConnection\u5bf9\u8c61\u7684context\u6210\u5458\u6765\u83b7\u53d6\u5f53\u524d\u62a5\u6587\u5904\u7406\u8fdb\u5ea6\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6210\u5458&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u63a5\u6536\u72b6\u6001<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5230\u8bf7\u6c42\u884c<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5230\u8bf7\u6c42\u5934\u90e8<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5230\u8bf7\u6c42\u6b63\u6587<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5b8c\u6bd5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u51fa\u9519<\/span><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"color:#7b7f82\">\u54cd\u5e94\u72b6\u6001\u7801<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5728HTTP\u8bf7\u6c42\u62a5\u6587\u7684\u89e3\u6790\u8fc7\u7a0b\u4e2d\u53ef\u80fd\u4f1a\u51fa\u73b0\u9519\u8bef&#xff0c;\u4f8b\u5982&#xff1a;\u8bbf\u95ee\u8d44\u6e90\u4e0d\u5b58\u5728\u3001\u8d44\u6e90\u8def\u5f84\u4e0d\u5408\u6cd5&#xff0c;\u6211\u4eec\u9700\u8981\u5bf9\u8fd9\u4e9b\u9519\u8bef\u8bbe\u7f6e\u5bf9\u5e94\u7684\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u63a5\u6536\u5e76\u5904\u7406\u6570\u636e<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fd4\u56de\u53cd\u5e8f\u5217\u5316\u89e3\u6790\u5b8c\u6bd5\u7684\u8bf7\u6c42\u4fe1\u606f&#xff08;\u4e00\u4e2aHTTPrequest\u5bf9\u8c61&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fd4\u56de\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fd4\u56de\u5f53\u524d\u5904\u7406\u7684\u72b6\u6001<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">HTTPServer\u6a21\u5757\u3002\u00a0<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a;\u5bf9HTTP\u534f\u8bae\u6a21\u5757\u7684\u6574\u5408<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;\u4f7f\u7528\u6237\u5bf9HTTP\u670d\u52a1\u5668\u7684\u642d\u5efa\u66f4\u52a0\u7684\u65b9\u4fbf\u7b80\u6377\u3002<\/span><\/p>\n<h4 id=\"%E6%A8%A1%E5%9D%97%E5%AE%9E%E7%8E%B0\">\u6a21\u5757\u5b9e\u73b0<\/h4>\n<h5 id=\"Util%E6%A8%A1%E5%9D%97\">Util\u6a21\u5757<\/h5>\n<p><span style=\"color:#7b7f82\">\u4e3a\u4e86\u65b9\u4fbf\u5728\u5176\u4ed6\u6a21\u5757\u4e2d\u4f7f\u7528Util\u7c7b\u4e2d\u7684\u65b9\u6cd5&#xff0c;\u6211\u4eec\u5c06Util\u7c7b\u4e2d\u7684\u65b9\u6cd5\u90fd\u8bbe\u7f6e\u4e3astatic\u9759\u6001\u6210\u5458\u51fd\u6570&#xff0c;\u5e76\u8bbe\u7f6e\u4e3apublic\u8bbf\u95ee\u6743\u9650&#xff0c;\u4ece\u800c\u53ef\u4ee5\u5728\u7c7b\u5916\u4f7f\u7528\u57df\u540d\u8bbf\u95ee\u6210\u5458\u51fd\u6570\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">Split\u5b57\u7b26\u4e32\u5206\u5272<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u5c06\u539f\u5b57\u7b26\u4e32src\u6839\u636esep\u4e3a\u5206\u9694\u7b26&#xff0c;\u5c06\u5206\u5272\u7ed3\u679c\u653e\u5165out\u4e2d&#xff0c;\u4e0d\u4fdd\u7559\u5206\u5272\u540e\u4ea7\u751f\u7684\u7a7a\u5b57\u7b26\u4e32\u3002<\/span><\/p>\n<p>    \/\/ \u5c06\u5b57\u7b26\u4e32Src\u6309\u7167sep\u5b57\u7b26\u8fdb\u884c\u5206\u5272&#xff0c;\u8f93\u51fa\u5230out\u4e2d<br \/>\n    static void Split(const std::string&amp; Src, std::vector&lt;std::string&gt;* Out, const std::string&amp; sep)<br \/>\n    {<br \/>\n        size_t start &#061; 0;<br \/>\n        while (start &lt; Src.size())<br \/>\n        {<br \/>\n            size_t pos &#061; Src.find(sep, start);<br \/>\n            if (pos &#061;&#061; std::string::npos)<br \/>\n            {<br \/>\n                \/\/ &#034;abd,,,cbd,def,&#034; &#8212;&gt;  &#034;abd&#034; &#034;cbd&#034; &#034;def&#034;<br \/>\n                Out-&gt;push_back(Src.substr(start));<br \/>\n                break;<br \/>\n            }<br \/>\n            if (start &#061;&#061; pos)<br \/>\n            {<br \/>\n                start &#043;&#061; sep.size();<br \/>\n                continue;<br \/>\n            }<br \/>\n            Out-&gt;push_back(Src.substr(start, pos &#8211; start));<br \/>\n            start &#061; pos &#043; sep.size();<br \/>\n        }<br \/>\n    } <\/p>\n<p>\u8bfb\u5199\u6587\u4ef6\u00a0<\/p>\n<p>    \/\/ \u6253\u5f00\u5e76\u8bfb\u53d6\u6587\u4ef6<br \/>\n    static bool ReadFile(const std::string&amp; path, std::string* content)<br \/>\n    {<br \/>\n        std::ifstream in(path, std::ios::binary);<br \/>\n        if (!in.is_open())<br \/>\n        {<br \/>\n            ERR_LOG(&#034;OPEN READ %s FILE FAILED&#034;, path.c_str());<br \/>\n            return false;<br \/>\n        }<br \/>\n        \/\/ \u901a\u8fc7\u8bfb\u6307\u9488\u504f\u79fb&#xff0c;\u83b7\u53d6\u6587\u6863\u5927\u5c0f<br \/>\n        in.seekg(0, in.end);<br \/>\n        size_t fsize &#061; in.tellg();<br \/>\n        in.seekg(0, in.beg);<\/p>\n<p>        \/\/ \u76f4\u63a5\u6269\u5bb9\u6307\u5b9a\u5927\u5c0f&#xff0c;\u5e76\u8bfb\u5230content\u4e2d<br \/>\n        content-&gt;resize(fsize);<br \/>\n        in.read(&amp;(*content)[0], fsize);<\/p>\n<p>        if (!in.good())<br \/>\n        {<br \/>\n            ERR_LOG(&#034;read %s file failed&#034;, path.c_str());<br \/>\n            in.close();<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        in.close();<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/ \u5411\u6587\u4ef6\u5199\u5165<br \/>\n    static bool WriteFile(const std::string&amp; path, const std::string&amp; content)<br \/>\n    {<br \/>\n        \/\/ \u8986\u76d6\u5199<br \/>\n        std::ofstream out(path, std::ios::binary | std::ios::trunc);<br \/>\n        if (!out.is_open())<br \/>\n        {<br \/>\n            ERR_LOG(&#034;OPEN WRITE %s FILE FAILED&#034;, path.c_str());<br \/>\n            return false;<br \/>\n        }<\/p>\n<p>        out.write(content.c_str(), content.size());<br \/>\n        if (!out.good())<br \/>\n        {<br \/>\n            ERR_LOG(&#034;write %s file failed&#034;, path.c_str());<br \/>\n            out.close();<br \/>\n            return false;<br \/>\n        }<br \/>\n        out.close();<br \/>\n        return true;<br \/>\n    } <\/p>\n<p>\u00a0URL\u7f16\u7801<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">URL\u7f16\u7801\u683c\u5f0f&#xff1a;\u5c06\u7279\u6b8a\u5b57\u7b26\u7684ASCII\u503c\u8f6c\u4e3a\u4e24\u4e2a16\u8fdb\u5236\u5b57\u7b26&#xff0c;\u524d\u7f00\u4e3a%\u3002\u4f8b\u5982&#034;C&#043;&#043;&#034;&#xff0c;\u8f6c\u4e3a&#034;C%2B%2b&#034;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">RFC3986\u6587\u6863\u89c4\u5b9a .\u00a0 &#8211;\u00a0 _\u00a0 ~\u00a0 \u5b57\u6bcd \u6570\u5b57 \u5747\u5c5e\u4e8e\u7edd\u5bf9\u4e0d\u7f16\u7801\u5b57\u7b26<\/span><\/li>\n<li><span style=\"color:#7b7f82\">W3C\u6807\u51c6\u89c4\u5b9a&#xff0c;\u67e5\u8be2\u5b57\u7b26\u4e32\u4e2d\u7684\u7a7a\u683c\u9700\u8981\u7f16\u7801\u4e3a&#043;&#xff0c;\u89e3\u7801\u5219\u662f\u5c06&#043;\u8f6c\u4e3a\u7a7a\u683c<\/span><\/li>\n<\/ul>\n<p>    static std::string EncodeURL(const std::string&amp; url, bool convert_space_to_plus)<br \/>\n    {<br \/>\n        std::string res;<br \/>\n        for (auto&amp; c : url)<br \/>\n        {<br \/>\n            if (c &#061;&#061; &#039;.&#039; || c &#061;&#061; &#039;_&#039; || c &#061;&#061; &#039;-&#039; || c &#061;&#061; &#039;~&#039; || c &#061;&#061; isalnum(c))<br \/>\n            {<br \/>\n                res &#043;&#061; c;<br \/>\n                continue;<br \/>\n            }<br \/>\n            if (c &#061;&#061; &#039; &#039; &amp;&amp; convert_space_to_plus)<br \/>\n            {<br \/>\n                res &#043;&#061; &#039;&#043;&#039;;<br \/>\n                continue;<br \/>\n            }<br \/>\n            char tmp[4] &#061; {0};<br \/>\n            snprintf(tmp, 4, &#034;%%%02X&#034;, c);<br \/>\n            res &#043;&#061; tmp;<\/p>\n<p>            return res;<br \/>\n        }<br \/>\n    } <\/p>\n<p>\u00a0URL\u89e3\u7801<\/p>\n<p>    static char HEXTOI(char c)<br \/>\n    {<br \/>\n        if (c &gt;&#061; &#039;0&#039; &amp;&amp; c &lt;&#061; &#039;9&#039;)<br \/>\n        {<br \/>\n            return c &#8211; &#039;0&#039;;<br \/>\n        }<br \/>\n        if (c &gt;&#061; &#039;a&#039; &amp;&amp; c &lt;&#061; &#039;z&#039;)<br \/>\n        {<br \/>\n            return c &#8211; &#039;a&#039; &#043; 10;<br \/>\n        }<br \/>\n        if (c &gt;&#061; &#039;A&#039; &amp;&amp; c &lt;&#061; &#039;Z&#039;)<br \/>\n        {<br \/>\n            return c &#8211; &#039;A&#039; &#043; 10;<br \/>\n        }<br \/>\n        return -1;<br \/>\n    }<br \/>\n    \/\/ URL\u89e3\u7801<br \/>\n    static std::string DecodeURL(const std::string&amp; url, bool convert_plus_to_space)<br \/>\n    {<br \/>\n        std::string res;<br \/>\n        for (int i &#061; 0; i &lt; url.size(); &#043;&#043;i)<br \/>\n        {<br \/>\n            if (url[i] &#061;&#061; &#039;&#043;&#039; &amp;&amp; convert_plus_to_space)<br \/>\n            {<br \/>\n                res &#043;&#061; &#039; &#039;;<br \/>\n                continue;<br \/>\n            }<br \/>\n            if (url[i] &#061;&#061; &#039;%&#039; &amp;&amp; i &#043; 2 &lt; url.size())<br \/>\n            {<br \/>\n                char c1 &#061; HEXTOI(url[i &#043; 1]);<br \/>\n                char c2 &#061; HEXTOI(url[i &#043; 2]);<br \/>\n                char c &#061; c1 * 16 &#043; c2;<br \/>\n                res &#043;&#061; c;<br \/>\n                i &#043;&#061; 2;<br \/>\n                continue;<br \/>\n            }<br \/>\n            res &#043;&#061; url[i];<br \/>\n        }<br \/>\n        return res;<br \/>\n    } <\/p>\n<p>\u00a0\u54cd\u5e94\u72b6\u6001\u7801\u7684\u83b7\u53d6<\/p>\n<p><span style=\"color:#7b7f82\">\u5c06maps\u4f7f\u7528static\u4fee\u9970&#xff0c;\u751f\u547d\u5468\u671f\u8f6c\u4e3a\u5168\u5c40&#xff0c;\u5e76\u53ea\u5728\u7b2c\u4e00\u6b21\u88ab\u521d\u59cb\u5316\u00a0<\/span><\/p>\n<p>    \/\/ \u54cd\u5e94\u72b6\u6001\u7801\u5bf9\u5e94\u7684\u89e3\u91ca\u4fe1\u606f<br \/>\n    static std::string StatusDesc(int status)<br \/>\n    {<br \/>\n        \/\/ \u53ea\u521d\u59cb\u5316\u4e00\u6b21<br \/>\n        static std::unordered_map&lt;int, std::string&gt; maps {<br \/>\n            {100,  &#034;Continue&#034;},<br \/>\n            {101,  &#034;Switching Protocol&#034;},<br \/>\n            {102,  &#034;Processing&#034;},<br \/>\n            {103,  &#034;Early Hints&#034;},<br \/>\n            {200,  &#034;OK&#034;},<br \/>\n            {201,  &#034;Created&#034;},<br \/>\n            {202,  &#034;Accepted&#034;},<br \/>\n            {203,  &#034;Non-Authoritative Information&#034;},<br \/>\n            {204,  &#034;No Content&#034;},<br \/>\n            {205,  &#034;Reset Content&#034;},<br \/>\n            {206,  &#034;Partial Content&#034;},<br \/>\n            {207,  &#034;Multi-Status&#034;},<br \/>\n            {208,  &#034;Already Reported&#034;},<br \/>\n            {226,  &#034;IM Used&#034;},<br \/>\n            {300,  &#034;Multiple Choice&#034;},<br \/>\n            {301,  &#034;Moved Permanently&#034;},<br \/>\n            {302,  &#034;Found&#034;},<br \/>\n            {303,  &#034;See Other&#034;},<br \/>\n            {304,  &#034;Not Modified&#034;},<br \/>\n            {305,  &#034;Use Proxy&#034;},<br \/>\n            {306,  &#034;unused&#034;},<br \/>\n            {307,  &#034;Temporary Redirect&#034;},<br \/>\n            {308,  &#034;Permanent Redirect&#034;},<br \/>\n            {400,  &#034;Bad Request&#034;},<br \/>\n            {401,  &#034;Unauthorized&#034;},<br \/>\n            {402,  &#034;Payment Required&#034;},<br \/>\n            {403,  &#034;Forbidden&#034;},<br \/>\n            {404,  &#034;Not Found&#034;},<br \/>\n            {405,  &#034;Method Not Allowed&#034;},<br \/>\n            {406,  &#034;Not Acceptable&#034;},<br \/>\n            {407,  &#034;Proxy Authentication Required&#034;},<br \/>\n            {408,  &#034;Request Timeout&#034;},<br \/>\n            {409,  &#034;Conflict&#034;},<br \/>\n            {410,  &#034;Gone&#034;},<br \/>\n            {411,  &#034;Length Required&#034;},<br \/>\n            {412,  &#034;Precondition Failed&#034;},<br \/>\n            {413,  &#034;Payload Too Large&#034;},<br \/>\n            {414,  &#034;URI Too Long&#034;},<br \/>\n            {415,  &#034;Unsupported Media Type&#034;},<br \/>\n            {416,  &#034;Range Not Satisfiable&#034;},<br \/>\n            {417,  &#034;Expectation Failed&#034;},<br \/>\n            {418,  &#034;I&#039;m a teapot&#034;},<br \/>\n            {421,  &#034;Misdirected Request&#034;},<br \/>\n            {422,  &#034;Unprocessable Entity&#034;},<br \/>\n            {423,  &#034;Locked&#034;},<br \/>\n            {424,  &#034;Failed Dependency&#034;},<br \/>\n            {425,  &#034;Too Early&#034;},<br \/>\n            {426,  &#034;Upgrade Required&#034;},<br \/>\n            {428,  &#034;Precondition Required&#034;},<br \/>\n            {429,  &#034;Too Many Requests&#034;},<br \/>\n            {431,  &#034;Request Header Fields Too Large&#034;},<br \/>\n            {451,  &#034;Unavailable For Legal Reasons&#034;},<br \/>\n            {501,  &#034;Not Implemented&#034;},<br \/>\n            {502,  &#034;Bad Gateway&#034;},<br \/>\n            {503,  &#034;Service Unavailable&#034;},<br \/>\n            {504,  &#034;Gateway Timeout&#034;},<br \/>\n            {505,  &#034;HTTP Version Not Supported&#034;},<br \/>\n            {506,  &#034;Variant Also Negotiates&#034;},<br \/>\n            {507,  &#034;Insufficient Storage&#034;},<br \/>\n            {508,  &#034;Loop Detected&#034;},<br \/>\n            {510,  &#034;Not Extended&#034;},<br \/>\n            {511,  &#034;Network Authentication Required&#034;}<br \/>\n        };<br \/>\n        auto it &#061; maps.find(status);<br \/>\n        if (it &#061;&#061; maps.end())<br \/>\n            return &#034;Unkown&#034;;<br \/>\n        return it-&gt;second;<br \/>\n    }<\/p>\n<p>\u83b7\u53d6\u6587\u4ef6\u7c7b\u578b<\/p>\n<p><span style=\"color:#7b7f82\">\u83b7\u53d6\u6587\u4ef6\u7c7b\u578b&#xff0c;\u5728\u6784\u5efaHTTP\u54cd\u5e94\u65f6\u9700\u8981\u8bbe\u7f6e\u5934\u90e8\u5b57\u6bb5\u8868\u660e\u6b63\u6587\u7c7b\u578b<\/span><\/p>\n<p>\/\/ \u6839\u636e\u6587\u4ef6\u540e\u7f00\u540d\u83b7\u53d6\u6587\u4ef6content_type<br \/>\n    static std::string ContentType(const std::string&amp; filename)<br \/>\n    {<br \/>\n        \/\/ \u53ea\u521d\u59cb\u5316\u4e00\u6b21<br \/>\n        static std::unordered_map&lt;std::string, std::string&gt; maps {<br \/>\n            {&#034;.aac&#034;,        &#034;audio\/aac&#034;},<br \/>\n            {&#034;.abw&#034;,        &#034;application\/x-abiword&#034;},<br \/>\n            {&#034;.arc&#034;,        &#034;application\/x-freearc&#034;},<br \/>\n            {&#034;.avi&#034;,        &#034;video\/x-msvideo&#034;},<br \/>\n            {&#034;.azw&#034;,        &#034;application\/vnd.amazon.ebook&#034;},<br \/>\n            {&#034;.bin&#034;,        &#034;application\/octet-stream&#034;},<br \/>\n            {&#034;.bmp&#034;,        &#034;image\/bmp&#034;},<br \/>\n            {&#034;.bz&#034;,         &#034;application\/x-bzip&#034;},<br \/>\n            {&#034;.bz2&#034;,        &#034;application\/x-bzip2&#034;},<br \/>\n            {&#034;.csh&#034;,        &#034;application\/x-csh&#034;},<br \/>\n            {&#034;.css&#034;,        &#034;text\/css&#034;},<br \/>\n            {&#034;.csv&#034;,        &#034;text\/csv&#034;},<br \/>\n            {&#034;.doc&#034;,        &#034;application\/msword&#034;},<br \/>\n            {&#034;.docx&#034;,       &#034;application\/vnd.openxmlformats-officedocument.wordprocessingml.document&#034;},<br \/>\n            {&#034;.eot&#034;,        &#034;application\/vnd.ms-fontobject&#034;},<br \/>\n            {&#034;.epub&#034;,       &#034;application\/epub&#043;zip&#034;},<br \/>\n            {&#034;.gif&#034;,        &#034;image\/gif&#034;},<br \/>\n            {&#034;.htm&#034;,        &#034;text\/html&#034;},<br \/>\n            {&#034;.html&#034;,       &#034;text\/html&#034;},<br \/>\n            {&#034;.ico&#034;,        &#034;image\/vnd.microsoft.icon&#034;},<br \/>\n            {&#034;.ics&#034;,        &#034;text\/calendar&#034;},<br \/>\n            {&#034;.jar&#034;,        &#034;application\/java-archive&#034;},<br \/>\n            {&#034;.jpeg&#034;,       &#034;image\/jpeg&#034;},<br \/>\n            {&#034;.jpg&#034;,        &#034;image\/jpeg&#034;},<br \/>\n            {&#034;.js&#034;,         &#034;text\/javascript&#034;},<br \/>\n            {&#034;.json&#034;,       &#034;application\/json&#034;},<br \/>\n            {&#034;.jsonld&#034;,     &#034;application\/ld&#043;json&#034;},<br \/>\n            {&#034;.mid&#034;,        &#034;audio\/midi&#034;},<br \/>\n            {&#034;.midi&#034;,       &#034;audio\/x-midi&#034;},<br \/>\n            {&#034;.mjs&#034;,        &#034;text\/javascript&#034;},<br \/>\n            {&#034;.mp3&#034;,        &#034;audio\/mpeg&#034;},<br \/>\n            {&#034;.mpeg&#034;,       &#034;video\/mpeg&#034;},<br \/>\n            {&#034;.mpkg&#034;,       &#034;application\/vnd.apple.installer&#043;xml&#034;},<br \/>\n            {&#034;.odp&#034;,        &#034;application\/vnd.oasis.opendocument.presentation&#034;},<br \/>\n            {&#034;.ods&#034;,        &#034;application\/vnd.oasis.opendocument.spreadsheet&#034;},<br \/>\n            {&#034;.odt&#034;,        &#034;application\/vnd.oasis.opendocument.text&#034;},<br \/>\n            {&#034;.oga&#034;,        &#034;audio\/ogg&#034;},<br \/>\n            {&#034;.ogv&#034;,        &#034;video\/ogg&#034;},<br \/>\n            {&#034;.ogx&#034;,        &#034;application\/ogg&#034;},<br \/>\n            {&#034;.otf&#034;,        &#034;font\/otf&#034;},<br \/>\n            {&#034;.png&#034;,        &#034;image\/png&#034;},<br \/>\n            {&#034;.pdf&#034;,        &#034;application\/pdf&#034;},<br \/>\n            {&#034;.ppt&#034;,        &#034;application\/vnd.ms-powerpoint&#034;},<br \/>\n            {&#034;.pptx&#034;,       &#034;application\/vnd.openxmlformats-officedocument.presentationml.presentation&#034;},<br \/>\n            {&#034;.rar&#034;,        &#034;application\/x-rar-compressed&#034;},<br \/>\n            {&#034;.rtf&#034;,        &#034;application\/rtf&#034;},<br \/>\n            {&#034;.sh&#034;,         &#034;application\/x-sh&#034;},<br \/>\n            {&#034;.svg&#034;,        &#034;image\/svg&#043;xml&#034;},<br \/>\n            {&#034;.swf&#034;,        &#034;application\/x-shockwave-flash&#034;},<br \/>\n            {&#034;.tar&#034;,        &#034;application\/x-tar&#034;},<br \/>\n            {&#034;.tif&#034;,        &#034;image\/tiff&#034;},<br \/>\n            {&#034;.tiff&#034;,       &#034;image\/tiff&#034;},<br \/>\n            {&#034;.ttf&#034;,        &#034;font\/ttf&#034;},<br \/>\n            {&#034;.txt&#034;,        &#034;text\/plain&#034;},<br \/>\n            {&#034;.vsd&#034;,        &#034;application\/vnd.visio&#034;},<br \/>\n            {&#034;.wav&#034;,        &#034;audio\/wav&#034;},<br \/>\n            {&#034;.weba&#034;,       &#034;audio\/webm&#034;},<br \/>\n            {&#034;.webm&#034;,       &#034;video\/webm&#034;},<br \/>\n            {&#034;.webp&#034;,       &#034;image\/webp&#034;},<br \/>\n            {&#034;.woff&#034;,       &#034;font\/woff&#034;},<br \/>\n            {&#034;.woff2&#034;,      &#034;font\/woff2&#034;},<br \/>\n            {&#034;.xhtml&#034;,      &#034;application\/xhtml&#043;xml&#034;},<br \/>\n            {&#034;.xls&#034;,        &#034;application\/vnd.ms-excel&#034;},<br \/>\n            {&#034;.xlsx&#034;,       &#034;application\/vnd.openxmlformats-officedocument.spreadsheetml.sheet&#034;},<br \/>\n            {&#034;.xml&#034;,        &#034;application\/xml&#034;},<br \/>\n            {&#034;.xul&#034;,        &#034;application\/vnd.mozilla.xul&#043;xml&#034;},<br \/>\n            {&#034;.zip&#034;,        &#034;application\/zip&#034;},<br \/>\n            {&#034;.3gp&#034;,        &#034;video\/3gpp&#034;},<br \/>\n            {&#034;.3g2&#034;,        &#034;video\/3gpp2&#034;},<br \/>\n            {&#034;.7z&#034;,         &#034;application\/x-7z-compressed&#034;}<br \/>\n        };<br \/>\n        size_t pos &#061; filename.rfind(&#034;.&#034;);<br \/>\n        if (pos &#061;&#061; std::string::npos)<br \/>\n        {<br \/>\n            return &#034;application\/octet-stream&#034;;<br \/>\n        }<br \/>\n        std::string ext &#061; filename.substr(pos);<br \/>\n        auto it &#061; maps.find(ext);<br \/>\n        if (it &#061;&#061; maps.end())<br \/>\n            return &#034;application\/octet-stream&#034;;<br \/>\n        return it-&gt;second;<br \/>\n    } <\/p>\n<p>\u00a0\u5224\u65ad\u6587\u4ef6\u662f\u5426\u662f\u76ee\u5f55\u3001\u666e\u901a\u6587\u4ef6<\/p>\n<p>\u6709\u4e00\u4e2a\u5b8fS_ISDIR&#xff0c;\u53ef\u4ee5\u5224\u65ad\u662f\u5426\u662f\u76ee\u5f55\u6587\u4ef6\u00a0<img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"365\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054559-6805db9730884.png\" width=\"756\" \/><\/p>\n<p>    \/\/ \u5224\u65ad\u4e00\u4e2a\u6587\u4ef6\u662f\u5426\u662f\u4e00\u4e2a\u76ee\u5f55<br \/>\n    static bool IsDir(const std::string&amp; filename)<br \/>\n    {<br \/>\n        struct stat st;<br \/>\n        int ret &#061; stat(filename.c_str(), &amp;st);<br \/>\n        if (ret &lt; 0) return false;<\/p>\n<p>        return S_ISDIR(st.st_mode);<br \/>\n    }<br \/>\n    \/\/ \u5224\u65ad\u4e00\u4e2a\u6587\u4ef6\u662f\u5426\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6<br \/>\n    static bool IsRegular(const std::string&amp; filename)<br \/>\n    {<br \/>\n        struct stat st;<br \/>\n        int ret &#061; stat(filename.c_str(), &amp;st);<br \/>\n        if (ret &lt; 0) return false;<\/p>\n<p>        return S_ISREG(st.st_mode);<br \/>\n    } <\/p>\n<p>\u00a0\u68c0\u9a8c\u8d44\u6e90\u8bf7\u6c42\u8def\u5f84\u662f\u5426\u5408\u6cd5<\/p>\n<p><span style=\"color:#7b7f82\">\u5ba2\u6237\u53ea\u80fd\u8bf7\u6c42\u76f8\u5bf9\u6839\u76ee\u5f55\u4e0b\u7684\u8d44\u6e90&#xff0c;\u4f8b\u5982\u4e0d\u80fd\u8bf7\u6c42\u76f8\u5bf9\u6839\u76ee\u5f55\u4e4b\u4e0a\u7684\u6587\u4ef6\u8d44\u6e90 \/..\/idex.html<\/span><\/p>\n<p> \/\/ \u68c0\u9a8cHTTP\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u662f\u5426\u5408\u6cd5\u5b89\u5168&#xff0c;\u5ba2\u6237\u53ea\u80fd\u8bf7\u6c42\u76f8\u5bf9\u6839\u76ee\u5f55\u4e0b\u7684\u8d44\u6e90&#xff0c;\u4f8b\u5982\u4e0d\u80fd\u8bf7\u6c42\/..\/idex.html<br \/>\n    static bool ValidPath(const std::string&amp; url)<br \/>\n    {<br \/>\n        \/\/ &#034;\/Test\/..\/HTTP\/..\/&#034;<\/p>\n<p>        \/\/ \u9ed8\u8ba4\u4ece\u6839\u76ee\u5f55\u5f00\u59cb&#xff0c;\u5c42\u6570\u4e3a1&#xff0c;\u662f\u5b89\u5168\u7684&#xff0c;\u4e00\u65e6\u5c42\u6570\u4e3a0&#xff0c;\u8868\u793a\u5230\u8fbe\u76f8\u5bf9\u6839\u76ee\u5f55\u7684\u4e0a\u5c42\u76ee\u5f55&#xff0c;\u662f\u4e0d\u5b89\u5168\u7684<br \/>\n        int deep &#061; 1;<br \/>\n        for (int i &#061; 1; i &lt; url.size(); &#043;&#043;i)<br \/>\n        {<br \/>\n            \/\/ \u4e00\u822c\u4ee5\u8fd9\u79cd\u5f62\u5f0f\u51fa\u73b0 &#034;..\/&#034;<br \/>\n            if (url[i] &#061;&#061; &#039;.&#039;)<br \/>\n            {<br \/>\n                if (i &#043; 2 &lt; url.size() &amp;&amp; url[i &#043; 1] &#061;&#061; &#039;.&#039; &amp;&amp; url[i &#043; 2] &#061;&#061; &#039;\/&#039;)<br \/>\n                {<br \/>\n                    if (&#8211;deep &#061;&#061; 0)<br \/>\n                        return false;<br \/>\n                    i &#043;&#061; 2;<br \/>\n                    continue;<br \/>\n                }<br \/>\n            }<br \/>\n            if (url[i] &#061;&#061; &#039;\/&#039;)<br \/>\n                deep&#043;&#043;;<br \/>\n        }<br \/>\n        if (deep &gt; 0) return true;<br \/>\n    } <\/p>\n<h5 id=\"HTTPRequest%E6%A8%A1%E5%9D%97\">HTTPRequest<span style=\"color:#7b7f82\">\u6a21\u5757<\/span><\/h5>\n<p><span style=\"color:#7b7f82\">\u00a0HTTPRequest\u6a21\u5757<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a;\u8d1f\u8d23HTTP\u8bf7\u6c42\u7684\u62a5\u6587\u53cd\u5e8f\u5217\u540e\u7684\u5b57\u6bb5\u5b58\u50a8\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;HTTP\u8bf7\u6c42\u53cd\u5e8f\u5217\u5316\u89e3\u6790\u540e&#xff0c;\u4fbf\u4e8e\u8bf7\u6c42\u4fe1\u606f\u7684\u83b7\u53d6\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6210\u5458&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u8bf7\u6c42\u65b9\u6cd5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bf7\u6c42\u8d44\u6e90\u8def\u5f84<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u67e5\u8be2\u5b57\u7b26\u4e32<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u534f\u8bae\u7248\u672c<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u67e5\u8be2\u5b57\u7b26\u4e32\u7684\u63d2\u5165\u548c\u83b7\u53d6<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5\u7684\u63d2\u5165\u548c\u83b7\u53d6<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587\u957f\u5ea6\u7684\u83b7\u53d6<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u957f\u77ed\u8fde\u63a5\u7684\u5224\u65ad<\/span><\/li>\n<\/ul>\n<\/p>\n<p>\u5b9e\u73b0<\/p>\n<p>class HttpRequest {<br \/>\npublic:<br \/>\n    std::string _method;      \/\/\u8bf7\u6c42\u65b9\u6cd5<br \/>\n    std::string _path;        \/\/\u8d44\u6e90\u8def\u5f84<br \/>\n    std::string _version;     \/\/\u534f\u8bae\u7248\u672c<br \/>\n    std::string _body;        \/\/\u8bf7\u6c42\u6b63\u6587<br \/>\n    std::smatch _matches;     \/\/\u8d44\u6e90\u8def\u5f84\u7684\u6b63\u5219\u63d0\u53d6\u6570\u636e<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _headers;  \/\/\u5934\u90e8\u5b57\u6bb5<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _params;   \/\/\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\npublic:<br \/>\n    HttpRequest() : _version(&#034;HTTP\/1.1&#034;) {}<br \/>\n    void ReSet()<br \/>\n    {<br \/>\n        _method.clear();<br \/>\n        _path.clear();<br \/>\n        _version &#061; &#034;HTTP\/1.1&#034;;<br \/>\n        _body.clear();<br \/>\n        std::smatch match;<br \/>\n        _matches.swap(match);<br \/>\n        _headers.clear();<br \/>\n        _params.clear();<br \/>\n    }<br \/>\n    \/\/\u63d2\u5165\u5934\u90e8\u5b57\u6bb5<br \/>\n    void SetHeader(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        _headers.insert(std::make_pair(key, val));<br \/>\n    }<br \/>\n    \/\/\u5224\u65ad\u662f\u5426\u5b58\u5728\u6307\u5b9a\u5934\u90e8\u5b57\u6bb5<br \/>\n    bool HasHeader(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n            return false;<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/\u83b7\u53d6\u6307\u5b9a\u5934\u90e8\u5b57\u6bb5\u7684\u503c<br \/>\n    std::string GetHeader(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end())<br \/>\n            return &#034;&#034;;<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/\u63d2\u5165\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    void SetParam(const std::string &amp;key, const std::string &amp;val)<br \/>\n    {<br \/>\n        _params.insert(std::make_pair(key, val));<br \/>\n    }<br \/>\n    \/\/\u5224\u65ad\u662f\u5426\u6709\u67d0\u4e2a\u6307\u5b9a\u7684\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    bool HasParam(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _params.find(key);<br \/>\n        if (it &#061;&#061; _params.end())<br \/>\n            return false;<\/p>\n<p>        return true;<br \/>\n    }<br \/>\n    \/\/\u83b7\u53d6\u6307\u5b9a\u7684\u67e5\u8be2\u5b57\u7b26\u4e32<br \/>\n    std::string GetParam(const std::string &amp;key) const<br \/>\n    {<br \/>\n        auto it &#061; _params.find(key);<br \/>\n        if (it &#061;&#061; _params.end())<br \/>\n            return &#034;&#034;;<\/p>\n<p>        return it-&gt;second;<br \/>\n    }<br \/>\n    \/\/\u83b7\u53d6\u6b63\u6587\u957f\u5ea6<br \/>\n    size_t ContentLength() const<br \/>\n    {<br \/>\n        \/\/ Content-Length: 1234\\\\r\\\\n<br \/>\n        bool ret &#061; HasHeader(&#034;Content-Length&#034;);<br \/>\n        if (ret &#061;&#061; false)<br \/>\n            return 0;<\/p>\n<p>        std::string clen &#061; GetHeader(&#034;Content-Length&#034;);<br \/>\n        return std::stol(clen);<br \/>\n    }<br \/>\n    \/\/\u5224\u65ad\u662f\u5426\u662f\u77ed\u94fe\u63a5<br \/>\n    bool Close() const<br \/>\n    {<br \/>\n        \/\/ \u6ca1\u6709Connection\u5b57\u6bb5&#xff0c;\u6216\u8005\u6709Connection\u4f46\u662f\u503c\u662fclose&#xff0c;\u5219\u90fd\u662f\u77ed\u94fe\u63a5&#xff0c;\u5426\u5219\u5c31\u662f\u957f\u8fde\u63a5<br \/>\n        if (HasHeader(&#034;Connection&#034;) &#061;&#061; true &amp;&amp; GetHeader(&#034;Connection&#034;) &#061;&#061; &#034;keep-alive&#034;)<br \/>\n        {<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n}; <\/p>\n<h5 id=\"HTTPResponse%E6%A8%A1%E5%9D%97\">HTTPResponse<span style=\"color:#7b7f82\">\u6a21\u5757<\/span><\/h5>\n<p><span style=\"color:#7b7f82\">HTTPResponse\u6a21\u5757<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a; \u8d1f\u8d23HTTP\u54cd\u5e94\u62a5\u6587\u7684\u4fe1\u606f\u5b58\u50a8\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;\u4fbf\u4e8e\u540e\u7eed\u6784\u5efaHTTP\u54cd\u5e94\u62a5\u6587\u65f6&#xff0c;\u83b7\u53d6\u5404\u4e2a\u62a5\u6587\u5b57\u6bb5\u4fe1\u606f\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6210\u5458&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5&#xff08;\u54c8\u5e0c\u8868\u5b58\u50a8&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u91cd\u5b9a\u5411\u4fe1\u606f&#xff08;\u662f\u5426\u8fdb\u884c\u4e86\u91cd\u5b9a\u5411&#xff0c;\u5df2\u7ecf\u91cd\u5b9a\u5411\u7684URL&#xff09;<\/span><\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5934\u90e8\u5b57\u6bb5\u7684\u63d2\u5165\u3001\u83b7\u53d6\u3001\u67e5\u8be2<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6b63\u6587\u7684\u8bbe\u7f6e<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u91cd\u5b9a\u5411\u8bbe\u7f6e<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u957f\u77ed\u8fde\u63a5\u7684\u5224\u65ad<\/span><\/li>\n<\/ul>\n<p>\u00a0\u5b9e\u73b0<\/p>\n<p>class HttpResponse<br \/>\n{<br \/>\npublic:<br \/>\n    int _statu;<br \/>\n    bool _redirect_flag;<br \/>\n    std::string _body;<br \/>\n    std::string _redirect_url;<br \/>\n    std::unordered_map&lt;std::string, std::string&gt; _headers;<br \/>\npublic:<br \/>\n    HttpResponse():_redirect_flag(false), _statu(200) {}<br \/>\n    HttpResponse(int statu):_redirect_flag(false), _statu(statu) {}<br \/>\n    void ReSet() {<br \/>\n        _statu &#061; 200;<br \/>\n        _redirect_flag &#061; false;<br \/>\n        _body.clear();<br \/>\n        _redirect_url.clear();<br \/>\n        _headers.clear();<br \/>\n    }<br \/>\n    \/\/\u63d2\u5165\u5934\u90e8\u5b57\u6bb5<br \/>\n    void SetHeader(const std::string &amp;key, const std::string &amp;val) {<br \/>\n        _headers.insert(std::make_pair(key, val));<br \/>\n    }<br \/>\n    \/\/\u5224\u65ad\u662f\u5426\u5b58\u5728\u6307\u5b9a\u5934\u90e8\u5b57\u6bb5<br \/>\n    bool HasHeader(const std::string &amp;key) {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end()) {<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/\u83b7\u53d6\u6307\u5b9a\u5934\u90e8\u5b57\u6bb5\u7684\u503c<br \/>\n    std::string GetHeader(const std::string &amp;key) {<br \/>\n        auto it &#061; _headers.find(key);<br \/>\n        if (it &#061;&#061; _headers.end()) {<br \/>\n            return &#034;&#034;;<br \/>\n        }<br \/>\n        return it-&gt;second;<br \/>\n    }<br \/>\n    void SetContent(const std::string &amp;body,  const std::string &amp;type &#061; &#034;text\/html&#034;) {<br \/>\n        _body &#061; body;<br \/>\n        SetHeader(&#034;Content-Type&#034;, type);<br \/>\n    }<br \/>\n    void SetRedirect(const std::string &amp;url, int statu &#061; 302) {<br \/>\n        _statu &#061; statu;<br \/>\n        _redirect_flag &#061; true;<br \/>\n        _redirect_url &#061; url;<br \/>\n    }<br \/>\n    \/\/\u5224\u65ad\u662f\u5426\u662f\u77ed\u94fe\u63a5<br \/>\n    bool Close() {<br \/>\n        \/\/ \u6ca1\u6709Connection\u5b57\u6bb5&#xff0c;\u6216\u8005\u6709Connection\u4f46\u662f\u503c\u662fclose&#xff0c;\u5219\u90fd\u662f\u77ed\u94fe\u63a5&#xff0c;\u5426\u5219\u5c31\u662f\u957f\u8fde\u63a5<br \/>\n        if (HasHeader(&#034;Connection&#034;) &#061;&#061; true &amp;&amp; GetHeader(&#034;Connection&#034;) &#061;&#061; &#034;keep-alive&#034;) {<br \/>\n            return false;<br \/>\n        }<br \/>\n        return true;<br \/>\n    }<br \/>\n}; <\/p>\n<h5 id=\"%E4%B8%8A%E4%B8%8B%E6%96%87\">HTTPContext<span style=\"color:#7b7f82\">\u6a21\u5757<\/span><\/h5>\n<p><span style=\"color:#7b7f82\">HTTPContext\u6a21\u5757<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u529f\u80fd&#xff1a;\u5bf9HTTP\u8bf7\u6c42\u53cd\u5e8f\u5217\u5316&#xff0c;\u5e76\u8bb0\u5f55HTTP\u8bf7\u6c42\u7684\u63a5\u6536\u548c\u5904\u7406\u8fdb\u5ea6\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u610f\u4e49&#xff1a;\u670d\u52a1\u7aef\u7684\u4e00\u4e2a\u8fde\u63a5\u8bfb\u4e8b\u4ef6\u5c31\u7eea\u540e&#xff0c;\u4f1a\u8c03\u7528\u8be5\u8fde\u63a5\u7684\u8bfb\u56de\u8c03\u51fd\u6570&#xff0c;\u6b64\u65f6\u8bfb\u4e0a\u6765\u7684\u6570\u636e\u53ef\u80fd\u5e76\u4e0d\u662f\u4e00\u4e2a\u5b8c\u6574\u7684HTTP\u8bf7\u6c42\u62a5\u6587&#xff08;\u56e0\u4e3aTCP\u9762\u5411\u5b57\u8282\u6d41&#xff09;&#xff0c;\u6240\u4ee5\u4e0a\u5c42\u4e1a\u52a1\u5904\u7406&#xff08;\u5bf9HTTP\u8bf7\u6c42\u62a5\u6587\u7684\u89e3\u6790&#xff09;\u5c31\u4f1a\u5931\u8d25&#xff0c;\u9700\u8981\u6536\u5230\u5269\u4f59\u7684HTTP\u8bf7\u6c42\u62a5\u6587\u6570\u636e\u624d\u80fd\u5b8c\u6210HTTP\u8bf7\u6c42\u62a5\u6587\u7684\u53cd\u5e8f\u5217\u5316\u5de5\u4f5c&#xff0c;\u56e0\u6b64\u6bcf\u6b21\u5728\u4e00\u4e2a\u8fde\u63a5\u7684\u8bf7\u6c42\u62a5\u6587\u5904\u7406\u7684\u65f6\u5019&#xff0c;\u9700\u8981\u5c06\u5904\u7406\u8fdb\u5ea6\u8bb0\u5f55&#xff0c;\u4ee5\u4fbf\u4e8e\u4e0b\u6b21\u5904\u7406\u65f6\u7ee7\u7eed\u4ece\u4e0a\u6b21\u7684\u8fdb\u5ea6\u5411\u4e0b\u5904\u7406\u3002\u6211\u4eec\u5728\u670d\u52a1\u5668\u6a21\u5757\u5df2\u7ecf\u5bf9\u4e00\u4e2a\u8fde\u63a5\u7684Connection\u5bf9\u8c61\u6dfb\u52a0\u4e86Any\u7c7b\u578b\u7684context\u6210\u5458&#xff0c;\u8fd9\u4e2acontext\u6210\u5458\u5c31\u662f\u7528\u6765\u63a5\u6536HTTPContext\u5bf9\u8c61\u7684&#xff0c;\u6240\u4ee5\u4e4b\u540e\u6bcf\u6b21\u5904\u7406\u8bf7\u6c42\u62a5\u6587\u65f6\u53ef\u4ee5\u6839\u636eConnection\u5bf9\u8c61\u7684context\u6210\u5458\u6765\u83b7\u53d6\u5f53\u524d\u62a5\u6587\u5904\u7406\u8fdb\u5ea6\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6210\u5458&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u63a5\u6536\u72b6\u6001<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5230\u8bf7\u6c42\u884c<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5230\u8bf7\u6c42\u5934\u90e8<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5230\u8bf7\u6c42\u6b63\u6587<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u5b8c\u6bd5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5904\u7406\u51fa\u9519<\/span><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"color:#7b7f82\">\u54cd\u5e94\u72b6\u6001\u7801<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5728HTTP\u8bf7\u6c42\u62a5\u6587\u7684\u89e3\u6790\u8fc7\u7a0b\u4e2d\u53ef\u80fd\u4f1a\u51fa\u73b0\u9519\u8bef&#xff0c;\u4f8b\u5982&#xff1a;\u8bbf\u95ee\u8d44\u6e90\u4e0d\u5b58\u5728\u3001\u8d44\u6e90\u8def\u5f84\u4e0d\u5408\u6cd5&#xff0c;\u6211\u4eec\u9700\u8981\u5bf9\u8fd9\u4e9b\u9519\u8bef\u8bbe\u7f6e\u5bf9\u5e94\u7684\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"color:#7b7f82\">\u63a5\u53e3&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u63a5\u6536\u5e76\u5904\u7406\u6570\u636e<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fd4\u56de\u53cd\u5e8f\u5217\u5316\u89e3\u6790\u5b8c\u6bd5\u7684\u8bf7\u6c42\u4fe1\u606f&#xff08;\u4e00\u4e2aHTTPrequest\u5bf9\u8c61&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fd4\u56de\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fd4\u56de\u5f53\u524d\u5904\u7406\u7684\u72b6\u6001<\/span><\/li>\n<\/ul>\n<p>#define MAX_LINE 8192<br \/>\nclass HttpContext<br \/>\n{<br \/>\nprivate:<br \/>\n    int _resp_statu; \/\/\u54cd\u5e94\u72b6\u6001\u7801<br \/>\n    HttpRecvStatu _recv_statu; \/\/\u5f53\u524d\u63a5\u6536\u53ca\u89e3\u6790\u7684\u9636\u6bb5\u72b6\u6001<br \/>\n    HttpRequest _request;  \/\/\u5df2\u7ecf\u89e3\u6790\u5f97\u5230\u7684\u8bf7\u6c42\u4fe1\u606f<br \/>\nprivate:<br \/>\n    bool ParseHttpLine(const std::string &amp;line)<br \/>\n    {}<br \/>\n    bool RecvHttpLine(Buffer *buf)<br \/>\n    {}<br \/>\n    bool RecvHttpHead(Buffer *buf)<br \/>\n    {}<br \/>\n    bool ParseHttpHead(std::string &amp;line)<br \/>\n    {}<br \/>\n    bool RecvHttpBody(Buffer *buf)<br \/>\n    {}<br \/>\npublic:<br \/>\n    HttpContext():_resp_statu(200), _recv_statu(RECV_HTTP_LINE) {}<br \/>\n    void ReSet()<br \/>\n    {}<br \/>\n    int RespStatu() {}<br \/>\n    HttpRecvStatu RecvStatu() {}<br \/>\n    HttpRequest &amp;Request() {}<br \/>\n    \/\/\u63a5\u6536\u5e76\u89e3\u6790HTTP\u8bf7\u6c42<br \/>\n    void RecvHttpRequest(Buffer *buf)<br \/>\n    {}<br \/>\n}; <\/p>\n<p>\u5b9e\u73b0\u00a0<\/p>\n<p><span style=\"color:#7b7f82\">\u679a\u4e3e\u4e94\u79cd\u72b6\u6001&#xff1a;<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">RECV_HTTP_ERROR<\/span><\/li>\n<li><span style=\"color:#7b7f82\">RECV_HTTP_LINE<\/span><\/li>\n<li><span style=\"color:#7b7f82\">RECV_HTTP_HEAD<\/span><\/li>\n<li><span style=\"color:#7b7f82\">RECV_HTTP_BODY<\/span><\/li>\n<li><span style=\"color:#7b7f82\">RECV_HTTP_OVER<\/span><\/li>\n<\/ul>\n<p>typedef enum {<br \/>\n    RECV_HTTP_ERROR,<br \/>\n    RECV_HTTP_LINE,<br \/>\n    RECV_HTTP_HEAD,<br \/>\n    RECV_HTTP_BODY,<br \/>\n    RECV_HTTP_OVER<br \/>\n}HttpRecvStatu;<\/p>\n<h6 id=\"ParseHttpLine\">ParseHttpLine<\/h6>\n<p><span style=\"color:#7b7f82\">\u00a0\u6b63\u5219\u8868\u8fbe\u5f0f\u89e3\u6790HTTP\u8bf7\u6c42\u884c&#xff0c;\u83b7\u53d6HTTP\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u3001\u67e5\u8be2\u5b57\u7b26\u4e32<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6b63\u5219\u8868\u8fbe\u5f0f\u662f\u4e00\u79cd\u7528\u4e8e\u5339\u914d\u5b57\u7b26\u4e32\u4e2d\u5b57\u7b26\u7ec4\u5408\u7684\u6a21\u5f0f\u3002\u901a\u8fc7\u4f7f\u7528\u4e00\u7cfb\u5217\u7279\u6b8a\u7684\u7b26\u53f7\u548c\u89c4\u5219&#xff0c;\u6211\u4eec\u53ef\u4ee5\u6784\u5efa\u51fa\u590d\u6742\u7684\u641c\u7d22\u6761\u4ef6&#xff0c;\u5e76\u5229\u7528\u5b83\u6765\u8fdb\u884c\u6587\u672c\u67e5\u627e\u3001\u66ff\u6362\u7b49\u64cd\u4f5c\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u6b63\u5219\u8868\u8fbe\u5f0f\u7684\u7ec4\u6210<\/span><\/p>\n<li><span style=\"color:#7b7f82\">\u666e\u901a\u5b57\u7b26&#xff1a;\u5305\u62ec\u5b57\u6bcd\u3001\u6570\u5b57\u4ee5\u53ca\u6807\u70b9\u7b26\u53f7\u7b49\u76f4\u63a5\u4ee3\u8868\u5b83\u4eec\u81ea\u8eab\u7684\u5b57\u7b26\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u7279\u6b8a\u5b57\u7b26&#xff08;\u5143\u5b57\u7b26&#xff09;&#xff1a;<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">.\u00a0\u5339\u914d\u4efb\u610f\u5355\u4e2a\u5b57\u7b26&#xff08;\u6362\u884c\u7b26\u9664\u5916&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">*\u00a0\u8868\u793a\u524d\u9762\u5143\u7d20\u53ef\u4ee5\u51fa\u73b0\u96f6\u6b21\u6216\u591a\u6b21<\/span><\/li>\n<li><span style=\"color:#7b7f82\">&#043;\u00a0\u524d\u9762\u5143\u7d20\u5fc5\u987b\u81f3\u5c11\u51fa\u73b0\u4e00\u6b21\u4ee5\u4e0a\u624d\u80fd\u6210\u529f\u5339\u914d<\/span><\/li>\n<li><span style=\"color:#7b7f82\">?\u00a0\u610f\u5473\u7740\u524d\u4e00\u9879\u76ee\u662f\u53ef\u9009\u9879&#xff0c;\u5373\u80fd\u5b58\u5728\u4e5f\u53ef\u4ee5\u4e0d\u5b58\u5728<\/span><\/li>\n<\/ul>\n<\/li>\n<p>\u4e3e\u4f8b&#xff1a;\u00a0<\/p>\n<p>std::string s &#061; &#034;GET \/helloworld\/login?user&#061;zhangsan&amp;passwd&#061;suici HTTP\/1.1\\\\r\\\\n&#034;;<br \/>\nstd::smatch matches;<br \/>\nstd::regex e(&#034;(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\\\\\\\?(.*))? (HTTP\/1\\\\\\\\.[01])(?:\\\\n|\\\\r\\\\n)?&#034;);<br \/>\n\/\/ (GET|HEAD|POST|PUT|DELETE) \u8868\u793a\u67e5\u627e\u8fd9\u4e9b\u5b57\u7b26\u4e32\u7684\u4efb\u610f\u4e00\u4e2a<br \/>\n\/\/ ([^?]*) [^?]\u8868\u793a\u5339\u914d\u975e\u95ee\u53f7\u5b57\u7b26&#xff0c;*\u8868\u793a0\u6b21\u6216\u8005\u591a\u6b21<br \/>\n\/\/ \\\\\\\\? \u8868\u793a\u8f6c\u4e49\u7684\u95ee\u53f7  (.*)\u8868\u793a\u63d0\u53d6&#xff1f;\u4e4b\u540e\u7684\u4efb\u610f\u5b57\u7b260\u6b21\u6216\u591a\u6b21<br \/>\nbool ret &#061; std::regex_match(s, matches, e);<br \/>\nif (!ret) return -1;<br \/>\nfor (auto&amp; e : matches)<br \/>\n{<br \/>\n    std::cout &lt;&lt; e &lt;&lt; std::endl;<br \/>\n} <\/p>\n<p>\u00a0<img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"119\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054559-6805db975aa5f.png\" width=\"445\" \/><\/p>\n<p><span style=\"color:#7b7f82\">\u6211\u4eec\u7684\u6b63\u5219\u8868\u8fbe\u5f0f\u907f\u514d\u4e86<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u56e0\u4e3a\u8bf7\u6c42\u884c\u4e2d\u53c8 \\\\r\\\\n \u800c\u5339\u914d\u5931\u8d25\u95ee\u9898<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6ca1\u6709\u641c\u7d22\u5173\u952e\u5b57? \u5931\u8d25\u95ee\u9898\u00a0<\/span><\/li>\n<\/ul>\n<p>\u00a0\u5b9e\u73b0<\/p>\n<p>\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<ul>\n<li>\n<p><span style=\"color:#7b7f82\">ParseHttpLine\u76ee\u7684\u662f\u53cd\u5e8f\u5217\u5316\u8bf7\u6c42\u884c&#xff0c;\u83b7\u53d6\u8bf7\u6c42\u62a5\u6587\u7684\u8bf7\u6c42\u65b9\u6cd5\u3001\u8bf7\u6c42\u8d44\u6e90\u8def\u5f84\u3001\u67e5\u8be2\u5b57\u7b26\u4e32\u3001HTTP\u7248\u672c\u4fe1\u606f&#xff0c;\u5e76\u5b58\u50a8\u5728HTTPRequest\u5bf9\u8c61\u4e2d<\/span><\/p>\n<\/li>\n<li><span style=\"color:#7b7f82\">\u4e3a\u4e86\u4ee3\u7801\u7684\u5065\u58ee\u6027&#xff0c;\u6709\u4e9bHTTP\u8bf7\u6c42\u7684\u8bf7\u6c42\u65b9\u6cd5\u53ef\u80fd\u662f\u5c0f\u5199&#xff0c;\u6240\u4ee5\u5728\u53cd\u5e8f\u5217\u5316\u8bf7\u6c42\u884c\u65f6\u9700\u8981\u5c06\u8bf7\u6c42\u65b9\u6cd5\u7edf\u4e00\u5927\u5199<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6d4f\u89c8\u5668\u7684URL\u9ed8\u8ba4\u4f1a\u8fdb\u884c\u7279\u6b8a\u5b57\u7b26\u7f16\u7801&#xff0c;\u6240\u4ee5\u6211\u4eec\u9700\u8981\u5c06\u83b7\u53d6\u5230\u7684\u8d44\u6e90\u8def\u5f84\u8fdb\u884cURL\u89e3\u7801\u00a0<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5bf9\u4e8e\u67e5\u8be2\u5b57\u7b26\u4e32&#xff0c;\u53ef\u80fd\u4f1a\u6709\u591a\u4e2a\u4ee5&amp;\u4f5c\u4e3a\u5206\u9694\u7b26\u7684\u952e\u503c\u5bf9&#xff0c;\u6240\u4ee5\u6211\u4eec\u5728\u5bf9HTTPRequest\u5bf9\u8c61\u586b\u5145\u8bf7\u6c42\u62a5\u6587\u7684\u62a5\u5934\u5b57\u6bb5\u65f6&#xff0c;\u9700\u8981\u8fdb\u884c\u5b57\u7b26\u4e32\u5206\u5272&#xff0c;\u83b7\u53d6\u5404\u4e2a\u952e\u503c\u5bf9&#xff0c;\u518d\u5bf9\u5404\u4e2a\u952e\u503c\u5bf9\u4ee5&#xff1a;\u4f5c\u4e3a\u5206\u9694\u7b26&#xff0c;\u63d2\u5165\u5230HTTPRequest\u5bf9\u8c61\u7684\u5b58\u50a8\u62a5\u5934\u5b57\u6bb5\u7684\u54c8\u5e0c\u8868\u4e2d<\/span><\/li>\n<\/ul>\n<ul>\n<li><span style=\"color:#7b7f82\">(GET|HEAD|POST|PUT|DELETE) \u8868\u793a\u67e5\u627e\u8fd9\u4e9b\u5b57\u7b26\u4e32\u7684\u4efb\u610f\u4e00\u4e2a<\/span><\/li>\n<li><span style=\"color:#7b7f82\">([^?]*) [^?]\u8868\u793a\u5339\u914d\u975e\u95ee\u53f7\u5b57\u7b26&#xff0c;*\u8868\u793a0\u6b21\u6216\u8005\u591a\u6b21<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\\\\\\\\? \u8868\u793a\u8f6c\u4e49\u7684\u95ee\u53f7 \u00a0(.*)\u8868\u793a\u63d0\u53d6&#xff1f;\u4e4b\u540e\u7684\u4efb\u610f\u5b57\u7b260\u6b21\u6216\u591a\u6b21<\/span><\/li>\n<\/ul>\n<p>bool ParseHttpLine(const std::string &amp;line)<br \/>\n{<br \/>\n    std::smatch matches;<br \/>\n    std::regex e(&#034;(GET|HEAD|POST|PUT|DELETE) ([^?]*)(?:\\\\\\\\?(.*))? (HTTP\/1\\\\\\\\.[01])(?:\\\\n|\\\\r\\\\n)?&#034;, std::regex::icase);<br \/>\n    bool ret &#061; std::regex_match(line, matches, e);<br \/>\n    if (ret &#061;&#061; false)<br \/>\n    {<br \/>\n        _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n        _resp_statu &#061; 400;\/\/BAD REQUEST<br \/>\n        return false;<br \/>\n    }<br \/>\n    \/\/0 : GET \/bitejiuyeke\/login?user&#061;xiaoming&amp;pass&#061;123123 HTTP\/1.1<br \/>\n    \/\/1 : GET<br \/>\n    \/\/2 : \/bitejiuyeke\/login<br \/>\n    \/\/3 : user&#061;xiaoming&amp;pass&#061;123123<br \/>\n    \/\/4 : HTTP\/1.1<br \/>\n    \/\/\u8bf7\u6c42\u65b9\u6cd5\u7684\u83b7\u53d6<br \/>\n    _request._method &#061; matches[1];<br \/>\n    std::transform(_request._method.begin(), _request._method.end(), _request._method.begin(), ::toupper);<br \/>\n    \/\/\u8d44\u6e90\u8def\u5f84\u7684\u83b7\u53d6&#xff0c;\u9700\u8981\u8fdb\u884cURL\u89e3\u7801\u64cd\u4f5c&#xff0c;\u4f46\u662f\u4e0d\u9700\u8981&#043;\u8f6c\u7a7a\u683c<br \/>\n    _request._path &#061; Util::UrlDecode(matches[2], false);<br \/>\n    \/\/\u534f\u8bae\u7248\u672c\u7684\u83b7\u53d6<br \/>\n    _request._version &#061; matches[4];<br \/>\n    \/\/\u67e5\u8be2\u5b57\u7b26\u4e32\u7684\u83b7\u53d6\u4e0e\u5904\u7406<br \/>\n    std::vector&lt;std::string&gt; query_string_arry;<br \/>\n    std::string query_string &#061; matches[3];<br \/>\n    \/\/\u67e5\u8be2\u5b57\u7b26\u4e32\u7684\u683c\u5f0f key&#061;val&amp;key&#061;val&#8230;.., \u5148\u4ee5 &amp; \u7b26\u53f7\u8fdb\u884c\u5206\u5272&#xff0c;\u5f97\u5230\u5404\u4e2a\u5b57\u4e32<br \/>\n    Util::Split(query_string, &#034;&amp;&#034;, &amp;query_string_arry);<br \/>\n    \/\/\u9488\u5bf9\u5404\u4e2a\u5b57\u4e32&#xff0c;\u4ee5 &#061; \u7b26\u53f7\u8fdb\u884c\u5206\u5272&#xff0c;\u5f97\u5230key \u548cval&#xff0c; \u5f97\u5230\u4e4b\u540e\u4e5f\u9700\u8981\u8fdb\u884cURL\u89e3\u7801<br \/>\n    for (auto &amp;str : query_string_arry)<br \/>\n    {<br \/>\n        size_t pos &#061; str.find(&#034;&#061;&#034;);<br \/>\n        if (pos &#061;&#061; std::string::npos)<br \/>\n        {<br \/>\n            _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n            _resp_statu &#061; 400;\/\/BAD REQUEST<br \/>\n            return false;<br \/>\n        }<br \/>\n        std::string key &#061; Util::UrlDecode(str.substr(0, pos), true);<br \/>\n        std::string val &#061; Util::UrlDecode(str.substr(pos &#043; 1), true);<br \/>\n        _request.SetParam(key, val);<br \/>\n    }<br \/>\n    return true;<br \/>\n} <\/p>\n<h6 id=\"RecvHttpLine\">RecvHttpLine<\/h6>\n<p>\u00a0\u4ece\u8f93\u5165\u7f13\u51b2\u533a\u8bfb\u53d6\u4e00\u884c\u6570\u636e&#xff0c;\u5e76\u8fdb\u884cHTTP\u8bf7\u6c42\u884c\u7684\u89e3\u6790<\/p>\n<p><span style=\"color:#7b7f82\">\u6ce8\u610f\u70b9&#xff1a;<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u89c4\u5b9a\u4e00\u4e2a\u8bf7\u6c42\u884c\u6700\u5927\u957f\u5ea6\u4e3a MAX_LINE\u00a0&#061;\u00a08K<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5148\u5224\u5b9a\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3aRECV_HTTP_LINE&#xff0c;\u5982\u679c\u4e0d\u662f\u5219 return false<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u8f93\u5165\u7f13\u51b2\u533a\u6ca1\u6709\u4e00\u884c\u6570\u636e&#xff08;\u5373\u6ca1\u6709 &#039;\\\\n&#039;&#xff09;<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u8f93\u5165\u7f13\u51b2\u533a\u53ef\u8bfb\u5b57\u8282\u6570\u5927\u4e8e8K&#xff0c;\u5219\u5224\u5b9a\u8be5\u8bf7\u6c42\u62a5\u6587\u6709\u95ee\u9898&#xff0c;HTTP\u54cd\u5e94414\u72b6\u6001\u7801 &#8212; \u201cURI Too Long\u201d&#xff0c;\u5e76return false<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u8f93\u5165\u7f13\u51b2\u533a\u53ef\u8bfb\u5b57\u8282\u6570\u5c0f\u4e8e8K&#xff0c;\u5219return true&#xff0c;\u7b49\u5f85\u4e0b\u4e00\u6b21\u8bfb\u4e8b\u4ef6\u5c31\u7eea\u65f6\u88ab\u56de\u8c03<\/span><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u83b7\u53d6\u5230\u4e86\u4e00\u884c\u6570\u636e&#xff0c;\u4f46\u662f\u6570\u636e\u957f\u5ea6\u5927\u4e8eMAX_LINE&#xff0c;\u540c\u6837HTTP\u54cd\u5e94414\u72b6\u6001\u7801 &#8212; \u201cURI Too Long\u201d&#xff0c;\u5e76return false<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8c03\u7528ParseHttpLine&#xff0c;\u8fdb\u884c\u8bf7\u6c42\u884c\u7684\u53cd\u5e8f\u5217\u5316\u5904\u7406<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679cParseHttpLine\u8fd4\u56de\u503c\u4e3a\u771f&#xff0c;\u5219\u8868\u660e\u53cd\u5e8f\u5217\u5316\u6210\u529f&#xff0c;\u8fdb\u5165\u5934\u90e8\u5b57\u6bb5\u83b7\u53d6\u72b6\u6001<\/span><\/li>\n<\/ul>\n<p>bool RecvHttpLine(Buffer *buf)<br \/>\n{<br \/>\n    if (_recv_statu !&#061; RECV_HTTP_LINE) return false;<br \/>\n    \/\/1. \u83b7\u53d6\u4e00\u884c\u6570\u636e&#xff0c;\u5e26\u6709\u672b\u5c3e\u7684\u6362\u884c<br \/>\n    std::string line &#061; buf-&gt;Getline();<br \/>\n    \/\/2. \u9700\u8981\u8003\u8651\u7684\u4e00\u4e9b\u8981\u7d20&#xff1a;\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c; \u83b7\u53d6\u7684\u4e00\u884c\u6570\u636e\u8d85\u5927<br \/>\n    if (line.size() &#061;&#061; 0) {<br \/>\n        \/\/\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u5219\u9700\u8981\u5224\u65ad\u7f13\u51b2\u533a\u7684\u53ef\u8bfb\u6570\u636e\u957f\u5ea6&#xff0c;\u5982\u679c\u5f88\u957f\u4e86\u90fd\u4e0d\u8db3\u4e00\u884c&#xff0c;\u8fd9\u662f\u6709\u95ee\u9898\u7684<br \/>\n        if (buf-&gt;ReadAbleSize() &gt; MAX_LINE)<br \/>\n        {<br \/>\n            _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n            _resp_statu &#061; 414;\/\/URI TOO LONG<br \/>\n            return false;<br \/>\n        }<br \/>\n        \/\/\u7f13\u51b2\u533a\u4e2d\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u4f46\u662f\u4e5f\u4e0d\u591a&#xff0c;\u5c31\u7b49\u7b49\u65b0\u6570\u636e\u7684\u5230\u6765<br \/>\n        return true;<br \/>\n    }<br \/>\n    if (line.size() &gt; MAX_LINE)<br \/>\n    {<br \/>\n        _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n        _resp_statu &#061; 414;\/\/URI TOO LONG<br \/>\n        return false;<br \/>\n    }<br \/>\n    bool ret &#061; ParseHttpLine(line);<br \/>\n    if (ret &#061;&#061; false)<br \/>\n        return false;<\/p>\n<p>    \/\/\u9996\u884c\u5904\u7406\u5b8c\u6bd5&#xff0c;\u8fdb\u5165\u5934\u90e8\u83b7\u53d6\u9636\u6bb5<br \/>\n    _recv_statu &#061; RECV_HTTP_HEAD;<br \/>\n    return true;<br \/>\n} <\/p>\n<h6 id=\"RecvHttpHead\">RecvHttpHead<\/h6>\n<p>HTTP\u8bf7\u6c42\u5934\u90e8\u5b57\u6bb5\u7684\u8bfb\u53d6<\/p>\n<p>\u00a0\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5148\u5224\u65ad\u5f53\u524d\u72b6\u6001\u662f\u5426\u4e3aRECV_HTTP_HEAD<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5faa\u73af\u8bfb\u53d6\u6bcf\u4e00\u4e2a\u5934\u90e8\u5b57\u6bb5&#xff0c;\u9047\u5230\u8fde\u7eed\u7684 \\\\r\\\\n \u6216\u8fde\u7eed\u7684 \\\\n \u5219 break<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5c06\u6bcf\u4e00\u4e2a\u5934\u90e8\u5b57\u6bb5\u8c03\u7528ParseHttpHead\u8fdb\u884c\u89e3\u6790&#xff0c;\u5e76\u5c06\u89e3\u6790\u7ed3\u679c insert \u5230 _request \u5bf9\u8c61\u4e2d<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u89e3\u6790\u6210\u529f&#xff0c;\u5219\u5f53\u524d\u5904\u7406\u72b6\u6001\u66f4\u6539\u4e3aRECV_HTTP_BODY&#xff0c;\u8868\u660e\u5934\u90e8\u5904\u7406\u5b8c\u6bd5&#xff0c;\u8fdb\u5165\u6b63\u6587\u83b7\u53d6\u9636\u6bb5<\/span><\/li>\n<\/ul>\n<p>bool RecvHttpHead(Buffer *buf)<br \/>\n{<br \/>\n    if (_recv_statu !&#061; RECV_HTTP_HEAD) return false;<br \/>\n    \/\/\u4e00\u884c\u4e00\u884c\u53d6\u51fa\u6570\u636e&#xff0c;\u76f4\u5230\u9047\u5230\u7a7a\u884c\u4e3a\u6b62&#xff0c; \u5934\u90e8\u7684\u683c\u5f0f key: val\\\\r\\\\nkey: val\\\\r\\\\n&#8230;.<br \/>\n    while(1)<br \/>\n    {<br \/>\n        std::string line &#061; buf-&gt;Getline();<br \/>\n        \/\/2. \u9700\u8981\u8003\u8651\u7684\u4e00\u4e9b\u8981\u7d20&#xff1a;\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c; \u83b7\u53d6\u7684\u4e00\u884c\u6570\u636e\u8d85\u5927<br \/>\n        if (line.size() &#061;&#061; 0)<br \/>\n        {<br \/>\n            \/\/\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u5219\u9700\u8981\u5224\u65ad\u7f13\u51b2\u533a\u7684\u53ef\u8bfb\u6570\u636e\u957f\u5ea6&#xff0c;\u5982\u679c\u5f88\u957f\u4e86\u90fd\u4e0d\u8db3\u4e00\u884c&#xff0c;\u8fd9\u662f\u6709\u95ee\u9898\u7684<br \/>\n            if (buf-&gt;ReadAbleSize() &gt; MAX_LINE)<br \/>\n            {<br \/>\n                _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n                _resp_statu &#061; 414;\/\/URI TOO LONG<br \/>\n                return false;<br \/>\n            }<br \/>\n            \/\/\u7f13\u51b2\u533a\u4e2d\u6570\u636e\u4e0d\u8db3\u4e00\u884c&#xff0c;\u4f46\u662f\u4e5f\u4e0d\u591a&#xff0c;\u5c31\u7b49\u7b49\u65b0\u6570\u636e\u7684\u5230\u6765<br \/>\n            return true;<br \/>\n        }<br \/>\n        if (line.size() &gt; MAX_LINE) {<br \/>\n            _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n            _resp_statu &#061; 414;\/\/URI TOO LONG<br \/>\n            return false;<br \/>\n        }<br \/>\n        if (line &#061;&#061; &#034;\\\\n&#034; || line &#061;&#061; &#034;\\\\r\\\\n&#034;)<br \/>\n            break;<\/p>\n<p>        bool ret &#061; ParseHttpHead(line);<br \/>\n        if (ret &#061;&#061; false)<br \/>\n            return false;<\/p>\n<p>    }<br \/>\n    \/\/\u5934\u90e8\u5904\u7406\u5b8c\u6bd5&#xff0c;\u8fdb\u5165\u6b63\u6587\u83b7\u53d6\u9636\u6bb5<br \/>\n    _recv_statu &#061; RECV_HTTP_BODY;<br \/>\n    return true;<br \/>\n} <\/p>\n<h6 id=\"%C2%A0ParseHttpHead\">\u00a0ParseHttpHead<\/h6>\n<p>\u00a0\u89e3\u6790\u4e00\u884c\u5934\u90e8\u5b57\u6bb5<\/p>\n<p>\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u4e0d\u8981\u5fd8\u4e86\u628a\u7ed3\u5c3e\u7684\\\\r\\\\n\u5904\u7406\u6389&#xff0c;\u5426\u5219\u76f4\u63a5substr\u4f1a\u5bfc\u81f4val\u643a\u5e26\\\\r\\\\n\u00a0<\/span><\/li>\n<\/ul>\n<p>bool ParseHttpHead(std::string &amp;line)<br \/>\n{<br \/>\n    \/\/key: val\\\\r\\\\nkey: val\\\\r\\\\n&#8230;.<br \/>\n    if (line.back() &#061;&#061; &#039;\\\\n&#039;) line.pop_back();\/\/\u672b\u5c3e\u662f\u6362\u884c\u5219\u53bb\u6389\u6362\u884c\u5b57\u7b26<br \/>\n    if (line.back() &#061;&#061; &#039;\\\\r&#039;) line.pop_back();\/\/\u672b\u5c3e\u662f\u56de\u8f66\u5219\u53bb\u6389\u56de\u8f66\u5b57\u7b26<br \/>\n    size_t pos &#061; line.find(&#034;: &#034;);<br \/>\n    if (pos &#061;&#061; std::string::npos)<br \/>\n    {<br \/>\n        _recv_statu &#061; RECV_HTTP_ERROR;<br \/>\n        _resp_statu &#061; 400;\/\/<br \/>\n        return false;<br \/>\n    }<br \/>\n    std::string key &#061; line.substr(0, pos);<br \/>\n    std::string val &#061; line.substr(pos &#043; 2);<br \/>\n    _request.SetHeader(key, val);<br \/>\n    return true;<br \/>\n} <\/p>\n<h6 id=\"%C2%A0RecvHttpBody\">\u00a0RecvHttpBody<\/h6>\n<p>\u83b7\u53d6\u8bf7\u6c42\u6b63\u6587<\/p>\n<p>\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5148\u5224\u65ad\u5f53\u524d\u5904\u7406\u72b6\u6001\u662f\u5426\u662fRECV_HTTP_BODY\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6839\u636e\u5df2\u7ecf\u89e3\u6790\u597d\u7684\u5934\u90e8\u5b57\u6bb5\u7684Content-Length\u83b7\u53d6\u6b63\u6587\u957f\u5ea6\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5224\u65ad\u8f93\u5165\u7f13\u51b2\u533a\u53ef\u8bfb\u7a7a\u95f4\u662f\u5426\u8db3\u591f\u6b63\u6587\u957f\u5ea6<\/span>\n<ul>\n<li><span style=\"color:#7b7f82\">Content-Length\u957f\u5ea6\u4e3a0&#xff0c;\u5219\u76f4\u63a5\u4fee\u6539\u5904\u7406\u72b6\u6001\u4e3aRECV_HTTP_OVER&#xff0c;\u8868\u660e\u8bf7\u6c42\u63a5\u6536\u89e3\u6790\u5b8c\u6bd5\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8db3\u591f&#xff0c;\u5219\u8ffd\u52a0\u5230_request\u7684\u6b63\u6587\u5b57\u6bb5\u4e2d&#xff08;\u6ce8\u610f\u662f\u8ffd\u52a0&#xff0c;\u4e0d\u662f\u8d4b\u503c&#xff0c;\u56e0\u4e3a\u8fd9\u53ef\u80fd\u662f\u7b2c\u4e8c\u6b21\u8fdb\u5165RecvHttpBody\u51fd\u6570&#xff09;&#xff0c;\u7136\u540e\u66f4\u6539\u5904\u7406\u72b6\u6001\u4e3aRECV_HTTP_OVER&#xff0c;\u8868\u660e\u8bf7\u6c42\u63a5\u6536\u89e3\u6790\u5b8c\u6bd5\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u4e0d\u8db3&#xff0c;\u5219\u4e5f\u5c06\u7f13\u51b2\u533a\u6570\u636e\u8ffd\u52a0\u5230_request\u7684\u6b63\u6587\u5b57\u6bb5\u4e2d&#xff0c;\u4e0d\u4fee\u6539\u5904\u7406\u72b6\u6001&#xff0c;\u7b49\u5f85\u4e0b\u4e00\u6b21\u7684\u8bfb\u4e8b\u4ef6\u5c31\u7eea\u88ab\u56de\u8c03<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>bool RecvHttpBody(Buffer *buf)<br \/>\n{<br \/>\n    if (_recv_statu !&#061; RECV_HTTP_BODY) return false;<br \/>\n    \/\/1. \u83b7\u53d6\u6b63\u6587\u957f\u5ea6<br \/>\n    size_t content_length &#061; _request.ContentLength();<br \/>\n    if (content_length &#061;&#061; 0)<br \/>\n    {<br \/>\n        \/\/\u6ca1\u6709\u6b63\u6587&#xff0c;\u5219\u8bf7\u6c42\u63a5\u6536\u89e3\u6790\u5b8c\u6bd5<br \/>\n        _recv_statu &#061; RECV_HTTP_OVER;<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/2. \u5f53\u524d\u5df2\u7ecf\u63a5\u6536\u4e86\u591a\u5c11\u6b63\u6587,\u5176\u5b9e\u5c31\u662f\u5f80  _request._body \u4e2d\u653e\u4e86\u591a\u5c11\u6570\u636e\u4e86<br \/>\n    size_t real_len &#061; content_length &#8211; _request._body.size();\/\/\u5b9e\u9645\u8fd8\u9700\u8981\u63a5\u6536\u7684\u6b63\u6587\u957f\u5ea6<br \/>\n    \/\/3. \u63a5\u6536\u6b63\u6587\u653e\u5230body\u4e2d&#xff0c;\u4f46\u662f\u4e5f\u8981\u8003\u8651\u5f53\u524d\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e&#xff0c;\u662f\u5426\u662f\u5168\u90e8\u7684\u6b63\u6587<br \/>\n    \/\/  3.1 \u7f13\u51b2\u533a\u4e2d\u6570\u636e&#xff0c;\u5305\u542b\u4e86\u5f53\u524d\u8bf7\u6c42\u7684\u6240\u6709\u6b63\u6587&#xff0c;\u5219\u53d6\u51fa\u6240\u9700\u7684\u6570\u636e<br \/>\n    if (buf-&gt;ReadAbleSize() &gt;&#061; real_len)<br \/>\n    {<br \/>\n        _request._body.append(buf-&gt;ReadPosition(), real_len);<br \/>\n        buf-&gt;MoveReadPos(real_len);<br \/>\n        _recv_statu &#061; RECV_HTTP_OVER;<br \/>\n        return true;<br \/>\n    }<br \/>\n    \/\/  3.2 \u7f13\u51b2\u533a\u4e2d\u6570\u636e&#xff0c;\u65e0\u6cd5\u6ee1\u8db3\u5f53\u524d\u6b63\u6587\u7684\u9700\u8981&#xff0c;\u6570\u636e\u4e0d\u8db3&#xff0c;\u53d6\u51fa\u6570\u636e&#xff0c;\u7136\u540e\u7b49\u5f85\u65b0\u6570\u636e\u5230\u6765<br \/>\n    _request._body.append(buf-&gt;ReadPosition(), buf-&gt;ReadAbleSize());<br \/>\n    buf-&gt;MoveReadPos(buf-&gt;ReadAbleSize());<br \/>\n    return true;<br \/>\n} <\/p>\n<h6 id=\"%E5%AF%B9%E5%A4%96%E6%8E%A5%E5%8F%A3%C2%A0\">\u5bf9\u5916\u63a5\u53e3\u00a0<\/h6>\n<p>\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u5728\u6784\u9020\u51fd\u6570\u4e2d&#xff0c;\u9ed8\u8ba4\u63a5\u6536\u5904\u7406\u72b6\u6001\u4e3aRECV_HTTP_LINE&#xff0c;\u54cd\u5e94\u72b6\u6001\u7801\u4e3a200<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u72b6\u6001\u91cd\u7f6e\u51fd\u6570&#xff0c;\u91cd\u7f6e\u5904\u7406\u7684\u72b6\u6001<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u83b7\u53d6\u5904\u7406\u72b6\u6001<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u83b7\u53d6\u54cd\u5e94\u72b6\u6001\u7801<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u83b7\u53d6\u53cd\u5e8f\u5217\u5316\u5e76\u586b\u5145\u597d\u5b57\u6bb5\u7684request\u5bf9\u8c61<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u53cd\u5e8f\u5217\u5316\u63a5\u53e3&#xff0c;\u6bcf\u6b21\u90fd\u9700\u8981\u8c03\u7528\u8be5\u63a5\u53e3\u53cd\u5e8f\u5217\u5316\u8bf7\u6c42\u62a5\u6587&#xff0c;\u6309\u987a\u5e8f\u53cd\u5e8f\u5217\u5316<\/span><\/li>\n<\/ul>\n<p>public:<br \/>\n    HttpContext():_resp_statu(200), _recv_statu(RECV_HTTP_LINE) {}<br \/>\n    void ReSet()<br \/>\n    {<br \/>\n        _resp_statu &#061; 200;<br \/>\n        _recv_statu &#061; RECV_HTTP_LINE;<br \/>\n        _request.ReSet();<br \/>\n    }<br \/>\n    int RespStatu() { return _resp_statu; }<br \/>\n    HttpRecvStatu RecvStatu() { return _recv_statu; }<br \/>\n    HttpRequest &amp;Request() { return _request; }<br \/>\n    \/\/\u63a5\u6536\u5e76\u89e3\u6790HTTP\u8bf7\u6c42<br \/>\n    void RecvHttpRequest(Buffer *buf)<br \/>\n    {<br \/>\n        \/\/\u4e0d\u540c\u7684\u72b6\u6001&#xff0c;\u505a\u4e0d\u540c\u7684\u4e8b\u60c5&#xff0c;\u4f46\u662f\u8fd9\u91cc\u4e0d\u8981break&#xff0c; \u56e0\u4e3a\u5904\u7406\u5b8c\u8bf7\u6c42\u884c\u540e&#xff0c;\u5e94\u8be5\u7acb\u5373\u5904\u7406\u5934\u90e8&#xff0c;\u800c\u4e0d\u662f\u9000\u51fa\u7b49\u65b0\u6570\u636e<br \/>\n        switch(_recv_statu)<br \/>\n        {<br \/>\n            case RECV_HTTP_LINE: RecvHttpLine(buf);<br \/>\n            case RECV_HTTP_HEAD: RecvHttpHead(buf);<br \/>\n            case RECV_HTTP_BODY: RecvHttpBody(buf);<br \/>\n        }<br \/>\n        return;<br \/>\n    } <\/p>\n<h5 id=\"%C2%A0HttpServer%E6%A8%A1%E5%9D%97\">\u00a0HttpServer\u6a21\u5757<\/h5>\n<p><span style=\"color:#7b7f82\">HTTPServer\u6a21\u5757\u3002<\/span><\/p>\n<p><span style=\"color:null\">\u529f\u80fd<\/span><span style=\"color:#7b7f82\">&#xff1a;\u5bf9HTTP\u534f\u8bae\u6a21\u5757\u7684\u6574\u5408&#xff0c;\u5b9e\u73b0HTTP\u670d\u52a1\u5668\u7684\u642d\u5efa\u3002<\/span><\/p>\n<p><span style=\"color:null\">\u610f\u4e49&#xff1a;<\/span><span style=\"color:#7b7f82\">\u4f7f\u7528\u6237\u5bf9HTTP\u670d\u52a1\u5668\u7684\u642d\u5efa\u66f4\u52a0\u7684\u65b9\u4fbf\u7b80\u6377\u3002<\/span><\/p>\n<p>\u8bbe\u8ba1&#xff1a;<span style=\"color:#7b7f82\">\u6211\u4eec\u7ef4\u62a4\u591a\u5f20\u8868&#xff0c;\u8868\u4e2d\u8bb0\u5f55\u4e86\u9488\u5bf9\u54ea\u4e2a\u8bf7\u6c42&#xff0c;\u5e94\u8be5\u8c03\u7528\u54ea\u4e2a\u56de\u8c03\u51fd\u6570\u6765\u8fdb\u884c\u4e1a\u52a1\u5904\u7406\u7684\u6620\u5c04\u5173\u7cfb\u3002\u5982\u679c\u7528\u6237\u4f7f\u7528\u7684\u662fGET\u65b9\u6cd5&#xff0c;\u5219\u540e\u7aef\u4f1a\u5728GET\u8868\u4e2d\u641c\u7d22\u7528\u6237\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u6240\u9700\u8981\u8c03\u7528\u7684\u56de\u8c03\u51fd\u6570&#xff0c;\u5e76\u5c06\u7528\u6237\u7684HTTP\u8bf7\u6c42\u4e2d\u7684\u641c\u7d22\u5173\u952e\u5b57\u4f20\u5165\u8fdb\u53bb&#xff0c;\u662f\u4e00\u79cd\u52a8\u6001\u8d44\u6e90\u7684\u83b7\u53d6\u3002\u8868\u7684\u529f\u80fd\u5982\u540c\u8def\u7531\u5668\u8868\u529f\u80fd\u4e00\u6837&#xff0c;\u6545\u4e3a\u8def\u7531\u8868\u3002<\/span><\/p>\n<p><span style=\"color:#7b7f82\">\u4ec0\u4e48\u8bf7\u6c42&#xff0c;\u600e\u4e48\u5904\u7406&#xff0c;\u7531\u7528\u6237\u6765\u51b3\u5b9a&#xff0c;\u6240\u4ee5\u8fd9\u51e0\u5f20\u8868\u662f\u7528\u6237\u6765\u586b\u5145\u7684\u3002\u8fd9\u6837\u505a\u7684\u597d\u5904\u5c31\u662f\u7528\u6237\u53ea\u9700\u8981\u5b9e\u73b0\u4e1a\u52a1\u5904\u7406\u51fd\u6570&#xff0c;\u7136\u540e\u5c06\u8bf7\u6c42\u4e0e\u5904\u7406\u51fd\u6570\u7684\u6620\u5c04\u5173\u7cfb&#xff0c;\u6dfb\u52a0\u5230\u670d\u52a1\u5668\u4e2d\u3002\u90a3\u4e48\u670d\u52a1\u5668\u53ea\u9700\u8981\u63a5\u53d7\u6570\u636e&#xff0c;\u8c03\u7528\u4e1a\u52a1\u56de\u8c03\u51fd\u6570&#xff0c;\u89e3\u6790\u6570\u636e&#xff0c;\u67e5\u627e\u8def\u7531\u8868\u6620\u5c04\u5173\u7cfb&#xff0c;\u6267\u884c\u4e1a\u52a1\u5904\u7406\u51fd\u6570\u3002<\/span><\/p>\n<p><span style=\"color:null\">\u6210\u5458<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">GET\u8bf7\u6c42\u7684\u8def\u7531\u6620\u5c04\u8868<\/span><\/li>\n<li><span style=\"color:#7b7f82\">POST\u8bf7\u6c42\u7684\u8def\u7531\u6620\u5c04\u8868<\/span><\/li>\n<li><span style=\"color:#7b7f82\">PUT\u8bf7\u6c42\u7684\u8def\u7531\u6620\u5c04\u8868<\/span><\/li>\n<li><span style=\"color:#7b7f82\">DELETE\u8bf7\u6c42\u7684\u8def\u7531\u00a0<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u9759\u6001\u8d44\u6e90\u76f8\u5bf9\u6839\u76ee\u5f55<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u9ad8\u6027\u80fdTCP\u670d\u52a1\u5668 &#8212; \u8fdb\u884c\u8fde\u63a5\u7684IO\u64cd\u4f5c<\/span><\/li>\n<\/ul>\n<p>\u63a5\u53e3&#xff1a;<\/p>\n<p>public&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u6dfb\u52a0\u8bf7\u6c42\u4e0e\u5904\u7406\u51fd\u6570\u7684\u6620\u5c04\u4fe1\u606f<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bbe\u7f6e\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bbe\u7f6e\u662f\u5426\u542f\u52a8\u8d85\u65f6\u8fde\u63a5\u5173\u95ed<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bbe\u7f6e\u4ece\u5c5eReactor\u7ebf\u7a0b\u6570\u91cf<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u542f\u52a8\u670d\u52a1\u5668<\/span><\/li>\n<\/ul>\n<p>private&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">OnConnected&#xff0c;\u7ed9TcpServer\u8bbe\u7f6e\u4e0a\u4e0b\u6587&#xff08;\u4e00\u4e2aHTTPContext\u5bf9\u8c61&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">OnMessage&#xff0c;\u4e1a\u52a1\u5904\u7406\u51fd\u6570&#xff0c;\u8bfb\u53d6\u7f13\u51b2\u533a\u6570\u636e\u3001\u53cd\u5e8f\u5217\u5316\u3001\u8def\u7531\u3001\u54cd\u5e94\u3001\u91cd\u7f6e\u4e0a\u4e0b\u6587\u3001\u5173\u95ed\u77ed\u8fde\u63a5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">Route&#xff0c;\u8bf7\u6c42\u7684\u8def\u7531\u67e5\u627e\u3002\u5224\u65ad\u5ba2\u6237\u7aef\u8bf7\u6c42\u7684\u662f\u9759\u6001\u8d44\u6e90\u8fd8\u662f\u529f\u80fd\u6027\u8bf7\u6c42<\/span><\/li>\n<li><span style=\"color:#7b7f82\">FileHandler&#xff0c;\u9759\u6001\u8d44\u6e90\u7684\u8bf7\u6c42\u5904\u7406<\/span><\/li>\n<li><span style=\"color:#7b7f82\">Dispatcher&#xff0c;\u529f\u80fd\u6027\u8bf7\u6c42\u7684\u5206\u7c7b\u5904\u7406<\/span><\/li>\n<li><span style=\"color:#7b7f82\">WriteReponse&#xff0c;\u7ec4\u7ec7HTTP\u54cd\u5e94\u62a5\u6587&#xff0c;\u5e76\u8c03\u7528Send\u53d1\u9001\u81f3\u53d1\u9001\u7f13\u51b2\u533a<\/span><\/li>\n<\/ul>\n<p>\u603b\u89c8\u63a5\u53e3\u00a0<\/p>\n<p>class HttpServer<br \/>\n{<br \/>\nprivate:<br \/>\n    using Handler &#061; std::function&lt;void(const HttpRequest &amp;, HttpResponse *)&gt;;<br \/>\n    using Handlers &#061; std::vector&lt;std::pair&lt;std::regex, Handler&gt;&gt;;<br \/>\n    Handlers _get_route;<br \/>\n    Handlers _post_route;<br \/>\n    Handlers _put_route;<br \/>\n    Handlers _delete_route;<br \/>\n    std::string _basedir; \/\/\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<br \/>\n    TcpServer _server;<br \/>\nprivate:<br \/>\n    void ErrorHandler(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n    {}<br \/>\n    \/\/\u5c06HttpResponse\u4e2d\u7684\u8981\u7d20\u6309\u7167http\u534f\u8bae\u683c\u5f0f\u8fdb\u884c\u7ec4\u7ec7&#xff0c;\u53d1\u9001<br \/>\n    void WriteReponse(const std::shared_ptr&lt;Connection&gt; &amp;conn, const HttpRequest &amp;req, HttpResponse &amp;rsp)<br \/>\n    {}<br \/>\n    bool IsFileHandler(const HttpRequest &amp;req)<br \/>\n    {}<br \/>\n    \/\/ \u9759\u6001\u8d44\u6e90\u7684\u8bf7\u6c42\u5904\u7406 &#8212; \u5c06\u9759\u6001\u8d44\u6e90\u6587\u4ef6\u7684\u6570\u636e\u8bfb\u53d6\u51fa\u6765&#xff0c;\u653e\u5230rsp\u7684_body\u4e2d, \u5e76\u8bbe\u7f6emime<br \/>\n    void FileHandler(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n    {}<br \/>\n    \/\/\u529f\u80fd\u6027\u8bf7\u6c42\u7684\u5206\u7c7b\u5904\u7406<br \/>\n    void Dispatcher(HttpRequest &amp;req, HttpResponse *rsp, Handlers &amp;handlers)<br \/>\n    {}<br \/>\n    void Route(HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n    {}<br \/>\n    \/\/\u8bbe\u7f6e\u4e0a\u4e0b\u6587<br \/>\n    void OnConnected(const std::shared_ptr&lt;Connection&gt; &amp;conn)<br \/>\n    {}<br \/>\n    \/\/\u7f13\u51b2\u533a\u6570\u636e\u89e3\u6790&#043;\u5904\u7406<br \/>\n    void OnMessage(const std::shared_ptr&lt;Connection&gt; &amp;conn, Buffer *buffer)<br \/>\n    {}<br \/>\npublic:<br \/>\n    HttpServer(int port, int timeout &#061; DEFALT_TIMEOUT):_server(port)<br \/>\n    {}<br \/>\n    void SetBaseDir(const std::string &amp;path)<br \/>\n    {}<br \/>\n    \/*\u8bbe\u7f6e\/\u6dfb\u52a0&#xff0c;\u8bf7\u6c42&#xff08;\u8bf7\u6c42\u7684\u6b63\u5219\u8868\u8fbe&#xff09;\u4e0e\u5904\u7406\u51fd\u6570\u7684\u6620\u5c04\u5173\u7cfb*\/<br \/>\n    void Get(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {}<br \/>\n    void Post(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {}<br \/>\n    void Put(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {}<br \/>\n    void Delete(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {}<br \/>\n    void SetThreadCount(int count)<br \/>\n    {}<br \/>\n    void Listen()<br \/>\n    {}<br \/>\n}; <\/p>\n<p>\u00a0\u5927\u81f4\u6d41\u7a0b<\/p>\n<li><span style=\"color:#7b7f82\">\u542f\u52a8\u670d\u52a1\u5668&#xff0c;\u670d\u52a1\u5668\u521b\u5efaEventLoop\u5bf9\u8c61\u3001Acceptor\u5bf9\u8c61\u5e76\u8c03\u7528Acceptor\u5185\u90e8\u7684baseloop\u7684Start\u51fd\u6570&#xff0c;\u5f00\u542fAcceptor\u4e2d\u5bf9Listen\u8bfb\u4e8b\u4ef6\u7684\u4e8b\u4ef6\u76d1\u63a7\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u521b\u5efa\u4f20\u5165\u7684Count\u6570\u91cf\u7684\u4ece\u5c5e\u7ebf\u7a0b&#xff08;\u4f8b\u5982\u662f\u4e09\u4e2a&#xff09;\u4e09\u4e2a\u7ebf\u7a0b\u5185\u90e8\u5b9e\u4f8b\u5316\u5404\u81ea\u7684EventLoop&#xff0c;\u5e76\u5728\u7ebf\u7a0b\u7684\u4f8b\u7a0b\u4e2d\u8c03\u7528Start\u51fd\u6570&#xff0c;\u7b49\u5f85epoll\u76d1\u63a7\u7684\u4e8b\u4ef6\u5c31\u7eea&#xff0c;\u5c31\u7eea\u540e\u5c31\u8c03\u7528\u5c31\u7eea\u4e8b\u4ef6\u7684\u56de\u8c03\u51fd\u6570&#xff08;Channel\u6a21\u5757\u4e2d\u7684HandlerEvent\u4e8b\u4ef6\u5206\u914d\u5668&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u4e00\u65e6\u6709\u65b0\u8fde\u63a5\u5c31\u7eea\u5219\u8c03\u7528Listen\u7684\u8bfb\u56de\u8c03\u51fd\u6570&#xff0c;accept\u65b0\u8fde\u63a5&#xff0c;\u4e3a\u65b0\u8fde\u63a5new\u4e00\u4e2aConnection\u5bf9\u8c61&#xff0c;\u5e76\u5bf9Connection\u5bf9\u8c61\u8bbe\u7f6e\u8bfb\u3001\u5199\u3001\u9519\u8bef\u3001\u5173\u95ed\u3001\u4efb\u610f\u4e8b\u4ef6\u56de\u8c03&#xff0c;\u4ee5\u53ca\u4e0a\u5c42\u8bbe\u7f6e\u7684\u9636\u6bb5\u56de\u8c03OnConnected\u3001OnMessage\u3001OnClosed\u3001AnyEvent\u3001SvrClosed\u56de\u8c03\u51fd\u6570&#xff0c;\u7136\u540e\u6dfb\u52a0\u8be5\u8fde\u63a5\u7684\u8bfb\u76d1\u63a7\u5230\u76f8\u5e94\u7684\u7ebf\u7a0b\u4e2d\u7684EventLoop\u5bf9\u8c61\u7684epoll\u4e2d\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8fde\u63a5\u7684\u8bfb\u4e8b\u4ef6\u5c31\u7eea\u5219\u8c03\u7528Connection\u4e2d\u8bbe\u7f6e\u7684\u8bfb\u56de\u8c03\u51fd\u6570&#xff0c;\u5c06\u8be5\u8fde\u63a5\u7684TCP\u63a5\u6536\u7f13\u51b2\u533a\u6570\u636e\u62f7\u8d1d\u5230\u6211\u4eec\u7684\u8f93\u5165\u7f13\u51b2\u533ainbuffer\u4e2d&#xff0c;\u7136\u540e\u8c03\u7528\u4e0a\u5c42\u8bbe\u7f6e\u7684\u4e1a\u52a1\u5904\u7406\u51fd\u6570OnMessage&#xff0c;\u5bf9\u6570\u636e\u8fdb\u884c\u4e1a\u52a1\u5904\u7406<\/span><\/li>\n<li><span style=\"color:#7b7f82\">OnMessage\u5bf9\u8bf7\u6c42\u8fdb\u884c\u89e3\u6790&#xff0c;\u53cd\u5e8f\u5217\u5316\u540e\u5c06\u4fe1\u606f\u586b\u5145\u5230HTTPRequest\u7684request\u5bf9\u8c61\u4e2d<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5bf9\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u8fdb\u884c\u8def\u7531\u67e5\u627e&#xff0c;\u627e\u5230\u5bf9\u5e94\u7684\u5904\u7406\u65b9\u6cd5&#xff08;\u9759\u6001\u8d44\u6e90\u8bf7\u6c42\u6216\u662f\u529f\u80fd\u6027\u8bf7\u6c42&#xff09;<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5bf9\u8bf7\u6c42\u8fdb\u884c\u5904\u7406&#xff0c;\u5e76\u586b\u5145\u4e00\u4e2aHTTPResponse\u7684response\u5bf9\u8c61&#xff0c;\u6839\u636eresponse\u7684\u4fe1\u606f\u6784\u5efa\u4e00\u4e2aHTTP\u54cd\u5e94\u62a5\u6587&#xff0c;\u5199\u5165\u5230\u6211\u4eec\u7684\u53d1\u9001\u7f13\u51b2\u533aoutbuffer&#xff0c;\u5f00\u542f\u8fde\u63a5\u7684\u5199\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u4e00\u65e6\u5199\u4e8b\u4ef6\u5c31\u7eea&#xff0c;\u5219\u5c06\u6211\u4eec\u7684\u53d1\u9001\u7f13\u51b2\u533a\u6570\u636e\u5199\u5165\u5230TCP\u7684\u53d1\u9001\u7f13\u51b2\u533a&#xff0c;\u5982\u679c\u6570\u636e\u53d1\u9001\u5b8c\u6bd5\u5219\u5173\u95ed\u8be5\u8fde\u63a5\u7684\u5199\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u5982\u679c\u6ca1\u6709\u5199\u5b8c&#xff0c;\u5219\u7ee7\u7eed\u76d1\u63a7\u5199\u4e8b\u4ef6<\/span><\/li>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"524\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054559-6805db9780c0a.png\" width=\"1248\" \/><\/p>\n<p>\u5b9e\u73b0<\/p>\n<h6 id=\"OnConnected\">OnConnected<\/h6>\n<p>\/\/\u8bbe\u7f6e\u4e0a\u4e0b\u6587<br \/>\nvoid OnConnected(const std::shared_ptr&lt;Connection&gt; &amp;conn)<br \/>\n{<br \/>\n    conn-&gt;SetContext(HttpContext());<br \/>\n    DBG_LOG(&#034;NEW CONNECTION %p&#034;, conn.get());<br \/>\n} <\/p>\n<p>\u529f\u80fd&#xff1a;<\/p>\n<p><span style=\"color:#7b7f82\">\u5728Acceptor\u4e2d&#xff0c;\u5982\u679cListen\u7684\u8bfb\u4e8b\u4ef6\u5c31\u7eea&#xff0c;\u5219\u4f1a\u83b7\u53d6\u65b0\u8fde\u63a5&#xff0c;\u5e76\u4e3a\u65b0\u8fde\u63a5new\u4e00\u4e2aConnection\u5bf9\u8c61&#xff0c;\u4e3a\u8fde\u63a5\u8fdb\u884c\u5404\u79cd\u56de\u8c03\u51fd\u6570\u8bbe\u7f6e&#xff0c;\u6700\u540e\u8c03\u7528\u8fde\u63a5\u7684Established\u51fd\u6570&#xff0c;\u542f\u52a8\u8be5\u8fde\u63a5\u7684\u8bfb\u4e8b\u4ef6\u76d1\u63a7&#xff0c;\u5e76\u8c03\u7528\u4e0a\u5c42\u8bbe\u7f6e\u7684\u8fde\u63a5\u5efa\u7acb\u65f6\u7684\u56de\u8c03\u51fd\u6570_conn_cb&#xff0c;\u6b64\u65f6\u5c31\u4f1a\u6267\u884c\u6211\u4eec\u7684OnConnected\u51fd\u6570&#xff0c;\u4e3a\u8be5\u8fde\u63a5\u8bbe\u7f6e\u4e00\u4e2a\u4e0a\u4e0b\u6587&#xff0c;\u6211\u4eec\u8fd9\u91cc\u9002\u914d\u7684\u662fHTTP\u534f\u8bae\u4e0a\u4e0b\u6587&#xff0c;\u5982\u679c\u662f\u5176\u4ed6\u534f\u8bae&#xff0c;\u5219\u8d4b\u503c\u5176\u4ed6\u534f\u8bae\u4e0a\u4e0b\u6587\u5bf9\u8c61\u5373\u53ef&#xff0c;\u5728Connection\u7c7b\u4e2d\u6211\u4eec\u4f7f\u7528\u7684\u662fAny\u7c7b\u5bf9\u8c61\u63a5\u6536context&#xff0c;\u65e0\u754f\u7c7b\u578b<\/span><\/p>\n<h6 id=\"OnMessage%C2%A0%C2%A0\">OnMessage\u00a0\u00a0<\/h6>\n<p>\/\/\u7f13\u51b2\u533a\u6570\u636e\u89e3\u6790&#043;\u5904\u7406<br \/>\nvoid OnMessage(const std::shared_ptr&lt;Connection&gt; &amp;conn, Buffer *buffer)<br \/>\n{<br \/>\n    while(buffer-&gt;ReadAbleSize() &gt; 0)<br \/>\n    {<br \/>\n        \/\/1. \u83b7\u53d6\u4e0a\u4e0b\u6587<br \/>\n        HttpContext *context &#061; conn-&gt;GetContext()-&gt;get&lt;HttpContext&gt;();<br \/>\n        \/\/2. \u901a\u8fc7\u4e0a\u4e0b\u6587\u5bf9\u7f13\u51b2\u533a\u6570\u636e\u8fdb\u884c\u89e3\u6790&#xff0c;\u5f97\u5230HttpRequest\u5bf9\u8c61<br \/>\n        \/\/  1. \u5982\u679c\u7f13\u51b2\u533a\u7684\u6570\u636e\u89e3\u6790\u51fa\u9519&#xff0c;\u5c31\u76f4\u63a5\u56de\u590d\u51fa\u9519\u54cd\u5e94<br \/>\n        \/\/  2. \u5982\u679c\u89e3\u6790\u6b63\u5e38&#xff0c;\u4e14\u8bf7\u6c42\u5df2\u7ecf\u83b7\u53d6\u5b8c\u6bd5&#xff0c;\u624d\u5f00\u59cb\u53bb\u8fdb\u884c\u5904\u7406<br \/>\n        context-&gt;RecvHttpRequest(buffer);<br \/>\n        HttpRequest &amp;req &#061; context-&gt;Request();<br \/>\n        HttpResponse rsp(context-&gt;RespStatu());<br \/>\n        if (context-&gt;RespStatu() &gt;&#061; 400)<br \/>\n        {<br \/>\n            \/\/\u8fdb\u884c\u9519\u8bef\u54cd\u5e94&#xff0c;\u5173\u95ed\u8fde\u63a5<br \/>\n            ErrorHandler(req, &amp;rsp);\/\/\u586b\u5145\u4e00\u4e2a\u9519\u8bef\u663e\u793a\u9875\u9762\u6570\u636e\u5230rsp\u4e2d<br \/>\n            WriteReponse(conn, req, rsp);\/\/\u7ec4\u7ec7\u54cd\u5e94\u53d1\u9001\u7ed9\u5ba2\u6237\u7aef<br \/>\n            context-&gt;ReSet();<br \/>\n            buffer-&gt;MoveReadPos(buffer-&gt;ReadAbleSize());\/\/\u51fa\u9519\u4e86\u5c31\u628a\u7f13\u51b2\u533a\u6570\u636e\u6e05\u7a7a<br \/>\n            conn-&gt;Shutdown();\/\/\u5173\u95ed\u8fde\u63a5<br \/>\n            return;<br \/>\n        }<br \/>\n        if (context-&gt;RecvStatu() !&#061; RECV_HTTP_OVER)<br \/>\n        {<br \/>\n            \/\/\u5f53\u524d\u8bf7\u6c42\u8fd8\u6ca1\u6709\u63a5\u6536\u5b8c\u6574,\u5219\u9000\u51fa&#xff0c;\u7b49\u65b0\u6570\u636e\u5230\u6765\u518d\u91cd\u65b0\u7ee7\u7eed\u5904\u7406<br \/>\n            return;<br \/>\n        }<br \/>\n        \/\/3. \u8bf7\u6c42\u8def\u7531 &#043; \u4e1a\u52a1\u5904\u7406<br \/>\n        Route(req, &amp;rsp);<br \/>\n        \/\/4. \u5bf9HttpResponse\u8fdb\u884c\u7ec4\u7ec7\u53d1\u9001<br \/>\n        WriteReponse(conn, req, rsp);<br \/>\n        \/\/5. \u91cd\u7f6e\u4e0a\u4e0b\u6587<br \/>\n        context-&gt;ReSet();<br \/>\n        \/\/6. \u6839\u636e\u957f\u77ed\u8fde\u63a5\u5224\u65ad\u662f\u5426\u5173\u95ed\u8fde\u63a5\u6216\u8005\u7ee7\u7eed\u5904\u7406<br \/>\n        if (rsp.Close() &#061;&#061; true) conn-&gt;Shutdown();\/\/\u77ed\u94fe\u63a5\u5219\u76f4\u63a5\u5173\u95ed<br \/>\n    }<br \/>\n    return;<br \/>\n} <\/p>\n<p>\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<li><span style=\"color:#7b7f82\">\u5faa\u73af\u5904\u7406&#xff0c;\u76f4\u81f3\u7f13\u51b2\u533a\u4e3a\u7a7a&#xff0c;\u56e0\u4e3ainbuffer\u63a5\u6536\u7f13\u51b2\u533a\u53ef\u80fd\u4e0d\u6b62\u4e00\u4e2aHTTP\u8bf7\u6c42\u62a5\u6587\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u83b7\u53d6\u8be5\u8fde\u63a5\u7684\u4e0a\u4e0b\u6587\u5bf9\u8c61&#xff0c;\u5982\u679c\u662f\u7b2c\u4e00\u4e2a\u8c03\u7528OnMessage\u5219\u4e0a\u4e0b\u6587\u5bf9\u8c61\u7684\u6210\u5458\u9ed8\u8ba4\u5904\u7406\u72b6\u6001\u5c31\u662fRECV_HTTP_LINE\u3002\u5982\u679c\u4e0d\u662f\u7b2c\u4e00\u6b21\u8c03\u7528OnMessage\u51fd\u6570&#xff0c;\u5219\u9700\u8981\u6839\u636e\u4e0a\u4e00\u6b21\u5904\u7406\u7ed3\u679c\u7684\u72b6\u6001&#xff0c;\u7ee7\u7eed\u5904\u7406&#xff0c;\u6240\u4ee5\u9700\u8981\u83b7\u53d6\u4e0a\u4e0b\u6587\u6570\u636e&#xff0c;\u4ee5\u660e\u786eHTTP\u8bf7\u6c42\u62a5\u6587\u5904\u7406\u5230\u54ea\u4e2a\u8fdb\u5ea6\u4e86\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u53cd\u5e8f\u5217\u5316HTTP\u8bf7\u6c42\u62a5\u6587&#xff0c;\u586b\u5145HTTPRequest\u7c7b\u5bf9\u8c61request&#xff0c;\u5e76\u83b7\u53d6request\u5bf9\u8c61\u3002\u5982\u679c\u53cd\u5e8f\u5217\u5316\u540e\u7684\u54cd\u5e94\u72b6\u6001\u7801\u4e0d\u4e3a200&#xff0c;\u5219\u8868\u660e\u89e3\u6790\u51fa\u9519&#xff0c;\u5bf9\u7528\u6237\u54cd\u5e94\u4e00\u4e2a\u9519\u8bef\u9875\u9762\u5373\u53ef&#xff0c;\u5e76\u91cd\u7f6e\u4e0a\u4e0b\u6587\u7684\u72b6\u6001&#xff0c;\u4e0d\u7136\u4e0b\u4e00\u6b21\u8be5\u8fde\u63a5\u6570\u636e\u518d\u6b21\u5230\u6765\u65f6&#xff0c;\u8fd8\u4f1a\u83b7\u53d6\u5230\u4e0a\u4e00\u6b21\u7684\u54cd\u5e94\u72b6\u6001\u7801&#xff0c;\u5373\u4f7f\u6ca1\u6709\u53cd\u5e8f\u5217\u5316\u51fa\u9519&#xff0c;\u4f46\u662f\u72b6\u6001\u7801\u4f9d\u65e7\u662f\u4e0a\u6b21\u6b8b\u7559\u72b6\u6001\u3002\u6700\u540e\u6e05\u7a7a\u7f13\u51b2\u533a\u6570\u636e&#xff0c;\u56e0\u4e3aHTTP\u8bf7\u6c42\u5df2\u7ecf\u89e3\u6790\u51fa\u9519\u4e86&#xff0c;\u540e\u9762\u7684\u89e3\u6790\u4e5f\u4e0d\u53ef\u80fd\u5bf9&#xff0c;\u6ca1\u5fc5\u8981\u518d\u5f80\u540e\u6267\u884c\u4e86&#xff0c;\u7136\u540e\u91ca\u653e\u5173\u95ed\u8fde\u63a5\u3002<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u54cd\u5e94\u72b6\u6001\u7801\u4e3a200&#xff0c;\u4f46\u662f\u63a5\u6536\u5904\u7406\u72b6\u6001\u4e0d\u662fRECV_HTTP_OVER&#xff0c;\u8868\u660e\u5f53\u524d\u8bf7\u6c42\u8fd8\u6ca1\u6709\u63a5\u6536\u5b8c\u6574&#xff0c;\u7b49\u65b0\u6570\u636e\u5230\u6765\u518d\u91cd\u65b0\u7ee7\u7eed\u5904\u7406&#xff0c;\u6240\u4ee5return<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u54cd\u5e94\u72b6\u6001\u7801\u4e3a200&#xff0c;\u63a5\u53d7\u5904\u7406\u72b6\u6001\u4e3aRECV_HTTP_OVER&#xff0c;\u8868\u660eHTTP\u8bf7\u6c42\u5904\u7406\u6210\u529f&#xff0c;\u8c03\u7528Route\u8fdb\u884c\u8d44\u6e90\u83b7\u53d6&#xff0c;\u586b\u5145HTTPResponse\u5bf9\u8c61rsp<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u6839\u636ersp\u6784\u5efaHTTP\u54cd\u5e94\u62a5\u6587&#xff0c;\u5199\u5165Connection\u7684\u53d1\u9001\u7f13\u51b2\u533a<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u5982\u679c\u8bf7\u6c42\u62a5\u6587\u4e2dConnection\u5bf9\u5e94\u952e\u503c\u4e3aclose&#xff0c;\u5219\u8868\u660e\u672c\u6b21\u8fde\u63a5\u4e3a\u77ed\u8fde\u63a5&#xff0c;\u54cd\u5e94\u6570\u636e\u540e\u76f4\u63a5\u91ca\u653e\u8fde\u63a5&#xff0c;\u5426\u5219&#xff0c;\u5982\u679c\u4e3akeep-alive\u5219\u4e3a\u957f\u8fde\u63a5&#xff0c;\u7ee7\u7eed\u5904\u7406\u8bf7\u6c42<\/span><\/li>\n<h6 id=\"Route\">Route<\/h6>\n<p><span style=\"color:#7b7f82\">\u00a0\u8fdb\u884c\u8bf7\u6c42\u7684\u5206\u8fa8&#xff0c;\u6839\u636e\u662f\u4e00\u4e2a\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u8fd8\u662f\u4e00\u4e2a\u529f\u80fd\u6027\u8bf7\u6c42\u5206\u7c7b\u5904\u7406<\/span><\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u5219\u8fdb\u884c\u9759\u6001\u8d44\u6e90\u7684\u5904\u7406&#xff0c;\u7136\u540e\u8fd4\u56de<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u529f\u80fd\u6027\u8bf7\u6c42&#xff0c;\u5219\u9700\u8981\u901a\u8fc7\u51e0\u4e2a\u8bf7\u6c42\u8def\u7531\u8868\u6765\u786e\u5b9a\u662f\u5426\u6709\u5904\u7406\u51fd\u6570<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u65e2\u4e0d\u662f\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u4e5f\u6ca1\u6709\u8bbe\u7f6e\u5bf9\u5e94\u7684\u529f\u80fd\u6027\u8bf7\u6c42\u5904\u7406\u51fd\u6570&#xff0c;\u5c31\u8fd4\u56de405<\/span><\/li>\n<\/ul>\n<p>void Route(HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n{<br \/>\n    \/\/1. \u5bf9\u8bf7\u6c42\u8fdb\u884c\u5206\u8fa8&#xff0c;\u662f\u4e00\u4e2a\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u8fd8\u662f\u4e00\u4e2a\u529f\u80fd\u6027\u8bf7\u6c42<br \/>\n    \/\/   \u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u5219\u8fdb\u884c\u9759\u6001\u8d44\u6e90\u7684\u5904\u7406<br \/>\n    \/\/   \u529f\u80fd\u6027\u8bf7\u6c42&#xff0c;\u5219\u9700\u8981\u901a\u8fc7\u51e0\u4e2a\u8bf7\u6c42\u8def\u7531\u8868\u6765\u786e\u5b9a\u662f\u5426\u6709\u5904\u7406\u51fd\u6570<br \/>\n    \/\/   \u65e2\u4e0d\u662f\u9759\u6001\u8d44\u6e90\u8bf7\u6c42&#xff0c;\u4e5f\u6ca1\u6709\u8bbe\u7f6e\u5bf9\u5e94\u7684\u529f\u80fd\u6027\u8bf7\u6c42\u5904\u7406\u51fd\u6570&#xff0c;\u5c31\u8fd4\u56de405<br \/>\n    if (IsFileHandler(req) &#061;&#061; true)<br \/>\n        \/\/\u662f\u4e00\u4e2a\u9759\u6001\u8d44\u6e90\u8bf7\u6c42, \u5219\u8fdb\u884c\u9759\u6001\u8d44\u6e90\u8bf7\u6c42\u7684\u5904\u7406<br \/>\n        return FileHandler(req, rsp);<\/p>\n<p>    if (req._method &#061;&#061; &#034;GET&#034; || req._method &#061;&#061; &#034;HEAD&#034;)<br \/>\n    {<br \/>\n        return Dispatcher(req, rsp, _get_route);<br \/>\n    }<br \/>\n    else if (req._method &#061;&#061; &#034;POST&#034;)<br \/>\n    {<br \/>\n        return Dispatcher(req, rsp, _post_route);<br \/>\n    }<br \/>\n    else if (req._method &#061;&#061; &#034;PUT&#034;)<br \/>\n    {<br \/>\n        return Dispatcher(req, rsp, _put_route);<br \/>\n    }<br \/>\n    else if (req._method &#061;&#061; &#034;DELETE&#034;)<br \/>\n    {<br \/>\n        return Dispatcher(req, rsp, _delete_route);<br \/>\n    }<br \/>\n    rsp-&gt;_statu &#061; 405;\/\/ Method Not Allowed<br \/>\n    return ;<br \/>\n} <\/p>\n<h6 id=\"IsFileHandler\">IsFileHandler<\/h6>\n<p><span style=\"color:null\">\u8be5\u8bf7\u6c42\u662f\u5426\u8bf7\u6c42\u7684\u9759\u6001\u8d44\u6e90&#xff0c;\u6211\u4eec\u6709\u4ee5\u4e0b\u51e0\u70b9\u5224\u65ad<\/span><\/p>\n<li><span style=\"color:#7b7f82\">\u4e0a\u5c42\u7528\u6237\u5fc5\u987b\u8bbe\u7f6e\u4e86\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u00a0\u5ba2\u6237\u7aef\u7684\u8bf7\u6c42\u65b9\u6cd5\u5fc5\u987b\u662fGET\u6216HEAD\u65b9\u6cd5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u5fc5\u987b\u5408\u6cd5<\/span><\/li>\n<li><span style=\"color:#7b7f82\">\u8bf7\u6c42\u7684\u8d44\u6e90\u5fc5\u987b\u5b58\u5728&#xff0c;\u5e76\u4e14\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6<\/span><\/li>\n<p>bool IsFileHandler(const HttpRequest &amp;req)<br \/>\n{<br \/>\n    \/\/ 1. \u5fc5\u987b\u8bbe\u7f6e\u4e86\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<br \/>\n    if (_basedir.empty())<br \/>\n        return false;<\/p>\n<p>    \/\/ 2. \u8bf7\u6c42\u65b9\u6cd5&#xff0c;\u5fc5\u987b\u662fGET \/ HEAD\u8bf7\u6c42\u65b9\u6cd5<br \/>\n    if (req._method !&#061; &#034;GET&#034; &amp;&amp; req._method !&#061; &#034;HEAD&#034;)<br \/>\n        return false;<\/p>\n<p>    \/\/ 3. \u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u5fc5\u987b\u662f\u4e00\u4e2a\u5408\u6cd5\u8def\u5f84<br \/>\n    if (Util::ValidPath(req._path) &#061;&#061; false)<br \/>\n        return false;<\/p>\n<p>    \/\/ 4. \u8bf7\u6c42\u7684\u8d44\u6e90\u5fc5\u987b\u5b58\u5728,\u4e14\u662f\u4e00\u4e2a\u666e\u901a\u6587\u4ef6<br \/>\n    \/\/    \u6709\u4e00\u79cd\u8bf7\u6c42\u6bd4\u8f83\u7279\u6b8a &#8212; \u76ee\u5f55&#xff1a;\/, \/image\/&#xff0c; \u8fd9\u79cd\u60c5\u51b5\u7ed9\u540e\u8fb9\u9ed8\u8ba4\u8ffd\u52a0\u4e00\u4e2a index.html<br \/>\n    \/\/ index.html    \/image\/a.png<br \/>\n    \/\/ \u4e0d\u8981\u5fd8\u4e86\u524d\u7f00\u7684\u76f8\u5bf9\u6839\u76ee\u5f55,\u4e5f\u5c31\u662f\u5c06\u8bf7\u6c42\u8def\u5f84\u8f6c\u6362\u4e3a\u5b9e\u9645\u5b58\u5728\u7684\u8def\u5f84  \/image\/a.png  -&gt;   .\/wwwroot\/image\/a.png<br \/>\n    std::string req_path &#061; _basedir &#043; req._path;\/\/\u4e3a\u4e86\u907f\u514d\u76f4\u63a5\u4fee\u6539\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84&#xff0c;\u56e0\u6b64\u5b9a\u4e49\u4e00\u4e2a\u4e34\u65f6\u5bf9\u8c61<br \/>\n    if (req._path.back() &#061;&#061; &#039;\/&#039;)<br \/>\n        req_path &#043;&#061; &#034;index.html&#034;;<\/p>\n<p>    if (Util::IsRegular(req_path) &#061;&#061; false)<br \/>\n        return false;<\/p>\n<p>    return true;<br \/>\n} <\/p>\n<h6 id=\"FileHandler\">FileHandler<\/h6>\n<p><span style=\"color:#7b7f82\">\u5224\u65ad\u5ba2\u6237\u7aef\u8bf7\u6c42\u4e3a\u9759\u6001\u8d44\u6e90\u540e&#xff0c;\u6839\u636e\u8def\u5f84\u83b7\u53d6\u6587\u6863\u5185\u5bb9&#xff0c;\u6784\u5efaHTTPResponse\u5bf9\u8c61\u5373\u53ef\u00a0<\/span><\/p>\n<p>\/\/ \u9759\u6001\u8d44\u6e90\u7684\u8bf7\u6c42\u5904\u7406 &#8212; \u5c06\u9759\u6001\u8d44\u6e90\u6587\u4ef6\u7684\u6570\u636e\u8bfb\u53d6\u51fa\u6765&#xff0c;\u653e\u5230rsp\u7684_body\u4e2d, \u5e76\u8bbe\u7f6emime<br \/>\nvoid FileHandler(const HttpRequest &amp;req, HttpResponse *rsp)<br \/>\n{<br \/>\n    std::string req_path &#061; _basedir &#043; req._path;<br \/>\n    if (req._path.back() &#061;&#061; &#039;\/&#039;)<br \/>\n        req_path &#043;&#061; &#034;index.html&#034;;<\/p>\n<p>    bool ret &#061; Util::ReadFile(req_path, &amp;rsp-&gt;_body);<br \/>\n    if (ret &#061;&#061; false)<br \/>\n        return;<\/p>\n<p>    std::string mime &#061; Util::ExtMime(req_path);<br \/>\n    rsp-&gt;SetHeader(&#034;Content-Type&#034;, mime);<br \/>\n    return;<br \/>\n} <\/p>\n<h6 id=\"Dispatcher%C2%A0\">Dispatcher\u00a0<\/h6>\n<p><span style=\"color:null\">\u5224\u65ad\u5ba2\u6237\u7aef\u8bf7\u6c42\u4e3a\u529f\u80fd\u8bf7\u6c42\u540e&#xff0c;\u5728\u5bf9\u5e94\u8bf7\u6c42\u65b9\u6cd5\u7684\u8def\u7531\u8868\u4e2d&#xff0c;\u67e5\u627e\u662f\u5426\u542b\u6709\u5bf9\u5e94\u8d44\u6e90\u8bf7\u6c42\u7684\u5904\u7406\u51fd\u6570&#xff0c;\u6709\u5219\u8c03\u7528&#xff0c;\u6ca1\u6709\u5219\u8fd4\u56de404<\/span><\/p>\n<p>\/\/\u529f\u80fd\u6027\u8bf7\u6c42\u7684\u5206\u7c7b\u5904\u7406<br \/>\nvoid Dispatcher(HttpRequest &amp;req, HttpResponse *rsp, Handlers &amp;handlers)<br \/>\n{<br \/>\n    \/\/\u5728\u5bf9\u5e94\u8bf7\u6c42\u65b9\u6cd5\u7684\u8def\u7531\u8868\u4e2d&#xff0c;\u67e5\u627e\u662f\u5426\u542b\u6709\u5bf9\u5e94\u8d44\u6e90\u8bf7\u6c42\u7684\u5904\u7406\u51fd\u6570&#xff0c;\u6709\u5219\u8c03\u7528&#xff0c;\u6ca1\u6709\u5219\u53d1\u6325404<br \/>\n    \/\/\u601d\u60f3&#xff1a;\u8def\u7531\u8868\u5b58\u50a8\u7684\u65f6\u952e\u503c\u5bf9 &#8212; \u6b63\u5219\u8868\u8fbe\u5f0f &amp; \u5904\u7406\u51fd\u6570<br \/>\n    \/\/\u4f7f\u7528\u6b63\u5219\u8868\u8fbe\u5f0f&#xff0c;\u5bf9\u8bf7\u6c42\u7684\u8d44\u6e90\u8def\u5f84\u8fdb\u884c\u6b63\u5219\u5339\u914d&#xff0c;\u5339\u914d\u6210\u529f\u5c31\u4f7f\u7528\u5bf9\u5e94\u51fd\u6570\u8fdb\u884c\u5904\u7406<br \/>\n    \/\/  \/numbers\/(\\\\d&#043;)       \/numbers\/12345<br \/>\n    for (auto &amp;handler : handlers)<br \/>\n    {<br \/>\n        const std::regex &amp;re &#061; handler.first;<br \/>\n        const Handler &amp;functor &#061; handler.second;<br \/>\n        bool ret &#061; std::regex_match(req._path, req._matches, re);<br \/>\n        if (ret &#061;&#061; false)<br \/>\n            continue;<\/p>\n<p>        return functor(req, rsp);\/\/\u4f20\u5165\u8bf7\u6c42\u4fe1\u606f&#xff0c;\u548c\u7a7a\u7684rsp&#xff0c;\u6267\u884c\u5904\u7406\u51fd\u6570<br \/>\n    }<br \/>\n    rsp-&gt;_statu &#061; 404;<br \/>\n} <\/p>\n<h6 id=\"%C2%A0WriteReponse\">\u00a0WriteReponse<\/h6>\n<p><span style=\"color:#7b7f82\">\u6784\u5efaHTTP\u54cd\u5e94\u62a5\u6587&#xff0c;\u5e76\u8c03\u7528Connection\u7684Send\u63a5\u53e3&#xff0c;\u5c06\u54cd\u5e94\u62a5\u6587\u62f7\u8d1d\u5230\u53d1\u9001\u7f13\u51b2\u533a<\/span><\/p>\n<p>\/\/\u5c06HttpResponse\u4e2d\u7684\u8981\u7d20\u6309\u7167http\u534f\u8bae\u683c\u5f0f\u8fdb\u884c\u7ec4\u7ec7&#xff0c;\u53d1\u9001<br \/>\nvoid WriteReponse(const std::shared_ptr&lt;Connection&gt; &amp;conn, const HttpRequest &amp;req, HttpResponse &amp;rsp) {<br \/>\n    \/\/1. \u5148\u5b8c\u5584\u5934\u90e8\u5b57\u6bb5<br \/>\n    if (req.Close() &#061;&#061; true)<br \/>\n    {<br \/>\n        rsp.SetHeader(&#034;Connection&#034;, &#034;close&#034;);<br \/>\n    }<br \/>\n    else<br \/>\n    {<br \/>\n        rsp.SetHeader(&#034;Connection&#034;, &#034;keep-alive&#034;);<br \/>\n    }<br \/>\n    if (rsp._body.empty() &#061;&#061; false &amp;&amp; rsp.HasHeader(&#034;Content-Length&#034;) &#061;&#061; false)<br \/>\n    {<br \/>\n        rsp.SetHeader(&#034;Content-Length&#034;, std::to_string(rsp._body.size()));<br \/>\n    }<br \/>\n    if (rsp._body.empty() &#061;&#061; false &amp;&amp; rsp.HasHeader(&#034;Content-Type&#034;) &#061;&#061; false)<br \/>\n    {<br \/>\n        rsp.SetHeader(&#034;Content-Type&#034;, &#034;application\/octet-stream&#034;);<br \/>\n    }<br \/>\n    if (rsp._redirect_flag &#061;&#061; true)<br \/>\n    {<br \/>\n        rsp.SetHeader(&#034;Location&#034;, rsp._redirect_url);<br \/>\n    }<br \/>\n    \/\/2. \u5c06rsp\u4e2d\u7684\u8981\u7d20&#xff0c;\u6309\u7167http\u534f\u8bae\u683c\u5f0f\u8fdb\u884c\u7ec4\u7ec7<br \/>\n    std::stringstream rsp_str;<br \/>\n    rsp_str &lt;&lt; req._version &lt;&lt; &#034; &#034; &lt;&lt; std::to_string(rsp._statu) &lt;&lt; &#034; &#034; &lt;&lt; Util::StatuDesc(rsp._statu) &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    for (auto &amp;head : rsp._headers)<br \/>\n    {<br \/>\n        rsp_str &lt;&lt; head.first &lt;&lt; &#034;: &#034; &lt;&lt; head.second &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    }<br \/>\n    rsp_str &lt;&lt; &#034;\\\\r\\\\n&#034;;<br \/>\n    rsp_str &lt;&lt; rsp._body;<br \/>\n    \/\/3. \u53d1\u9001\u6570\u636e<br \/>\n    conn-&gt;Send(rsp_str.str().c_str(), rsp_str.str().size());<br \/>\n} <\/p>\n<h6 id=\"ErrorHandler\">ErrorHandler<\/h6>\n<p>\u7ec4\u7ec7\u4e00\u4e2a\u9519\u8bef\u5c55\u793a\u9875\u9762&#xff0c;\u5c06\u9875\u9762\u6570\u636e&#xff0c;\u5f53\u4f5c\u54cd\u5e94\u6b63\u6587&#xff0c;\u653e\u5165rsp\u4e2d<\/p>\n<p>void ErrorHandler(const HTTPRequest&amp; req, HTTPResponse* rsp)<br \/>\n{<br \/>\n    \/\/ \u76ee\u6807&#xff1a;\u9519\u8bef\u9875\u9762\u4e3a\u54cd\u5e94\u6b63\u6587&#xff0c;\u586b\u5145\u597drsp\u5373\u53ef<br \/>\n    std::string body;<br \/>\n    Util::ReadFile(&#034;.\/wwwroot\/err.html&#034;, &amp;body);<br \/>\n    rsp-&gt;SetContent(body, &#034;text\/html&#034;);<br \/>\n} <\/p>\n<h6 id=\"%E5%AF%B9%E5%A4%96%E6%8E%A5%E5%8F%A3\">\u5bf9\u5916\u63a5\u53e3<\/h6>\n<p>\u6ce8\u610f\u70b9&#xff1a;<\/p>\n<ul>\n<li><span style=\"color:#7b7f82\">\u8def\u7531\u8868\u7684Key\u5e76\u4e0d\u662fstring\u7c7b\u578b&#xff0c;\u800c\u662fregex\u7c7b\u578b&#xff0c;\u8fd9\u662f\u7531\u4e8eregex\u6bcf\u6b21\u4f7f\u7528\u90fd\u9700\u8981\u6b63\u5219\u8868\u8fbe\u5f0f\u7f16\u8bd1\u4e3a\u5b83\u53ef\u4ee5\u8bc6\u522b\u7684\u4e00\u79cd\u683c\u5f0f&#xff0c;\u5982\u679c\u6bcf\u4e00\u4e2a\u8bf7\u6c42\u90fd\u8981\u7f16\u8bd1&#xff0c;\u4f1a\u5f71\u54cd\u6548\u7387&#xff0c;\u6240\u4ee5\u76f4\u63a5\u4fdd\u5b58\u7f16\u8bd1\u597d\u7684regex\u4f5c\u4e3akey<\/span><\/li>\n<\/ul>\n<p>class HttpServer<br \/>\n{<br \/>\nprivate:<br \/>\n    using Handler &#061; std::function&lt;void(const HttpRequest &amp;, HttpResponse *)&gt;;<br \/>\n    using Handlers &#061; std::vector&lt;std::pair&lt;std::regex, Handler&gt;&gt;;<br \/>\n    Handlers _get_route;<br \/>\n    Handlers _post_route;<br \/>\n    Handlers _put_route;<br \/>\n    Handlers _delete_route;<br \/>\n    std::string _basedir; \/\/\u9759\u6001\u8d44\u6e90\u6839\u76ee\u5f55<br \/>\n    TcpServer _server;<br \/>\npublic:<br \/>\n    HttpServer(int port, int timeout &#061; DEFALT_TIMEOUT):_server(port)<br \/>\n    {<br \/>\n        _server.EnableInactiveRelease(timeout);<br \/>\n        _server.SetConnectedCallback(std::bind(&amp;HttpServer::OnConnected, this, std::placeholders::_1));<br \/>\n        _server.SetMessageCallback(std::bind(&amp;HttpServer::OnMessage, this, std::placeholders::_1, std::placeholders::_2));<br \/>\n    }<br \/>\n    void SetBaseDir(const std::string &amp;path)<br \/>\n    {<br \/>\n        assert(Util::IsDirectory(path) &#061;&#061; true);<br \/>\n        _basedir &#061; path;<br \/>\n    }<br \/>\n    \/*\u8bbe\u7f6e\/\u6dfb\u52a0&#xff0c;\u8bf7\u6c42&#xff08;\u8bf7\u6c42\u7684\u6b63\u5219\u8868\u8fbe&#xff09;\u4e0e\u5904\u7406\u51fd\u6570\u7684\u6620\u5c04\u5173\u7cfb*\/<br \/>\n    void Get(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {<br \/>\n        _get_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n    }<br \/>\n    void Post(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {<br \/>\n        _post_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n    }<br \/>\n    void Put(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {<br \/>\n        _put_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n    }<br \/>\n    void Delete(const std::string &amp;pattern, const Handler &amp;handler)<br \/>\n    {<br \/>\n        _delete_route.push_back(std::make_pair(std::regex(pattern), handler));<br \/>\n    }<br \/>\n    void SetThreadCount(int count)<br \/>\n    {<br \/>\n        _server.SetThreadCount(count);<br \/>\n    }<br \/>\n    void Listen()<br \/>\n    {<br \/>\n        _server.Start();<br \/>\n    }<br \/>\n}; <\/p>\n<h3 id=\"%E6%B5%8B%E8%AF%95\" style=\"background-color:transparent\">\u6d4b\u8bd5<\/h3>\n<p>#include &#034;HTTP.hpp&#034;<br \/>\n#include &#034;..\/Server.hpp&#034;<\/p>\n<p>const std::string basedir &#061; &#034;.\/wwwroot\/&#034;;<\/p>\n<p>std::string RequestStr(const HttpRequest&amp; req)<br \/>\n{<br \/>\n    std::string message;<br \/>\n    message &#043;&#061; req._method &#043; &#034; &#034; &#043; req._path &#043; &#034; &#034; &#043; req._version &#043; &#034;\\\\r\\\\n&#034;;<br \/>\n    for (auto&amp; it : req._params)<br \/>\n    {<br \/>\n        message &#043;&#061; it.first &#043; &#034;: &#034; &#043; it.second &#043; &#034;\\\\r\\\\n&#034;;<br \/>\n    }<br \/>\n    for (auto&amp; it : req._headers)<br \/>\n    {<br \/>\n        message &#043;&#061; it.first &#043; &#034;: &#034; &#043; it.second &#043; &#034;\\\\r\\\\n&#034;;<br \/>\n    }<br \/>\n    message &#043;&#061; &#034;\\\\r\\\\n&#034;;<br \/>\n    message &#043;&#061; req._body;<br \/>\n    return message;<br \/>\n}<br \/>\nvoid Hello(const HttpRequest&amp; req, HttpResponse* rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n}<br \/>\nvoid Login(const HttpRequest&amp; req, HttpResponse* rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n}<br \/>\nvoid PutFile(const HttpRequest&amp; req, HttpResponse* rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n}<br \/>\nvoid DelFile(const HttpRequest&amp; req, HttpResponse* rsp)<br \/>\n{<br \/>\n    rsp-&gt;SetContent(RequestStr(req), &#034;text\/plain&#034;);<br \/>\n}<\/p>\n<p>int main()<br \/>\n{<br \/>\n    HttpServer svr(8080);<br \/>\n    svr.SetThreadCount(3);<br \/>\n    \/\/ \u8bbe\u7f6e\u6839\u76ee\u5f55<br \/>\n    svr.SetBaseDir(basedir);<br \/>\n    svr.Get(&#034;\/hello&#034;, Hello);<br \/>\n    svr.Post(&#034;\/login&#034;, Login);<br \/>\n    svr.Put(&#034;\/put&#034;, PutFile);<br \/>\n    svr.Delete(&#034;\/del&#034;, DelFile);<\/p>\n<p>    svr.Listen();<\/p>\n<p>    return 0;<br \/>\n} <\/p>\n<h3 id=\"%C2%A0%E2%80%8B%E7%BC%96%E8%BE%91\">\u00a0<img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"213\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054559-6805db97d3f1a.png\" width=\"1088\" \/><\/h3>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"146\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054600-6805db981881e.png\" width=\"792\" \/>\u63d0\u4ea4\u8868\u5355\u540e\u670d\u52a1\u5668\u8fd4\u56de\u6211\u4eec\u7684\u8bf7\u6c42\u62a5\u6587<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"307\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054600-6805db98445e0.png\" width=\"1078\" \/><\/p>\n<h4 id=\"%E5%8E%8B%E5%8A%9B%E6%B5%8B%E8%AF%95\">\u538b\u529b\u6d4b\u8bd5<\/h4>\n<p><span style=\"color:#7b7f82\">\u57282\u68382G\u4e91\u670d\u52a1\u5668\u4e0a&#xff0c;\u5373\u8fd0\u884c\u670d\u52a1\u7aef&#xff0c;\u53c8\u8fd0\u884c\u5ba2\u6237\u7aef&#xff0c;\u5f97\u7684\u6d4b\u8bd5\u7ed3\u679c&#xff1a;\u5f53\u5e76\u53d1\u91cf\u4e3a4000\u65f6&#xff08;\u4e91\u670d\u52a1\u5668\u53ef\u521b\u5efa\u8fdb\u7a0b\u6570\u91cf\u6709\u9650&#xff09;&#xff0c;QPS&#xff1a;88286 \/ 60 &#061; 1471<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"300\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054600-6805db98867bd.png\" width=\"621\" \/><\/p>\n<\/p>\n<p><span style=\"color:#7b7f82\">\u865a\u62df\u673a\u914d\u7f6e\u4e3a4\u68384G&#xff0c;\u6211\u4eec\u5728\u865a\u62df\u673a\u4e0a\u540c\u65f6\u8fd0\u884c\u670d\u52a1\u7aef\u4e0ewebbench\u8fdb\u884c5000\u5e76\u53d1\u91cf\u6d4b\u8bd5<\/span><\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb876\u6b21\uff0c\u70b9\u8d5e13\u6b21\uff0c\u6536\u85cf8\u6b21\u3002\u4e3b\u4eceReactor\u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u5bf9HTTP\u534f\u8bae\u7684\u652f\u6301<\/p>\n","protected":false},"author":2,"featured_media":31419,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[151,58,43,78,185],"topic":[],"class_list":["post-31426","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-http","tag-linux","tag-43","tag-78","tag-185"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/31426.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb876\u6b21\uff0c\u70b9\u8d5e13\u6b21\uff0c\u6536\u85cf8\u6b21\u3002\u4e3b\u4eceReactor\u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u5bf9HTTP\u534f\u8bae\u7684\u652f\u6301\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/31426.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2025-04-21T05:46:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054559-6805db9730884.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/31426.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/31426.html\",\"name\":\"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2025-04-21T05:46:01+00:00\",\"dateModified\":\"2025-04-21T05:46:01+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/31426.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/31426.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/31426.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/31426.html","og_locale":"zh_CN","og_type":"article","og_title":"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u6587\u7ae0\u6d4f\u89c8\u9605\u8bfb876\u6b21\uff0c\u70b9\u8d5e13\u6b21\uff0c\u6536\u85cf8\u6b21\u3002\u4e3b\u4eceReactor\u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u5bf9HTTP\u534f\u8bae\u7684\u652f\u6301","og_url":"https:\/\/www.wsisp.com\/helps\/31426.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2025-04-21T05:46:01+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2025\/04\/20250421054559-6805db9730884.png"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"21 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/31426.html","url":"https:\/\/www.wsisp.com\/helps\/31426.html","name":"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2025-04-21T05:46:01+00:00","dateModified":"2025-04-21T05:46:01+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/31426.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/31426.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/31426.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\uff1c\u9879\u76ee\uff1e \u9ad8\u5e76\u53d1\u670d\u52a1\u5668\u7684HTTP\u534f\u8bae\u652f\u6301"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/31426","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=31426"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/31426\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/31419"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=31426"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=31426"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=31426"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=31426"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}