{"id":5693,"date":"2026-05-12T19:01:17","date_gmt":"2026-05-12T10:01:17","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=5693"},"modified":"2026-05-12T19:01:53","modified_gmt":"2026-05-12T10:01:53","slug":"webserver-miniwebserver-11","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/05\/12\/webserver-miniwebserver-11\/","title":{"rendered":"[Webserver]miniWebserver-(11)"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb \uc8fc\uc694 \ubcc0\uacbd\uc0ac\ud56d\uc740 \uc544\ub798\uc640 \uac19\uc2b5\ub2c8\ub2e4.<br>The major changes are as follows.<\/p>\n\n\n\n<p>\u2714\ufe0f \u2757\ufe0f \ud45c\uc2dc\ub41c \ubd80\ubd84\uc774 \ubcc0\uacbd\uc0ac\ud56d\uc785\ub2c8\ub2e4.<br>The parts marked with \u2757\ufe0f are the changes.<\/p>\n\n\n\n<p>\u2714\ufe0f \uac00\uc0c1\ud638\uc2a4\ud2b8 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4.<br>Added virtual host functionality.<\/p>\n\n\n\n<p>\u2714\ufe0f HttpsServer.cpp\uc5d0 \uc2a4\ub808\ub4dc \uc815\ub9ac\uc2dc\uac04\uc744 \uc880 \ub354 \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4.<br>I added some more thread cleanup time to HttpsServer.cpp.<\/p>\n\n\n\n<p>\u2714\ufe0f \uc11c\ubc84\uc885\ub8cc \ubd80\ubd84\uc5d0 try-catch \ubd80\ubd84\uc774 \ucd94\uac00\ub418\uc5c8\uc2b5\ub2c8\ub2e4.<br>A try-catch block has been added to the server termination section.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb\ucf54\ub4dc \/ Code<\/p>\n\n\n\n<p>\u2714\ufe0f\uac00\uc0c1\ud638\uc2a4\ud2b8 \/ Virtual Host<\/p>\n\n\n\n<p>&#8212; main.cpp<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>    \/\/ virtusl host \ub77c\uc6b0\ud130 \/ virtual host router\u2757\ufe0f\n    Router virtual_router(\"..\/public_virtual\");\n    virtual_router.add_route(\"GET\",\"\/test1\", \"test1.html\");\n    virtual_router.add_route(\"POST\",\"\/test2\", \"test2.html\");\n\n    \/\/ virtual host http(5080) server host map\u2757\ufe0f\n    static std::map&lt;std::string, Router*&gt; vhost_routers = {\n        {\"yourmainhost.domain.org\", &amp;server1_router},\n        {\"yourvirtualhost.domain.org\", &amp;virtual_router},\n        {\"localhost\", &amp;server1_router},\n        {\"127.0.0.1\", &amp;server1_router},\n        {\"192.168.0.100\", &amp;server1_router}\n    };\n\n    \/\/ virtual host https(6443) server host map\u2757\ufe0f\n    static std::map&lt;std::string, Router*&gt; vhost_https_routers = {\n        {\"yourmainhost.domain.org\", &amp;server2_router},\n        {\"yourvirtualhost.domain.org\"\", &amp;virtual_router},\n        {\"localhost\", &amp;server2_router},\n        {\"127.0.0.1\", &amp;server2_router},\n        {\"192.168.0.100\", &amp;server2_router}\n    };\n\n        std::pair&lt;std::string, std::string&gt; result;\n\n\n        \/\/ \uc694\uccad \ud5e4\ub354 \uc804\uccb4 \uc77d\uae30 \ubc0f Host \ud5e4\ub354 \ud30c\uc2f1\u2757\ufe0f\n        \/\/ Read all request headers and parse Host headers\n        std::string line;\n        std::string host;\n\n        \/\/ \ud5e4\ub354\uc5d0\uc11c \uac1c\ud589\ubb38\uc790 \uc81c\uac70\uc6a9 \u2757\ufe0f\n        \/\/ For removing newline characters from headers\n        std::string dummy;\n        std::getline(req_stream, dummy);\n\n        \/\/ \uc694\uccad \ud5e4\ub354 \ud30c\uc2f1(req stream\uc758 \uac12\uc744 \uc77d\uc5b4\uc11c line \ubcc0\uc218\uc5d0 \ud55c \uc904\uc529 \ubcf5\uc0ac)\u2757\ufe0f\n        \/\/ Parse request headers (read values \u200b\u200bfrom the req stream and copy them line by line to the line variable)\n        while (std::getline(req_stream, line) &amp;&amp; line != \"\\r\" &amp;&amp; !line.empty()) {\n            \/\/ \"Host:\" \ucc3e\uae30 (\ub300\uc18c\ubb38\uc790 \ubb34\uad00\ud558\uac8c \uac80\uc0ac\ud558\ub294 \uac83\uc774 \uc548\uc804\ud568)\n            if (line.compare(0, 5, \"Host:\") == 0 || line.compare(0, 5, \"host:\") == 0) {\n                host = line.substr(5);\n                \/\/ \uacf5\ubc31 \ubc0f \\r \uc81c\uac70\n                host.erase(0, host.find_first_not_of(\" \\t\"));\n                size_t last = host.find_last_not_of(\" \\t\\r\\n\");\n                if (last != std::string::npos) host.erase(last + 1);\n\n                \/\/ std::cout &lt;&lt; \"&#91;DEBUG] https Host Found: \" &lt;&lt; host &lt;&lt; std::endl &lt;&lt; std::flush;\n            }\n        }\n\nserver2.set_handler(&#91;&amp;](const std::string&amp; req) {\n\n... \uc911\ub7b5 \/ Skipping the middle ...\n\n        \/\/ \ud3ec\ud2b8 \ubc88\ud638 \uc81c\uac70\ud558\uc5ec \ub3c4\uba54\uc778\uba85\ub9cc \ucd94\ucd9c\u2757\ufe0f\n        \/\/ Remove port number to extract only the domain name\n        std::string host_normalized = host;\n        size_t pos = host.find(':');\n        if (pos != std::string::npos) {\n            host_normalized = host.substr(0, pos);\n        }\n\n        \/\/ \ub77c\uc6b0\ud130 \uc120\ud0dd: \ud574\ub2f9 \ud638\uc2a4\ud2b8\uc758 \ub77c\uc6b0\ud130 \ucc3e\uae30, \uc5c6\uc73c\uba74 \uae30\ubcf8 \ub77c\uc6b0\ud130\u2757\ufe0f\n        \/\/ Select Router: Find the router for the host, if none exists, use the default router\n        Router* router_ptr = &amp;server2_router; \/\/ \uae30\ubcf8\uac12 \/ default value\n        auto it = vhost_https_routers.find(host_normalized);\n        if (it != vhost_https_routers.end()) {\n            router_ptr = it-&gt;second;\n        }\n\n\n        if (method == \"GET\" || method == \"POST\" || method == \"PUT\" || method == \"DELETE\" || method == \"FETCH\") {\n\n            \/\/ \uc774\uc804\ucf54\ub4dc \/ previous code\n            \/\/result = server2_router.router(method, path);\n            \/\/\n            \/\/ virtual host \uc801\uc6a9 \/ apply virtual host\u2757\ufe0f\n            result = router_ptr-&gt;router(method, path);\n        }\n\n... \uc911\ub7b5 \/ Skipping the middle ...\n\n}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \uc2a4\ub808\ub4dc \uc815\ub9ac\uc2dc\uac04 \ucd94\uac00 \/ Add thread cleanup time<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>  \/\/ \uc2a4\ub808\ub4dc \uc815\ub9ac\uc2dc\uac04 \ucd94\uac00\u2757\ufe0f\n  \/\/ Add thread cleanup time\n  std::this_thread::sleep_for(std::chrono::milliseconds(300));<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ube4c\ub4dc \/ Build<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd build\ncmake ..\nmake<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc2e4\ud589 \/ Run<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/main<\/code><\/pre>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \ube0c\ub77c\uc6b0\uc800 \uc811\uc18d \/ Access Browser<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>http:&#47;&#47;yourmainhost.domain.org:5080\nhttp:\/\/yourvirtualhost.domain.org:5080\n\nhttps:\/\/yourmainhost.domain.org:6444\nhttps:\/\/yourvirtualhost.domain.org:6444<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb \uc8fc\uc694 \ubcc0\uacbd\uc0ac\ud56d\uc740 \uc544\ub798\uc640 \uac19\uc2b5\ub2c8\ub2e4.The major changes are as follows. \u2714\ufe0f \u2757\ufe0f \ud45c\uc2dc\ub41c \ubd80\ubd84\uc774 \ubcc0\uacbd\uc0ac\ud56d\uc785\ub2c8\ub2e4.The parts marked with \u2757\ufe0f are the changes. \u2714\ufe0f \uac00\uc0c1\ud638\uc2a4\ud2b8 \uae30\ub2a5\uc744 \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4.Added virtual host functionality. \u2714\ufe0f HttpsServer.cpp\uc5d0 \uc2a4\ub808\ub4dc \uc815\ub9ac\uc2dc\uac04\uc744 \uc880 \ub354 \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4.I added some more thread cleanup time to HttpsServer.cpp. \u2714\ufe0f \uc11c\ubc84\uc885\ub8cc \ubd80\ubd84\uc5d0 try-catch \ubd80\ubd84\uc774 \ucd94\uac00\ub418\uc5c8\uc2b5\ub2c8\ub2e4.A try-catch block has been added [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[23,1],"tags":[],"class_list":["post-5693","post","type-post","status-publish","format-standard","hentry","category-cpp","category-uncategorized","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/5693","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=5693"}],"version-history":[{"count":1,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/5693\/revisions"}],"predecessor-version":[{"id":5694,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/5693\/revisions\/5694"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=5693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=5693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=5693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}