Skip to content

Commit 8f428e4

Browse files
committed
优化配置方式
1 parent edaa646 commit 8f428e4

16 files changed

Lines changed: 276 additions & 178 deletions

main.cpp

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,21 @@ int main(int argc, char **argv)
6060
signals.async_wait([&](auto, auto)
6161
{ io_context.stop(); });
6262

63-
hcpp::httpserver hs;
63+
auto hh = std::make_shared<hcpp::http_handler>();
64+
c->config_to(hh);
65+
hh->add_request_handler("/stop", [&io_context](auto &&path)
66+
{
67+
io_context.stop();
68+
return "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nContent-Length: 12\r\n\r\nserver stop!"; });
69+
6470
hcpp::mimt_https_server mhs;
71+
mhs.set_http_handler(hh);
6572
if (!c->config_to(mhs))
6673
{
6774
return -1;
6875
}
6976
mhs.set_ch(std::make_shared<hcpp::socket_channel>(io_context, 10));
7077

71-
hs.attach_tunnel(
72-
[&mhs](auto &&c, auto h, auto s)
73-
{
74-
if (auto r = mhs.find_tunnel(h, s); r)
75-
{
76-
return *r;
77-
}
78-
return c;
79-
});
80-
8178
auto exit_handler = [&io_context](auto &&eptr)
8279
{
8380
try
@@ -92,8 +89,8 @@ int main(int argc, char **argv)
9289
}
9390
};
9491

95-
co_spawn(io_context, hs.wait_http(c->get_port(), io_context), exit_handler);
96-
co_spawn(io_context, mhs.wait_c(c->get_proxy_service()), exit_handler);
92+
co_spawn(io_context, mhs.wait_http(c->get_port()), exit_handler);
93+
co_spawn(io_context, mhs.wait_c(), exit_handler);
9794

9895
auto create_thread = [&](auto self, int i) -> void
9996
{

src/config.cpp

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ namespace hcpp
3838
spdlog::error("{} : {}", config_path, j.get_errors());
3939
throw std::runtime_error("解析config出错");
4040
}
41+
//BUG https://github.com/dayu521/lsf/issues/5
4142
lsf::json_to_struct_ignore_absence(*res, cs_);
4243

4344
// 主机映射配置文件
@@ -104,33 +105,17 @@ namespace hcpp
104105
}
105106
}
106107

107-
bool config::config_to(std::shared_ptr<slow_dns> dns)
108+
bool config::config_to(std::shared_ptr<http_handler> hh)
108109
{
110+
static thread_local std::regex r(R"(^\*|((\*\.)+.+)$)");
111+
112+
std::map<unsigned int, std::pair<std::regex, InterceptSet>> star_map;
109113
for (auto &&i : cs_.proxy_service_)
110114
{
111115
if (i.doh_)
112116
{
113-
dns->add_doh_filter(i.host_);
117+
hh->add_intercept(std::make_pair(i.host_, i));
114118
}
115-
}
116-
dns->load_hm(hm_);
117-
dns->load_dp(cs_.dns_provider_);
118-
return true;
119-
}
120-
121-
bool config::config_to(std::shared_ptr<mimt_https_server> mhs)
122-
{
123-
return config_to(*mhs);
124-
}
125-
126-
bool config::config_to(mimt_https_server &mhs)
127-
{
128-
static thread_local std::regex r(R"(^\*|((\*\.)+.+)$)");
129-
130-
std::map<unsigned int, std::pair<std::regex, std::string>> star_map;
131-
132-
for (auto &&i : cs_.proxy_service_)
133-
{
134119
if (i.mitm_)
135120
{
136121
std::smatch mr;
@@ -148,16 +133,44 @@ namespace hcpp
148133
}
149134
auto s = std::regex_replace(i.host_, std::regex(R"(\*\.)"), R"(.+\.)");
150135
log::info("构造的正则: {} -> {}", i.host_, s);
151-
star_map.insert({nstar, std::make_pair(std::regex(std::move(s)), i.svc_)});
136+
star_map.insert({nstar, std::make_pair(std::regex(std::move(s)), std::move(i))});
137+
}
138+
else
139+
{
140+
hh->add_intercept(std::make_pair(i.host_, std::move(i)));
152141
}
153-
154-
mhs.tunnel_set_.insert({i.host_, i.svc_});
155142
}
156143
}
144+
157145
for (auto &&i : star_map)
158146
{
159-
mhs.tunnel_regx_list_.push_back(std::move(i.second));
147+
hh->add_intercept(std::move(i.second));
148+
}
149+
150+
return true;
151+
}
152+
153+
bool config::config_to(std::shared_ptr<slow_dns> dns)
154+
{
155+
for (auto &&i : cs_.proxy_service_)
156+
{
157+
if (i.doh_)
158+
{
159+
dns->add_doh_filter(i.host_);
160+
}
160161
}
162+
dns->load_hm(hm_);
163+
dns->load_dp(cs_.dns_provider_);
164+
return true;
165+
}
166+
167+
bool config::config_to(std::shared_ptr<mimt_https_server> mhs)
168+
{
169+
return config_to(*mhs);
170+
}
171+
172+
bool config::config_to(mimt_https_server &mhs)
173+
{
161174
subject_identify si;
162175

163176
auto si_tu = std::forward_as_tuple(cs_.ca_pkey_path_, cs_.ca_cert_path_);

src/config.h

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <functional>
1010
#include <cstdint>
1111

12+
#include "http/intercept.h"
13+
1214
namespace hcpp
1315
{
1416
// dns mapping config
@@ -29,17 +31,23 @@ namespace hcpp
2931
JS_OBJECT(JS_MEMBER(provider_), JS_MEMBER(host_));
3032
};
3133

32-
struct proxy_service
34+
struct proxy_service : InterceptSet
3335
{
34-
std::string host_;
35-
std::string svc_; // 端口或服务名.例如 http https
36-
std::string url_;
37-
bool mitm_ = false;
38-
bool doh_ = false;
39-
bool close_sni_ = false; // 默认就是false.优先级高于sni_host_
40-
std::string sni_host_; // 假的主机名
41-
42-
JS_OBJECT(JS_MEMBER(host_), JS_MEMBER(svc_), JS_MEMBER(url_), JS_MEMBER(mitm_), JS_MEMBER(doh_), JS_MEMBER(close_sni_), JS_MEMBER(sni_host_));
36+
// std::string host_;
37+
// std::string svc_; // 端口或服务名.例如 http https
38+
// std::string url_;
39+
// bool mitm_ = false;
40+
// bool doh_ = false;
41+
// bool close_sni_ = false; // 默认就是false.优先级高于sni_host_
42+
// std::string sni_host_; // 假的主机名
43+
44+
JS_OBJECT(JS_MEMBER(host_),
45+
JS_MEMBER(svc_),
46+
JS_MEMBER(url_),
47+
JS_MEMBER(mitm_),
48+
JS_MEMBER(doh_),
49+
JS_MEMBER(close_sni_),
50+
JS_MEMBER(sni_host_));
4351
};
4452

4553
struct config_struct
@@ -64,6 +72,7 @@ namespace hcpp
6472

6573
class slow_dns;
6674
class mimt_https_server;
75+
class http_handler;
6776

6877
class config
6978
{
@@ -76,6 +85,7 @@ namespace hcpp
7685
config(const config &) = delete;
7786
~config();
7887

88+
bool config_to(std::shared_ptr<http_handler> hs);
7989
bool config_to(std::shared_ptr<slow_dns> dns);
8090
bool config_to(std::shared_ptr<mimt_https_server> mhs);
8191
bool config_to(mimt_https_server &mhs);

src/dns.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,9 @@ namespace hcpp
5656

5757
std::string dns_path_;
5858

59-
awaitable<edp_lists> resolve(host_edp hedp);
59+
awaitable<edp_lists> resolve(host_edp hedp, bool doh = false);
6060

61-
awaitable<void> async_resolve(std::shared_ptr<channel> cc, host_edp hedp);
61+
awaitable<void> async_resolve(std::shared_ptr<channel> cc, host_edp hedp, bool doh = false);
6262

6363
void remove(host_edp hedp);
6464

@@ -139,9 +139,9 @@ namespace hcpp
139139
return p;
140140
}
141141

142-
awaitable<edp_lists> slow_dns::resolve(host_edp hedp)
142+
awaitable<edp_lists> slow_dns::resolve(host_edp hedp, bool doh)
143143
{
144-
auto ip_edp = co_await imp_->resolve(hedp);
144+
auto ip_edp = co_await imp_->resolve(hedp, doh);
145145

146146
for (auto &&i : ip_edp)
147147
{
@@ -232,7 +232,7 @@ namespace hcpp
232232
{
233233
}
234234

235-
awaitable<edp_lists> slow_dns::slow_dns_imp::resolve(host_edp hedp)
235+
awaitable<edp_lists> slow_dns::slow_dns_imp::resolve(host_edp hedp, bool doh)
236236
{
237237
{
238238
std::shared_lock<std::shared_mutex> m(smutex_);
@@ -256,7 +256,7 @@ namespace hcpp
256256
// 解析时可以发现其他消费者是否已经解析,进而跳过不必要的解析.解析完成 发送消息唤醒
257257

258258
// HACK 不直接使用channel https://github.com/chriskohlhoff/asio/issues/1175
259-
asio::co_spawn(ex, async_resolve(cc, hedp), detached);
259+
asio::co_spawn(ex, async_resolve(cc, hedp, doh), detached);
260260

261261
std::variant<edp_lists, std::monostate> results = co_await (cc->async_receive() || t.async_wait());
262262
if (results.index() != 0)
@@ -267,7 +267,9 @@ namespace hcpp
267267
}
268268

269269
// FIXME 注意,如果使用asio::coro,这里就有线程问题,下面的加锁无效,仍旧出现死锁问题
270-
awaitable<void> slow_dns::slow_dns_imp::async_resolve(std::shared_ptr<channel> cc, host_edp hedp)
270+
// Asio 1.30.2
271+
// Fixed a compile error that occurred when channels and experimental::coro were both used in the same translation unit.
272+
awaitable<void> slow_dns::slow_dns_imp::async_resolve(std::shared_ptr<channel> cc, host_edp hedp, bool doh)
271273
{
272274
/// 协程内,协程切换时,一定不能持有锁,它都可能会和其他协程持有的锁互斥,除非所有都是共享锁
273275

@@ -294,7 +296,7 @@ namespace hcpp
294296
try
295297
{
296298

297-
if (doh_filter_.contains(hedp.first))
299+
if (doh)
298300
{
299301
el = co_await hcpp::resolve(hedp, dns_providers_);
300302
}
@@ -315,7 +317,7 @@ namespace hcpp
315317
}
316318
catch (const std::exception &e)
317319
{
318-
log::error("slow_dns::slow_dns_imp::async_resolve: 解析失败 {}",e.what());
320+
log::error("slow_dns::slow_dns_imp::async_resolve: 解析失败 {}", e.what());
319321
std::unique_lock<std::mutex> m(rmutex_);
320322
resolve_running_.erase(hedp);
321323
throw;

src/dns.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace hcpp
2828
static std::shared_ptr<slow_dns> get_slow_dns();
2929

3030
public:
31-
awaitable<edp_lists> resolve(host_edp hedp);
31+
awaitable<edp_lists> resolve(host_edp hedp,bool doh = false);
3232
void remove_svc(const host_edp & hedp, std::string_view ip);
3333

3434
void load_hm(const std::vector<host_mapping> & hm);

src/hcpp-cfg.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
{
4747
"host_":"gitee.com",
4848
"svc_":"443",
49+
// "url_":"www.baidu.com", //暂时的行为是替换host_,拦截去访问另外的主机,但不能使用session,cookie ,所以不能登陆
4950
"url_":"",
5051
"mitm_":true,
5152
"doh_":false,

src/http/http_svc_keeper.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,30 @@ namespace hcpp
2828
{
2929
}
3030

31-
awaitable<std::shared_ptr<memory>> http_svc_keeper::wait(std::string svc_host, std::string svc_service)
31+
awaitable<std::shared_ptr<memory>> http_svc_keeper::wait(std::string svc_host, std::string svc_service, std::shared_ptr<InterceptSet> is)
3232
{
33-
if (!m_)
33+
if (m_ && host_ == svc_host && service_ == svc_service)
3434
{
35-
if (auto o = co_await make_socket(svc_host, svc_service); o)
36-
{
37-
m_ = std::make_shared<socket_memory>(std::move(*o));
38-
}
39-
else
40-
{
41-
m_ = std::make_shared<failed_mem>();
42-
}
35+
co_return m_;
36+
}
37+
38+
auto use_doh = is ? is->doh_ : false;
39+
if (auto o = co_await make_socket(svc_host, svc_service, use_doh); o)
40+
{
41+
m_ = std::make_shared<socket_memory>(std::move(*o));
42+
}
43+
else
44+
{
45+
m_ = std::make_shared<failed_mem>();
4346
}
47+
4448
co_return m_;
4549
// auto svc_endpoint = co_await endpoint_cache_->get_endpoint(svc_host, svc_service, slow_dns_);
4650

4751
// co_return std::make_shared<service_worker>(svc_endpoint, svc_host, svc_service, endpoint_cache_);
4852
}
4953

50-
awaitable<std::shared_ptr<tunnel>> http_svc_keeper::wait_tunnel(std::string svc_host, std::string svc_service)
54+
awaitable<std::shared_ptr<tunnel>> http_svc_keeper::wait_tunnel(std::string svc_host, std::string svc_service, std::shared_ptr<InterceptSet> is)
5155
{
5256
co_return std::make_shared<socket_tunnel>();
5357
}

src/http/http_svc_keeper.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ namespace hcpp
6666
virtual bool ok() override;
6767
virtual void reset() override;
6868
virtual void close() override;
69-
virtual bool alive()override;
69+
virtual bool alive() override;
7070

7171
private:
7272
std::shared_ptr<memory> m_;
@@ -92,14 +92,17 @@ namespace hcpp
9292
public:
9393
http_svc_keeper(std::shared_ptr<svc_cache> cache, std::shared_ptr<slow_dns> dns);
9494

95-
awaitable<std::shared_ptr<memory>> wait(std::string svc_host, std::string svc_service) override;
95+
awaitable<std::shared_ptr<memory>> wait(std::string svc_host, std::string svc_service, std::shared_ptr<InterceptSet> is) override;
9696

97-
awaitable<std::shared_ptr<tunnel>> wait_tunnel(std::string svc_host, std::string svc_service) override;
97+
awaitable<std::shared_ptr<tunnel>> wait_tunnel(std::string svc_host, std::string svc_service, std::shared_ptr<InterceptSet> is) override;
9898

9999
private:
100100
std::shared_ptr<slow_dns> slow_dns_;
101101
std::shared_ptr<svc_cache> endpoint_cache_;
102102
std::shared_ptr<memory> m_;
103+
104+
std::string host_;
105+
std::string service_;
103106
};
104107

105108
class svc_cache

src/http/intercept.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef SRC_HTTP_INTERCEPT
2+
#define SRC_HTTP_INTERCEPT
3+
4+
#include <string>
5+
6+
namespace hcpp
7+
{
8+
struct InterceptSet
9+
{
10+
std::string host_; //请求的主机.标识key查询拦截
11+
std::string svc_; // 端口或服务名.例如 http https
12+
std::string url_; //TODO 替换url
13+
std::string real_host_; //TODO 替换的主机名
14+
15+
bool doh_ = false; //使用doh查询主机ip
16+
std::string doh_provider_; //TODO 当前主机使用此提供商查询,而非全局配置的提供商
17+
18+
bool mitm_ = false;
19+
bool close_sni_ = false; // 不发送sni信息.默认就是false.优先级高于sni_host_
20+
std::string sni_host_; // 发送假的sni信息
21+
};
22+
} // namespace hcpp
23+
24+
#endif /* SRC_HTTP_INTERCEPT */

0 commit comments

Comments
 (0)