Files
chat_rebot-connect-with-one…/c/network/http_rel.c
2025-10-03 10:57:53 +08:00

81 lines
2.0 KiB
C

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "http_rel.h"
const char *http_get_body(const char *buf)
{
if (!buf) return NULL;
/* 找到 header 与 body 之间的空行 "\r\n\r\n" */
const char *sep = strstr(buf, "\r\n\r\n");
if (!sep) return NULL; /* 格式错误 */
const char *body = sep + 4; /* 跳过 "\r\n\r\n" */
/* 简单判断:如果后面还有数据,就认为是 body */
if (*body == '\0') return NULL; /* 没有 body */
return body;
}
/* 一次性读完一个 HTTP 请求,返回 malloc 得到的完整字符串(含头+体),调用者 free。
返回 NULL 表示读取出错或内存不足。
*/
char *recv_http_request(int cfd)
{
char head[8192];
int body_len = 0;
/* 1. 读头部到 \r\n\r\n */
size_t n = 0;
while (n < sizeof(head)) {
if (read(cfd, head + n, 1) != 1) goto err;
if (n >= 3 && memcmp(head + n - 3, "\r\n\r", 3) == 0) {
if (read(cfd, head + n, 1) != 1) goto err; /* 再吃一个 \n */
++n;
break;
}
++n;
}
head[n] = 0;
/* 2. 解析 Content-Length */
const char *p = head;
while ((p = strchr(p, '\n')) != NULL) {
if (sscanf(p, "\nContent-Length: %d", &body_len) == 1) break;
++p;
}
/* 3. 读 body */
char *body = NULL;
if (body_len > 0) {
body = malloc(body_len + 1);
if (!body) goto err;
size_t got = 0;
while (got < (size_t)body_len) {
ssize_t rd = read(cfd, body + got, body_len - got);
if (rd <= 0) { free(body); goto err; }
got += rd;
}
body[got] = 0;
}
/* 4. 拼成完整字符串 */
char *full = malloc(n + (body_len ? body_len : 0) + 1);
if (!full) { free(body); goto err; }
memcpy(full, head, n);
if (body_len) memcpy(full + n, body, body_len);
full[n + body_len] = 0;
free(body);
return full;
err:
return NULL;
}