Skip to content

Commit 5a9ebe8

Browse files
committed
feat: add HttpContext::Run method and improve middleware handling
1 parent b2fdfff commit 5a9ebe8

4 files changed

Lines changed: 67 additions & 13 deletions

File tree

src/cppnet/http/server/http_server.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@
99

1010
namespace cppnet {
1111

12+
void HttpContext::Run(int run_func_pos) {
13+
if (run_func_pos >= route_funcs_.size()) {
14+
return;
15+
}
16+
for (int i = run_func_pos; i < route_funcs_.size(); i++) {
17+
func_pos_ = i;
18+
route_funcs_[i](*this);
19+
if (!this->is_continue_) {
20+
break;
21+
}
22+
}
23+
}
24+
1225
int HttpGroup::GET(const std::string &path, HttpCallback callback,
1326
const std::vector<std::shared_ptr<HttpFilter>> &filters) {
1427
auto new_filters = filters;
@@ -358,8 +371,8 @@ void HttpServer::HandleRead(TcpServer &server, Socket &event_soc) {
358371
}
359372
auto path = req.route().GetPath();
360373
auto method = req.method();
361-
logger_->Info("req: " + HttpMethodUtil::ConvertToStr(method) + " " + path +
362-
" soc:" + std::to_string(event_soc.fd()));
374+
logger_->Debug("req: " + HttpMethodUtil::ConvertToStr(method) + " " + path +
375+
" soc:" + std::to_string(event_soc.fd()));
363376

364377
// step2:find route and run func
365378
HttpContext ctx(req, resp, soc);
@@ -379,14 +392,12 @@ void HttpServer::HandleRead(TcpServer &server, Socket &event_soc) {
379392
}
380393
}
381394
if (route_func) {
382-
route_func(ctx);
383-
if (!is_continue_) {
384-
return false;
385-
}
395+
ctx.route_funcs_.push_back(route_func);
386396
}
387397
}
388398
return true;
389399
});
400+
ctx.Run(0);
390401

391402
// step3:build resp and send
392403
if (resp.status_code() == HttpStatusCode::UNKNOWN) {
@@ -405,7 +416,7 @@ void HttpServer::HandleRead(TcpServer &server, Socket &event_soc) {
405416
soc->Close();
406417
return;
407418
}
408-
logger_->Info(
419+
logger_->Debug(
409420
"resp: " + HttpStatusCodeUtil::ConvertToStr(resp.status_code()) +
410421
" soc:" + std::to_string(event_soc.fd()) + kEndl);
411422
}

src/cppnet/http/server/http_server.hpp

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717

1818
namespace cppnet {
1919

20+
// advance statement
21+
class HttpServer;
22+
class HttpContext;
23+
using HttpCallback = std::function<void(HttpContext &)>;
24+
2025
class HttpContext {
2126
public:
2227
HttpContext(HttpReq &req, HttpResp &resp, std::shared_ptr<Socket> &soc)
@@ -29,9 +34,11 @@ class HttpContext {
2934
/*
3035
* @brief: whether continue, use in middware
3136
* */
32-
inline void Next() { is_continue_ = true; }
37+
inline void Next() {
38+
Run(func_pos_ + 1);
39+
is_continue_ = false;
40+
}
3341
inline void Abort() { is_continue_ = false; }
34-
inline bool is_continue() { return is_continue_; }
3542
/*
3643
* @brief: get inline data
3744
*/
@@ -52,15 +59,25 @@ class HttpContext {
5259
HttpResp &resp() { return resp_; }
5360
Socket &soc() { return *soc_; }
5461

62+
private:
63+
/*
64+
* @brief: run all route func,inside func
65+
*/
66+
void Run(int run_func_pos);
67+
5568
private:
5669
HttpReq &req_;
5770
HttpResp &resp_;
5871
std::shared_ptr<Socket> soc_ = nullptr;
59-
bool is_continue_ = false;
72+
bool is_continue_ = true;
6073
std::unordered_map<std::string, std::any> inline_data_;
61-
};
74+
std::vector<HttpCallback> route_funcs_;
75+
int func_pos_ = 0;
6276

63-
using HttpCallback = std::function<void(HttpContext &)>;
77+
private:
78+
// for call run func
79+
friend class HttpServer;
80+
};
6481

6582
struct HttpTrieData {
6683
HttpCallback callback = nullptr;

src/test/http/server/http_server_test.hpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ TEST(HttpServer, Middleware) {
232232
ctx.Set("temp", temp);
233233
ctx.Next();
234234
};
235+
atomic<int> abort_count = 0;
236+
auto abort_func = [&abort_count](HttpContext &ctx) {
237+
DEBUG("use abort");
238+
abort_count++;
239+
ctx.Abort();
240+
};
235241

236242
server.Use(count_func);
237243

@@ -247,6 +253,13 @@ TEST(HttpServer, Middleware) {
247253
},
248254
count_func});
249255

256+
server.GET("/abort", {[&](HttpContext &ctx) {
257+
ctx.resp().Text(HttpStatusCode::OK, "hello world");
258+
},
259+
abort_func,
260+
[&](HttpContext &ctx) { FATAL("not end after abort"); },
261+
abort_func});
262+
250263
// sync run server
251264
GO_JOIN([&] { server.Run(); });
252265

@@ -257,6 +270,13 @@ TEST(HttpServer, Middleware) {
257270
HttpReq req;
258271
HttpResp resp;
259272

273+
req.GET("/abort");
274+
rc = client.Send(req, resp);
275+
MUST_TRUE(rc == 0, client.err_msg());
276+
MUST_TRUE(resp.status_code() == HttpStatusCode::OK,
277+
"get wrong status code " +
278+
HttpStatusCodeUtil::ConvertToStr(resp.status_code()));
279+
260280
req.GET("/hello");
261281
rc = client.Send(req, resp);
262282
MUST_TRUE(rc == 0, client.err_msg());
@@ -266,7 +286,9 @@ TEST(HttpServer, Middleware) {
266286
MUST_TRUE(resp.body() == "hello world", "get wrong body " + resp.body());
267287
DEBUG("resp: " << resp.body());
268288

269-
MUST_TRUE(count == 2, "get wrong count " + to_string(count));
289+
MUST_TRUE(count == 4, "get wrong count " + to_string(count));
290+
MUST_TRUE(abort_count == 1,
291+
"get wrong abort count " + to_string(abort_count));
270292
}
271293

272294
#ifdef CPPNET_OPENSSL

src/test/log/file_logger_test.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ TEST(FileLogger, FirstWrite) {
6666
}
6767

6868
BENCHMARK(FileLogger, WriteRate) {
69+
#ifdef __APPLE__
70+
// not use mac for benchmark
71+
SKIP()
72+
#endif
6973
const std::string file_path = "file_benct_test.log";
7074
const std::string write_msg = "[test]:test-for-benchmark";
7175
auto logger = std::make_shared<FileLogger>();

0 commit comments

Comments
 (0)