cocoon/http.h
xfy911 ea5436febb feat(compression): 添加 Brotli 压缩支持,优先于 Gzip
- static.c: 新增 brotli_compress(),使用 libbrotlienc(质量 11,窗口 22)
- static_serve_file(): 优先 Brotli,回退 Gzip,二进制文件跳过
- http.c: 解析 Accept-Encoding: br,http_request_t 新增 accept_brotli
- cocoon.h: cocoon_config_t 新增 brotli_enabled(默认 true)
- config.c/h: 解析 brotli_enabled JSON 字段,config_merge() 新增 has_brotli_enabled
- main.c: --no-brotli 命令行选项
- server.c: 连接结构体新增 brotli_enabled
- Makefile: 链接 -lbrotlienc
- 单元测试: test_static.c 新增 4 个 Brotli 测试;test_config.c 新增 brotli 配置测试
- 集成测试: 新增 5 项 Brotli 测试(br 压缩、优先策略、图片不压缩)
- cocoon.json: 添加 brotli_enabled 字段
- README: 更新特性描述、curl 示例、命令行参数、路线图
- 113 个单元测试全部通过,37 项集成测试全部通过
2026-06-04 06:19:42 +08:00

136 lines
3.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* http.h - HTTP 解析模块接口
*
* 提供 HTTP 请求解析和响应构建的接口。
*
* @author xfy
*/
#ifndef COCOON_HTTP_H
#define COCOON_HTTP_H
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
/* === HTTP 方法 === */
typedef enum {
HTTP_GET,
HTTP_HEAD,
HTTP_POST,
HTTP_PUT,
HTTP_DELETE,
HTTP_OPTIONS,
HTTP_UNKNOWN
} http_method_t;
/* === HTTP 请求 === */
#define HTTP_MAX_PATH 4096
#define HTTP_MAX_HEADERS 32
#define HTTP_HEADER_NAME_MAX 64
#define HTTP_HEADER_VALUE_MAX 1024
#define HTTP_MAX_BODY 8388608 /* 8MB 最大请求体 */
typedef struct {
http_method_t method;
char path[HTTP_MAX_PATH];
char version[16];
/* 请求头 */
struct {
char name[HTTP_HEADER_NAME_MAX];
char value[HTTP_HEADER_VALUE_MAX];
} headers[HTTP_MAX_HEADERS];
int num_headers;
/* 常用头快速访问 */
int64_t content_length;
bool keep_alive;
bool has_range;
int64_t range_start;
int64_t range_end;
/* 缓存相关头 */
char if_none_match[64];
char if_modified_since[64];
bool has_if_none_match;
bool has_if_modified_since;
/* 压缩相关头 */
bool accept_gzip; /* 客户端支持 gzip */
bool accept_brotli; /* 客户端支持 brotli */
bool accept_deflate; /* 客户端支持 deflate */
bool has_accept_encoding;
/* 请求体 */
char *body; /* 请求体数据(动态分配) */
size_t body_len; /* 请求体实际长度 */
char content_type[HTTP_HEADER_VALUE_MAX]; /* 解析后的 Content-Type */
} http_request_t;
/* === HTTP 响应 === */
typedef struct {
int status_code;
const char *status_text;
const char *content_type;
int64_t content_length;
bool keep_alive;
bool has_range;
int64_t range_start;
int64_t range_end;
int64_t total_length;
/* 缓存 */
const char *etag;
const char *last_modified;
/* 压缩 */
const char *content_encoding;
} http_response_t;
/* === API === */
/**
* http_parse_request - 从缓冲区解析 HTTP 请求
*
* @param buf 输入缓冲区
* @param len 缓冲区长度
* @param req 输出请求结构体
* @return 成功解析的字节数,< 0 表示错误(-1 = 不完整,-2 = 格式错误)
*/
int http_parse_request(const char *buf, size_t len, http_request_t *req);
/**
* http_format_response_header - 格式化响应头到缓冲区
*
* @param buf 输出缓冲区
* @param buf_size 缓冲区大小
* @param resp 响应信息
* @return 写入的字节数,< 0 表示缓冲区不足
*/
int http_format_response_header(char *buf, size_t buf_size, const http_response_t *resp);
/**
* http_method_str - HTTP 方法转字符串
*
* @param method HTTP 方法
* @return 方法字符串(如 "GET"
*/
const char *http_method_str(http_method_t method);
/**
* http_request_free - 释放 HTTP 请求中动态分配的资源
*
* @param req 请求结构体
*/
void http_request_free(http_request_t *req);
/**
* http_mime_type - 根据文件扩展名获取 MIME 类型
*
* @param path 文件路径
* @return MIME 类型字符串
*/
const char *http_mime_type(const char *path);
#endif /* COCOON_HTTP_H */