可用于 ESP32 设备异步提交 HTTP/HTTPS 请求,适合接口调用与数据传输。组件基于 ESP-IDF 队列驱动,支持全方法、分片回调、HTTPS 证书校验、chunked 编码和结果回调,无需调用方管理内存,大响应无需整体缓存。【此简介由AI生成】
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 11 天前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 11 天前 | ||
| 11 天前 |
HTTP Request / HTTP 请求组件
EN — Queue-based HTTP/HTTPS request component for ESP-IDF. Requests are submitted from any task, executed one by one in a dedicated background task, and the response body is delivered to your callback in chunks so that large responses never need to be buffered in RAM as a whole.
中文 — 面向 ESP-IDF 的队列式 HTTP/HTTPS 请求组件。任意任务都可以提交请求,由独立的后台任务串行执行,响应体分片回调给用户,大响应无需整体缓存在 RAM 中。
Features / 功能特性
EN
- Queue-based — submit a request from any task, never block the caller
- Chunked streaming callback — the response body is delivered piece by piece; per-request chunk size
- Result callback — every request reports success/failure plus the HTTP status code exactly once
- All HTTP methods — GET / POST / PUT / DELETE / HEAD / PATCH / OPTIONS
- Chunked transfer encoding aware — responses without
Content-Lengthare received correctly - HTTPS supported — server verification through the built-in ESP x509 certificate bundle
- Zero memory management for the caller — URL and body strings are copied internally
- Incomplete transfer detection — a response cut short by the peer is reported as a failure
中文
- 队列驱动:任意任务提交请求,调用方永不阻塞
- 分片流式回调:响应体分片回调,可逐片处理,支持自定义分片长度
- 结果回调:每次请求无论成功失败都回调一次,携带 HTTP 状态码
- 支持全部 HTTP 方法:GET / POST / PUT / DELETE / HEAD / PATCH / OPTIONS
- 兼容 chunked 编码:服务器不返回
Content-Length时也能正确接收 - 支持 HTTPS:使用 ESP 内置 x509 根证书包校验服务器
- 调用方不管内存:URL 与请求体由组件内部拷贝,可安全传入字符串常量
- 不完整传输检测:对端提前断开会被识别为失败,而不是当成正常结束
Requirements / 运行环境
EN
- ESP-IDF >= 5.0
- Targets: ESP32, ESP32-S2, ESP32-S3, ESP32-C3, ESP32-C6
中文
- ESP-IDF >= 5.0
- 支持目标:ESP32、ESP32-S2、ESP32-S3、ESP32-C3、ESP32-C6
Installation / 安装
EN — Add the component to your project's idf_component.yml:
中文 — 在工程的 idf_component.yml 中添加依赖:
dependencies:
junhui93/http_request: "^1.0.0"
EN — Or copy the http_request folder into your project's components/ directory.
中文 — 也可以将 http_request 文件夹拷贝到工程的 components/ 目录下。
Quick Start / 快速开始
#include "esp_log.h"
#include "http_request.h"
/* EN: Called once per received chunk. Not a C string — always use data_len. */
/* 中文: 每收到一片数据调用一次。注意不是完整字符串,请按 data_len 使用。 */
static void on_data(const char *data, int data_len, int64_t total_len)
{
ESP_LOGI("app", "got %d bytes (total %lld)", data_len, (long long)total_len);
printf("%.*s", data_len, data);
}
/* EN: Called exactly once per request, success or failure. */
/* 中文: 每次请求调用一次,成功或失败都会调用。 */
static void on_done(http_request_result_t result, int status_code)
{
ESP_LOGI("app", "request finished: result=%d, status=%d", (int)result, status_code);
}
void app_main(void)
{
/* ... connect to WiFi first ... */
/* EN: The queue depth decides how many requests may be pending. */
/* 中文: 队列深度决定最多允许积压多少个请求。 */
QueueHandle_t queue = xQueueCreate(4, sizeof(http_request_item_t));
http_request_init(queue);
http_request_get("http://example.com", on_data, on_done);
http_request_post("http://httpbin.org/post", "{\"hello\":\"world\"}", on_data, on_done);
}
EN — For full control use the http_request_config_t form:
中文 — 需要完整控制时使用 http_request_config_t:
const http_request_config_t config = {
.url = "https://example.com/api/v1/data",
.method = HTTP_METHOD_PUT,
.post_data = "{\"value\":123}",
.content_type = "application/json", /* optional, this is the default */
.chunk_size = 512, /* per-request receive chunk */
.timeout_ms = 10000, /* per-request timeout */
.on_data = on_data,
.on_done = on_done,
};
ESP_ERROR_CHECK(http_request_submit(&config));
API / 接口说明
| Function / 函数 | Description / 说明 |
|---|---|
http_request_init(QueueHandle_t queue) |
EN Start the background task. The queue must be created with xQueueCreate(depth, sizeof(http_request_item_t)). Repeated calls are ignored. 中文 启动后台任务。队列必须用 xQueueCreate(深度, sizeof(http_request_item_t)) 创建。重复调用会被忽略。 |
http_request_submit(&config) |
EN Submit a request. Strings are copied internally, the caller owns nothing. Returns ESP_OK / ESP_ERR_INVALID_ARG / ESP_ERR_INVALID_STATE / ESP_ERR_TIMEOUT (queue full) / ESP_ERR_NO_MEM. 中文 提交请求,字符串由组件内部拷贝,调用方不负责释放。返回 ESP_OK / ESP_ERR_INVALID_ARG / ESP_ERR_INVALID_STATE / ESP_ERR_TIMEOUT(队列满)/ ESP_ERR_NO_MEM。 |
http_request_get(url, on_data, on_done) |
EN Convenience wrapper for a GET request. 中文 GET 请求便捷封装。 |
http_request_post(url, post_data, on_data, on_done) |
EN Convenience wrapper for a POST request. 中文 POST 请求便捷封装。 |
http_request_deinit(void) |
EN Delete the task, drain the queue and release the HTTP client. Call only when no request is running. 中文 删除任务、清空队列残留内存并释放 HTTP 客户端。请在确认没有请求正在执行时调用。 |
Callbacks / 回调
EN
http_request_callback_t(data, data_len, total_len)— invoked for every received chunk.total_lenis-1when the server uses chunked encoding. The buffer is terminated with'\0', but always honourdata_lenbecause binary payloads may contain'\0'.http_request_done_callback_t(result, status_code)— invoked once per request.status_codeis0when no response header was received.- Both callbacks run in the HTTP task context — do not block for long inside them.
中文
http_request_callback_t(data, data_len, total_len)— 每收到一片数据调用一次。服务器使用 chunked 编码时total_len为-1。缓冲区末尾已补'\0',但仍请以data_len为准,因为二进制数据里可能含'\0'。http_request_done_callback_t(result, status_code)— 每次请求调用一次。未取到响应头时status_code为0。- 两个回调都在 HTTP 任务上下文中执行,请不要在里面长时间阻塞。
Result codes / 结果码
| Value / 取值 | Meaning / 含义 |
|---|---|
HTTP_REQUEST_OK |
EN finished, check status_code 中文 请求完成,具体看 status_code |
HTTP_REQUEST_FAIL_PARAM |
EN invalid URL 中文 链接非法 |
HTTP_REQUEST_FAIL_NO_MEM |
EN out of memory 中文 内存不足 |
HTTP_REQUEST_FAIL_OPEN |
EN connection could not be established 中文 建立连接失败 |
HTTP_REQUEST_FAIL_WRITE |
EN request body could not be sent 中文 请求体发送失败 |
HTTP_REQUEST_FAIL_HEADER |
EN response header could not be read 中文 获取响应头失败 |
HTTP_REQUEST_FAIL_RECV |
EN body read error or incomplete transfer 中文 响应体读取出错或不完整 |
Notes / 注意事项
EN
http_request_deinit()deletes the task, so do not call it while a request is in flight.- The HTTP client handle is created once and reused.
esp_http_client_close()is called after every request to avoid reusing a connection that the server has already dropped, which means HTTP keep-alive is not used — each request performs a new TCP connect (and a new TLS handshake for HTTPS). If you need connection reuse, keep the connection open on success and add retry logic for stale sockets. - Requests are executed strictly one by one. A slow request blocks the ones behind it in the queue.
- A response with a non-2xx status code is still delivered to
on_data; checkstatus_codeinon_done.
中文
http_request_deinit()会删除后台任务,请不要在有请求正在执行时调用。- HTTP 客户端句柄常驻复用,但每轮请求结束都会调用
esp_http_client_close(),以避免复用到已被服务器关闭的连接。因此没有使用 HTTP 长连接复用:每次请求都会重新建立 TCP 连接(HTTPS 还要重新握手)。如果需要连接复用,需要在成功时保留连接,并为失效连接的场景增加重试逻辑。 - 请求严格串行执行,一个慢请求会阻塞排在它后面的请求。
- 非 2xx 的响应同样会回调
on_data,请在on_done里检查status_code。
Example / 示例工程
EN — See examples/basic. It connects to WiFi via the ESP-IDF example connection helper, then issues one GET and one POST request.
中文 — 见 examples/basic,通过 ESP-IDF 示例连接组件联网后,发起一次 GET 和一次 POST 请求。
cd examples/basic
idf.py set-target esp32
idf.py menuconfig # Example Connection Configuration -> WiFi SSID / Password
idf.py build flash monitor
License / 许可证
EN — MIT License, see LICENSE.
中文 — MIT 协议,详见 LICENSE。