https://github.com/suconghou/httplib
simple async http server
https://github.com/suconghou/httplib
async event-loop http-parser http-server poll webserver
Last synced: 10 months ago
JSON representation
simple async http server
- Host: GitHub
- URL: https://github.com/suconghou/httplib
- Owner: suconghou
- Created: 2025-03-13T02:30:01.000Z (11 months ago)
- Default Branch: main
- Last Pushed: 2025-04-02T15:09:17.000Z (10 months ago)
- Last Synced: 2025-04-02T15:32:13.096Z (10 months ago)
- Topics: async, event-loop, http-parser, http-server, poll, webserver
- Language: C++
- Homepage:
- Size: 115 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# httplib
基于poll实现的单线程异步HTTP服务器库
基于 https://github.com/suconghou/poll_server 的异步IO
使用状态机解析HTTP协议,支持 HTTP/1.0和HTTP/1.1协议
- 异步非阻塞I/O
- 支持GET、POST、PUT、PATCH、DELETE等HTTP方法
- 支持正则路由匹配
- 支持chunked传输编码
- 内置URL解码和路径解析
- 支持请求头、请求体、响应头的处理
- 支持文件流传输
- 支持keep-alive连接
- 解析query和cookie的辅助方法
- 支持chunked请求的trailer headers
## 快速开始
```cpp
#include "httplib.cpp"
int main() {
Server server;
// 注册路由
server.get("/hello", [](Request* req, Response* res) {
res->status(200)->end("Hello World");
});
// 启动服务器
server.start(8080, [] { return 3500; });
return 0;
}
```
## API 介绍
### Server 类
- **get**: 注册GET请求的路由。
```cpp
server.get("/path", [](Request* req, Response* res) {
// 处理逻辑
});
```
- **post**: 注册POST请求的路由。
```cpp
server.post("/path", [](Request* req, Response* res) {
// 处理逻辑
});
```
- **put**: 注册PUT请求的路由。
```cpp
server.put("/path", [](Request* req, Response* res) {
// 处理逻辑
});
```
- **patch**: 注册PATCH请求的路由。
```cpp
server.patch("/path", [](Request* req, Response* res) {
// 处理逻辑
});
```
- **delete_**: 注册DELETE请求的路由。
```cpp
server.delete_("/path", [](Request* req, Response* res) {
// 处理逻辑
});
```
- **options**: 注册OPTIONS请求的路由。
```cpp
server.options("/path", [](Request* req, Response* res) {
// 处理逻辑
});
```
- **start**: 启动服务器,监听指定端口。
```cpp
server.start(8080, [] { return 3500; });
```
### 正则路由及捕获参数
- 使用正则表达式注册路由,并捕获路径参数。
```cpp
server.get("/user/(\\d+)", [](Request* req, Response* res) {
std::string userId = req->params[1]; // 捕获的参数
res->status(200)->end("User ID: " + userId);
});
```
### bind_use_body_handler 用法示例
- 注册一个处理请求体的回调函数,并与路由注册结合使用。
```cpp
server.post("/submit", Server::bind_use_body_handler([](Request* req, Response* res, const char* data, size_t length) {
// 处理请求体数据
std::string body(data, length);
res->end("Received: " + body);
}));
```
### chunked 传输编码说明
- 在响应头中未指定`Content-Length`时,服务器会自动使用chunked编码。
- 适用于流式传输或动态生成内容的场景。
### Request 类
- **method**: 请求方法(如GET、POST)。
- **uri**: 请求URI。
- **version**: http版本。
- **path**: 请求的path部分。
- **rawQuery**: 请求的query部分。
- **params**: 路由参数
- **headers**: 请求头信息。
- **trailers**: chunked请求的trailer headers
- **query()**: 获取解析后的查询参数。
- **cookies()**: 获取解析后的Cookie。
### Response 类
- **status**: 设置响应状态码。
```cpp
res->status(200);
```
- **end**: 结束响应并发送数据。
```cpp
res->end("Response Body");
```
- **stream**: 以流的方式发送数据。
```cpp
res->stream(fileReader);
```
- **length**: 设置响应的内容长度。
- 如果设置了`length`,则使用普通编码;如果未设置,则使用chunked编码。
```cpp
res->length(1024);
```
- **write**: 写入响应体数据。
- 在响应头发送后,使用此方法写入数据。
```cpp
res->write("Partial Response");
```
- **writeHead**: 发送响应头。
- 在发送响应体之前调用此方法。
```cpp
res->writeHead(200, {{"Content-Type", "text/plain"}});
```
## 构建
编译时需先将 https://github.com/suconghou/poll_server 的`poll.cpp`文件拷贝到当前目录。
`main.cpp` 和 `httplibext.cpp` 为一个示例的HTTP静态文件服务器,支持目录浏览和Range请求。
```bash
g++ -Wall -std=c++20 -O1 main.cpp
```
```bash
g++ -Wall -std=c++20 -flto=auto -static-libstdc++ -static-libgcc --static -Wl,-Bstatic,--gc-sections -O3 -ffunction-sections -fdata-sections main.cpp -o fileserver
```