esp_http_request:基于 ESP-IDF 的队列式 HTTP/HTTPS 请求组件项目

可用于 ESP32 设备异步提交 HTTP/HTTPS 请求,适合接口调用与数据传输。组件基于 ESP-IDF 队列驱动,支持全方法、分片回调、HTTPS 证书校验、chunked 编码和结果回调,无需调用方管理内存,大响应无需整体缓存。【此简介由AI生成】

分支1Tags0
文件最后提交记录最后更新时间
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-Length are 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_len is -1 when the server uses chunked encoding. The buffer is terminated with '\0', but always honour data_len because binary payloads may contain '\0'.
  • http_request_done_callback_t(result, status_code) — invoked once per request. status_code is 0 when 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; check status_code in on_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。

项目介绍

可用于 ESP32 设备异步提交 HTTP/HTTPS 请求,适合接口调用与数据传输。组件基于 ESP-IDF 队列驱动,支持全方法、分片回调、HTTPS 证书校验、chunked 编码和结果回调,无需调用方管理内存,大响应无需整体缓存。【此简介由AI生成】

定制我的领域