85 lines
2.2 KiB
C
85 lines
2.2 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include <unistd.h>
|
||
#include "network/mongoose/mongoose.h"
|
||
|
||
#include "http_rel.h"
|
||
/* 接收状态辅助结构 */
|
||
struct recv_state {
|
||
char *request; // 完整请求字符串
|
||
int done; // 接收完成标志
|
||
int error; // 错误标志
|
||
};
|
||
|
||
/* mongoose 事件处理函数 */
|
||
static void http_recv_handler(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
|
||
{
|
||
struct recv_state *state = (struct recv_state *)fn_data;
|
||
|
||
switch (ev) {
|
||
case MG_EV_HTTP_MSG: {
|
||
struct mg_http_message *hm = (struct mg_http_message *)ev_data;
|
||
/* 分配内存并复制完整请求(头+体) */
|
||
state->request = malloc(hm->message.len + 1);
|
||
if (state->request) {
|
||
memcpy(state->request, hm->message.buf, hm->message.len);
|
||
state->request[hm->message.len] = '\0';
|
||
} else {
|
||
state->error = 1; // 内存不足
|
||
}
|
||
state->done = 1;
|
||
break;
|
||
}
|
||
case MG_EV_CLOSE:
|
||
case MG_EV_ERROR:
|
||
state->done = 1;
|
||
break;
|
||
}
|
||
}
|
||
|
||
char *recv_http_request(int cfd)
|
||
{
|
||
struct mg_mgr mgr;
|
||
struct mg_connection *c;
|
||
struct recv_state state = {0};
|
||
|
||
/* 初始化 mongoose 管理器 */
|
||
mg_mgr_init(&mgr);
|
||
|
||
/* 将已连接的 socket 包装成 mongoose 连接 */
|
||
c = mg_wrapfd(&mgr, cfd, http_recv_handler, &state); // ← 修复此处
|
||
|
||
/* 设置 5 秒超时 */
|
||
int64_t end_time = mg_millis() + 5000;
|
||
while (!state.done && mg_millis() < end_time) {
|
||
mg_mgr_poll(&mgr, 100);
|
||
}
|
||
|
||
/* 超时处理 */
|
||
if (!state.done) {
|
||
state.error = 1;
|
||
}
|
||
|
||
/* 清理 mongoose 资源(不会关闭原始 fd) */
|
||
mg_mgr_free(&mgr);
|
||
|
||
/* 出错时释放内存 */
|
||
if (state.error) {
|
||
free(state.request);
|
||
return NULL;
|
||
}
|
||
|
||
return state.request;
|
||
}
|
||
|
||
/* http_get_body 无需修改,保持原样 */
|
||
const char *http_get_body(const char *buf)
|
||
{
|
||
if (!buf) return NULL;
|
||
const char *sep = strstr(buf, "\r\n\r\n");
|
||
if (!sep) return NULL;
|
||
const char *body = sep + 4;
|
||
if (*body == '\0') return NULL;
|
||
return body;
|
||
} |