Skip to content

Commit 0960eae

Browse files
committed
发现问题
协程销毁时不调用协程内变量的析构函数
1 parent 3ca8c2e commit 0960eae

5 files changed

Lines changed: 52 additions & 17 deletions

File tree

README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,12 @@
1818

1919
需要c++20
2020

21-
- linux下使用clang>16,在debug下编译.
21+
- linux下使用clang>16.
2222

2323
例如,在archlinux下需要安装下述依赖
2424

2525
```bash
26-
sudo pacman -S clang spdlog fmt asio openssl xmake pkgconf git unzip --needed --noconfirm
26+
sudo pacman -S clang spdlog fmt asio openssl xmake pkgconf git unzip --needed
2727
```
2828

2929
其他发行版对应安装
@@ -36,10 +36,11 @@
3636
linux下打开`终端`或者windows下打开`windows terminal`
3737

3838
```shell
39+
#下载依赖库时,可以设置github镜像代理
3940
xmake g --proxy_pac=github_mirror.lua
40-
41-
xmake -rvwD hcpp
42-
41+
#编译
42+
xmake -vDrw hcpp
43+
#运行
4344
xmake run hcpp
4445
```
4546

main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ int main(int argc, char **argv)
8989
}
9090
};
9191

92-
co_spawn(io_context, hs.wait_http(c->get_port()), exit_handler);
92+
co_spawn(io_context, hs.wait_http(c->get_port(),io_context), exit_handler);
9393
co_spawn(io_context, mhs.wait_c(10, c->get_proxy_service()), exit_handler);
9494

9595
auto create_thread = [&](auto self, int i) -> void

src/http/httpclient.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ namespace hcpp
9090
if (h.url_.empty() && !h.host_.empty())
9191
{
9292
h.url_ = "/";
93+
}else if(!h.url_.empty()){
94+
if(auto p=h.url_.find_first_of("?");p!=std::string::npos){
95+
h.url_=h.url_.substr(0,p);
96+
}
9397
}
9498
}
9599
assert(url_end + 1 <= svl.size());

src/httpserver.cpp

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace hcpp
1717
namespace log = spdlog;
1818
// inline std::latch latch(1);
1919

20-
awaitable<void> http_do(std::unique_ptr<http_client> client, std::shared_ptr<service_keeper> sk)
20+
awaitable<void> http_handler::http_do(std::unique_ptr<http_client> client, std::shared_ptr<service_keeper> sk)
2121
{
2222
co_await client->init();
2323
while (true)
@@ -136,8 +136,15 @@ namespace hcpp
136136
}
137137
else // TODO 用于控制自身行为
138138
{
139-
co_await ss->async_write_all("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 16\r\n\r\nHello,from http!");
140-
continue;
139+
if (auto p=base_handlers_.find(req.url_);p!=base_handlers_.end())
140+
{
141+
co_await ss->async_write_all((p->second)(req.url_));
142+
}
143+
else
144+
{
145+
co_await ss->async_write_all("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 16\r\n\r\nHello,from http!");
146+
continue;
147+
}
141148
}
142149
}
143150
}
@@ -151,24 +158,35 @@ namespace hcpp
151158
}
152159
}
153160
}
161+
162+
void http_handler::add_handler(std::string_view path, std::function<std::string (std::string_view)> handler)
163+
{
164+
base_handlers_.insert({path, handler});
165+
}
154166

155167
using tcp_acceptor = use_awaitable_t<>::as_default_on_t<ip::tcp::acceptor>;
156168

157-
awaitable<void> httpserver::wait_http(uint16_t port)
169+
awaitable<void> httpserver::wait_http(uint16_t port, io_context &ic)
158170
{
159171
auto executor = co_await this_coro::executor;
160172

161173
tcp_acceptor acceptor(executor, {ip::tcp::v4(), port});
162174
co_await nc->async_receive();
163175
spdlog::debug("http_server监听端口:{}", acceptor.local_endpoint().port());
176+
http_handler hh;
177+
hh.add_handler("/stop", [&ic](auto &&path)
178+
{
179+
ic.stop();
180+
return "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\n\r\nserver stop!";
181+
});
164182
for (;;)
165183
{
166184
try
167185
{
168186
auto socket = co_await acceptor.async_accept();
169187
auto sk = std::make_unique<http_svc_keeper>(make_threadlocal_svc_cache(), slow_dns::get_slow_dns());
170188
auto hsk = std::make_shared<hack_sk>(std::move(sk), ta_);
171-
co_spawn(executor, http_do(std::make_unique<http_client>(std::move(socket)), std::move(hsk)), detached);
189+
co_spawn(executor, hh.http_do(std::make_unique<http_client>(std::move(socket)), std::move(hsk)), detached);
172190
}
173191
catch (const std::exception &e)
174192
{
@@ -204,8 +222,9 @@ namespace hcpp
204222

205223
co_await nc->async_send(asio::error_code{}, "ok");
206224
// 在当前协程运行
207-
auto https_listener = [&executor, c = channel_, cr_ps_map, ca_subject = ca_subject_]() -> awaitable<void>
225+
auto https_listener = [c = channel_, cr_ps_map, ca_subject = ca_subject_]() -> awaitable<void>
208226
{
227+
http_handler hh;
209228
for (;;)
210229
{
211230
try
@@ -253,7 +272,7 @@ namespace hcpp
253272
self.set_mem(co_await std::move(*cc).make(std::move(si)));
254273
};
255274

256-
co_spawn(executor, http_do(std::move(hsc), std::move(sk)), detached);
275+
co_spawn(co_await this_coro::executor, hh.http_do(std::move(hsc), std::move(sk)), detached);
257276
}
258277
catch (const std::exception &e)
259278
{
@@ -280,7 +299,8 @@ namespace hcpp
280299
}
281300
spdlog::debug("mimt https server线程退出成功");
282301
};
283-
std::jthread t(https_service);
302+
std::thread t(https_service);
303+
t.detach();
284304

285305
std::unique_ptr<int, std::function<void(int *)>> ptr(new int(0), [&work_guard, &executor](auto &&p)
286306
{
@@ -291,7 +311,7 @@ namespace hcpp
291311
delete p; });
292312

293313
co_await co_spawn(executor, https_listener(), use_awaitable);
294-
//XXX 不会执行到这里
314+
// XXX 不会执行到这里
295315
co_return;
296316
}
297317

src/httpserver.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ namespace hcpp
2121

2222
// using socket_channel = asio::use_awaitable_t<>::as_default_on_t<concurrent_channel<void(asio::error_code, std::shared_ptr<tls_client>)>>;
2323

24+
class http_handler
25+
{
26+
public:
27+
void add_handler(std::string_view path, std::function<std::string (std::string_view)> handler);
28+
awaitable<void> http_do(std::unique_ptr<http_client> client, std::shared_ptr<service_keeper> sk);
29+
private:
30+
std::unordered_map<std::string_view, std::function<std::string (std::string_view)>> base_handlers_;
31+
};
32+
2433
awaitable<void> http_do(std::unique_ptr<http_client> client, std::shared_ptr<service_keeper> sk);
2534

2635
using tunnel_advice = std::function<std::shared_ptr<tunnel>(std::shared_ptr<tunnel>, std::string_view, std::string_view)>;
@@ -49,7 +58,7 @@ namespace hcpp
4958
class httpserver
5059
{
5160
public:
52-
awaitable<void> wait_http(uint16_t port);
61+
awaitable<void> wait_http(uint16_t port,io_context & ic);
5362

5463
// TODO 让mitm替换掉tunnel实现,从而拦截默认tunnel
5564
void attach_tunnel(tunnel_advice w);
@@ -76,7 +85,7 @@ namespace hcpp
7685
class mimt_https_server
7786
{
7887
public:
79-
awaitable<void> wait_c(std::size_t cn,std::vector<proxy_service> ps);
88+
awaitable<void> wait_c(std::size_t cn, std::vector<proxy_service> ps);
8089
awaitable<void> wait(uint16_t port);
8190

8291
std::optional<std::shared_ptr<tunnel>> find_tunnel(std::string_view svc_host, std::string_view svc_service);
@@ -85,6 +94,7 @@ namespace hcpp
8594

8695
void set_ca(subject_identify ca_subject);
8796
void set_root_verify_store_path(std::string_view root_verify_store_path);
97+
8898
private:
8999
std::shared_ptr<socket_channel> channel_;
90100
std::shared_ptr<subject_identify> ca_subject_;

0 commit comments

Comments
 (0)