#include #include #include #include #include #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; }