修复部分bug

This commit is contained in:
2025-11-21 18:02:37 +08:00
parent 26dac05e5b
commit 08589dfe79
7 changed files with 153 additions and 120 deletions

View File

@ -3,7 +3,7 @@
#include <string.h>
#include <unistd.h>
#include "network/mongoose/mongoose.h"
#include "tools/log/log.h"
#include "http_rel.h"
/* 接收状态辅助结构 */
struct recv_state {
@ -12,10 +12,11 @@ struct recv_state {
int error; // 错误标志
};
/* mongoose 事件处理函数 */
static void http_recv_handler(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
static void http_recv_handler(struct mg_connection *c, int ev, void *ev_data)
{
struct recv_state *state = (struct recv_state *)fn_data;
// 从连接对象获取用户数据
struct recv_state *state = (struct recv_state *)c->fn_data;
switch (ev) {
case MG_EV_HTTP_MSG: {
@ -48,7 +49,7 @@ char *recv_http_request(int cfd)
mg_mgr_init(&mgr);
/* 将已连接的 socket 包装成 mongoose 连接 */
c = mg_wrapfd(&mgr, cfd, http_recv_handler, &state); // ← 修复此处
c = mg_wrapfd(&mgr, cfd, http_recv_handler, &state);
/* 设置 5 秒超时 */
int64_t end_time = mg_millis() + 5000;
@ -66,7 +67,12 @@ char *recv_http_request(int cfd)
/* 出错时释放内存 */
if (state.error) {
free(state.request);
free(state.request); // 安全释放free(NULL) 是安全的)
return NULL;
}
/* 确保返回的请求不为空 */
if (!state.request) {
return NULL;
}
@ -82,4 +88,93 @@ const char *http_get_body(const char *buf)
const char *body = sep + 4;
if (*body == '\0') return NULL;
return body;
}
}
/**
* @brief 初始化HTTP监听socket所有错误通过logmanager记录
* @param port 监听端口
* @param logger 日志管理器实例指针
* @return 成功返回监听fd失败返回-1并记录日志
*/
int init_http_network(int port, log_manager *logger)
{
logs *log;
int fd;
/* 1. 创建socket */
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd == -1) {
log = malloc(sizeof(logs));
// cppcheck-suppress uninitdata
snprintf(log->log, sizeof(log->log),
"[FATAL] socket() failed: %s", strerror(errno));
logger->in_log(log, logger);
return -1;
}
/* 2. 设置SO_REUSEADDR避免TIME_WAIT状态导致bind失败 */
int opt = 1;
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == -1) {
log = malloc(sizeof(logs));
snprintf(log->log, sizeof(log->log),
"[ERROR] setsockopt(SO_REUSEADDR) on fd=%d failed: %s",
fd, strerror(errno));
logger->in_log(log, logger);
close(fd);
return -1;
}
/* 3. 设置为非阻塞模式配合epoll使用 */
int flags = fcntl(fd, F_GETFL, 0);
if (flags == -1) {
log = malloc(sizeof(logs));
snprintf(log->log, sizeof(log->log),
"[ERROR] fcntl(F_GETFL) on fd=%d failed: %s", fd, strerror(errno));
logger->in_log(log, logger);
close(fd);
return -1;
}
if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) == -1) {
log = malloc(sizeof(logs));
snprintf(log->log, sizeof(log->log),
"[ERROR] fcntl(O_NONBLOCK) on fd=%d failed: %s", fd, strerror(errno));
logger->in_log(log, logger);
close(fd);
return -1;
}
/* 4. 绑定到指定端口 */
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有网卡
if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
log = malloc(sizeof(logs));
snprintf(log->log, sizeof(log->log),
"[FATAL] bind(port %d) failed: %s (fd=%d)",
port, strerror(errno), fd);
logger->in_log(log, logger);
close(fd);
return -1;
}
/* 5. 开始监听 */
if (listen(fd, 10) == -1) {
log = malloc(sizeof(logs));
snprintf(log->log, sizeof(log->log),
"[FATAL] listen(fd=%d, backlog=10) failed: %s",
fd, strerror(errno));
logger->in_log(log, logger);
close(fd);
return -1;
}
/* 6. 成功日志 */
log = malloc(sizeof(logs));
snprintf(log->log, sizeof(log->log),
"[HTTP] Successfully listening on port %d (fd=%d)", port, fd);
logger->in_log(log, logger);
return fd;
}