Appearance
HTTP库
HTTP server库
基础使用
用于从 ESP-IDF 应用程序中发起 HTTP/S 请求
- 首先调用
esp_http_client_init()
,创建一个esp_http_client_handle_t
实例,即基于给定的esp_http_client_config_t
配置创建 HTTP 客户端句柄。此函数必须第一个被调用。若用户未明确定义参数的配置值,则使用默认值。
c
esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config);
- 其次调用
esp_http_client_perform()
,执行esp_http_client
的所有操作,包括打开连接、交换数据、关闭连接(如需要),同时在当前任务完成前阻塞该任务。所有相关的事件(在esp_http_client_config_t
中指定)将通过事件处理程序被调用。
esp_http_client_open -> esp_http_client_write -> esp_http_client_fetch_headers -> esp_http_client_read (and option) esp_http_client_close
cesp_err_t esp_http_client_perform(esp_http_client_handle_t client);
- 最后调用
esp_http_client_cleanup()
来关闭连接(如有),并释放所有分配给 HTTP 客户端实例的内存。此函数必须在操作完成后最后一个被调用。
c
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
int https_status = 0;
int64_t gzip_len = 0;
memset(dstBuf, 0, 1024);
esp_http_client_config_t config = {
.url = "https://devapi.qweather.com/v7/weather/now?location=101010100&key=7be28a7cc429438abf4f1d5feeb9c910",
.event_handler = _http_event_handler, //事件处理回调函数
.crt_bundle_attach = esp_crt_bundle_attach,
.user_data = local_response_buffer, // Pass address of local buffer to get response
}; //基础配置
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_perform(client);
//获取信息
https_status = esp_http_client_get_status_code(client);
gzip_len = esp_http_client_get_content_length(client);
if (err == ESP_OK) {
ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %"PRIu64,
https_status,
gzip_len);
} else {
ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));
}
esp_http_client_cleanup(client);
设置post数据
c
esp_err_t esp_http_client_set_post_field(esp_http_client_handle_t client, const char *data, int len);
int esp_http_client_get_post_field(esp_http_client_handle_t client, char **data);
通过post方式请求的数据,传入发送数据的缓存地址与长度,必须在
esp_http_client_perform
之前调用
设置header
c
esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char *key, const char *value);
esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char *key, char **value);
esp_err_t esp_http_client_delete_header(esp_http_client_handle_t client, const char *key);
设置、获取、删除请求头,可新增、删除或根据应用发送的数据类型来自定义请求文件类型来修改请求头
esp_http_client_set_header(client, "HeaderKey", "HeaderValue");
请求方式
c
//请求方式枚举
typedef enum {
HTTP_METHOD_GET = 0, /*!< HTTP GET Method */
HTTP_METHOD_POST, /*!< HTTP POST Method */
HTTP_METHOD_PUT, /*!< HTTP PUT Method */
HTTP_METHOD_PATCH, /*!< HTTP PATCH Method */
HTTP_METHOD_DELETE, /*!< HTTP DELETE Method */
HTTP_METHOD_HEAD, /*!< HTTP HEAD Method */
HTTP_METHOD_NOTIFY, /*!< HTTP NOTIFY Method */
HTTP_METHOD_SUBSCRIBE, /*!< HTTP SUBSCRIBE Method */
HTTP_METHOD_UNSUBSCRIBE,/*!< HTTP UNSUBSCRIBE Method */
HTTP_METHOD_OPTIONS, /*!< HTTP OPTIONS Method */
HTTP_METHOD_COPY, /*!< HTTP COPY Method */
HTTP_METHOD_MOVE, /*!< HTTP MOVE Method */
HTTP_METHOD_LOCK, /*!< HTTP LOCK Method */
HTTP_METHOD_UNLOCK, /*!< HTTP UNLOCK Method */
HTTP_METHOD_PROPFIND, /*!< HTTP PROPFIND Method */
HTTP_METHOD_PROPPATCH, /*!< HTTP PROPPATCH Method */
HTTP_METHOD_MKCOL, /*!< HTTP MKCOL Method */
HTTP_METHOD_MAX,
} esp_http_client_method_t;
esp_http_client_set_method(client, HTTP_METHOD_GET);//GET请求
HTTP事件
c
/**
* @brief HTTP configuration
*/
typedef struct {
const char *url; //url请求接口必须配置
/*!< HTTP URL, the information on the URL is most important, it overrides
the other fields below, if any */
const char *host; //服务器域名或ip地址
/*!< Domain or IP as string */
int port; //端口 http默认80 https 默认443
/*!< Port to connect, default depend on esp_http_client_transport_t (80 or 443) */
const char *username;
//用户名,认证使用
/*!< Using for Http authentication */
const char *password; //用户密码,认证使用
/*!< Using for Http authentication */
esp_http_client_auth_type_t auth_type; //认证方式
/*!< Http authentication type, see `esp_http_client_auth_type_t` */
const char *path; //路径
/*!< HTTP Path, if not set, default is `/` */
const char *query; //请求参数
/*!< HTTP query */
const char *cert_pem; //证书
/*!< SSL server certification, PEM format as string, if the client requires
to verify server */
const char *client_cert_pem;
/*!< SSL client certification, PEM format as string, if the server requires
to verify client */
const char *client_key_pem;
/*!< SSL client key, PEM format as string, if the server requires to verify client */
esp_http_client_method_t method; //请求方式 post get
/*!< HTTP Method */
int timeout_ms; //请求超时
/*!< Network timeout in milliseconds */
bool disable_auto_redirect;
/*!< Disable HTTP automatic redirects */
int max_redirection_count;
/*!< Max number of redirections on receiving HTTP redirect status code,
using default value if zero*/
int max_authorization_retries;
/*!< Max connection retries on receiving HTTP unauthorized status code,
using default value if zero. Disables authorization retry if -1*/
http_event_handle_cb event_handler; //可注册回调
/*!< HTTP Event Handle */
esp_http_client_transport_t transport_type; // 传输方式 tcp ssl
/*!< HTTP transport type, see `esp_http_client_transport_t` */
int buffer_size; //接收缓存大小
/*!< HTTP receive buffer size */
int buffer_size_tx; //发送缓存大小
/*!< HTTP transmit buffer size */
void *user_data; //http用户数据
/*!< HTTP user_data context */
bool is_async; //同步模式
/*!< Set asynchronous mode, only supported with HTTPS for now */
bool use_global_ca_store;
/*!< Use a global ca_store for all the connections in which this bool is set. */
bool skip_cert_common_name_check;
//跳过证书 /*!< Skip any validation of server certificate CN field */
} esp_http_client_config_t;
这些事件可以使用事件处理回调函数进行处理, 这些回调函数的默认数据类型如下
HTTP_EVENT_ERROR : esp_http_client_handle_t
HTTP_EVENT_ON_CONNECTED : esp_http_client_handle_t
HTTP_EVENT_HEADERS_SENT : esp_http_client_handle_t
HTTP_EVENT_ON_HEADER : esp_http_client_handle_t
HTTP_EVENT_ON_DATA : esp_http_client_on_data_t
HTTP_EVENT_ON_FINISH : esp_http_client_handle_t
HTTP_EVENT_DISCONNECTED : esp_http_client_handle_t
HTTP_EVENT_REDIRECT : esp_http_client_redirect_event_data_t
c
//事件回调
static esp_err_t _http_event_handle(esp_http_client_event_t *evt)
{
switch(evt->event_id) {
case HTTP_EVENT_ERROR://错误事件
ESP_LOGI(TAG, "HTTP_EVENT_ERROR");
break;
case HTTP_EVENT_ON_CONNECTED://连接成功事件
ESP_LOGI(TAG, "HTTP_EVENT_ON_CONNECTED");
break;
case HTTP_EVENT_HEADER_SENT://发送头事件
ESP_LOGI(TAG, "HTTP_EVENT_HEADER_SENT");
break;
case HTTP_EVENT_ON_HEADER://接收头事件
ESP_LOGI(TAG, "HTTP_EVENT_ON_HEADER");
printf("%.*s", evt->data_len, (char*)evt->data);
break;
case HTTP_EVENT_ON_DATA://接收数据事件
ESP_LOGI(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);
if (!esp_http_client_is_chunked_response(evt->client)) {
printf("%.*s", evt->data_len, (char*)evt->data);
}
break;
case HTTP_EVENT_ON_FINISH://会话完成事件
ESP_LOGI(TAG, "HTTP_EVENT_ON_FINISH");
break;
case HTTP_EVENT_DISCONNECTED://断开事件
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
break;
}
return ESP_OK;
}
cesp_http_client_config_t config = { .method = HTTP_METHOD_GET, //get请求 .url = "https://www.baidu.com/", //请求url .event_handler = _http_event_handle,//注册时间回调 };
在init 的时候设置回调函数
配置结构体
c
/**
* @brief HTTP configuration
*/
typedef struct {
const char *url; /*!< HTTP URL, the information on the URL
is most important, it overrides the other fields below, if any 网址*/
const char *host; /*!< Domain or IP as string ip地址*/
int port; /*!< Port to connect, default depend on
esp_http_client_transport_t (80 or 443) 端口*/
const char *username; /*!< Using for Http authentication */
const char *password; /*!< Using for Http authentication */
esp_http_client_auth_type_t auth_type; /*!< Http authentication type, see
`esp_http_client_auth_type_t` */
const char *path; /*!< HTTP Path, if not set, default is `/` */
const char *query; /*!< HTTP query 参数*/
const char *cert_pem; /*!< SSL server certification, PEM format
as string, if the client requires to verify server */
size_t cert_len; /*!< Length of the buffer pointed to by
cert_pem. May be 0 for null-terminated pem */
const char *client_cert_pem; /*!< SSL client certification, PEM format
as string, if the server requires to verify client */
size_t client_cert_len; /*!< Length of the buffer pointed to by
client_cert_pem. May be 0 for null-terminated pem */
const char *client_key_pem; /*!< SSL client key, PEM format as
string, if the server requires to verify client */
size_t client_key_len; /*!< Length of the buffer pointed to by
client_key_pem. May be 0 for null-terminated pem */
const char *client_key_password; /*!< Client key decryption password
string */
size_t client_key_password_len; /*!< String length of the password
pointed to by client_key_password */
#ifdef CONFIG_MBEDTLS_HARDWARE_ECDSA_SIGN
bool use_ecdsa_peripheral; /*!< Use ECDSA peripheral to use
private key. */
uint8_t ecdsa_key_efuse_blk; /*!< The efuse block where ECDSA key is stored. */
#endif
const char *user_agent; /*!< The User Agent string to send with
HTTP requests */
esp_http_client_method_t method; /*!< HTTP Method */
int timeout_ms; /*!< Network timeout in milliseconds */
bool disable_auto_redirect; /*!< Disable HTTP automatic
redirects */
int max_redirection_count; /*!< Max number of redirections on
receiving HTTP redirect status code, using default value if zero*/
int max_authorization_retries; /*!< Max connection retries on
receiving HTTP unauthorized status code, using default value if zero. Disables
authorization retry if -1*/
http_event_handle_cb event_handler; /*!< HTTP Event Handle事件处理函数*/
esp_http_client_transport_t transport_type; /*!< HTTP transport type, see
`esp_http_client_transport_t` */
int buffer_size; /*!< HTTP receive buffer size */
int buffer_size_tx; /*!< HTTP transmit buffer size */
void *user_data; /*!< HTTP user_data context
获取的信息*/
bool is_async; /*!< Set asynchronous mode, only
supported with HTTPS for now */
bool use_global_ca_store; /*!< Use a global ca_store for all
the connections in which this bool is set. */
bool skip_cert_common_name_check; /*!< Skip any validation of
server certificate CN field */
const char *common_name; /*!< Pointer to the string
containing server certificate common name.
If non-NULL, server certificate CN must match this name,
If NULL, server certificate CN must match hostname. */
esp_err_t (*crt_bundle_attach)(void *conf); /*!< Function pointer to
esp_crt_bundle_attach. Enables the use of certification
bundle for server verification, must be enabled in menuconfig */
bool keep_alive_enable; /*!< Enable keep-alive timeout */
int keep_alive_idle; /*!< Keep-alive idle time. Default is 5
(second) */
int keep_alive_interval; /*!< Keep-alive interval time. Default is
5 (second) */
int keep_alive_count; /*!< Keep-alive packet retry send count.
Default is 3 counts */
struct ifreq *if_name; /*!< The name of interface for data to go
through. Use the default interface without setting */
#if CONFIG_ESP_TLS_USE_SECURE_ELEMENT
bool use_secure_element; /*!< Enable this option to use secure element */
#endif
#if CONFIG_ESP_TLS_USE_DS_PERIPHERAL
void *ds_data; /*!< Pointer for digital signature peripheral
context, see ESP-TLS Documentation for more details */
#endif
} esp_http_client_config_t;
HTTP server实现
这是个在的项目基础上面添
c
#include <esp_http_server.h>
http_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_start
httpd_register_uri_handler
httpd_stop
c
//两个网页
const char mainpage[] = "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>你好</title>\r\n</head>\r\n<body>\r\n<div style=\"text-align: center;\">\r\n<h1>你好page1</h1>\r\n<hr size=3>\r\n<a href=\"index.html\">Back To Homepage</a>\r\n</div>\r\n</body>\r\n</html>\r\n";
const char mainpage2[] = "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n<meta charset=\"UTF-8\">\r\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\r\n<title>你好</title>\r\n</head>\r\n<body>\r\n<div style=\"text-align: center;\">\r\n<h1>你好page2</h1>\r\n<hr size=3>\r\n<a href=\"index.html\">Back To Homepage</a>\r\n</div>\r\n</body>\r\n</html>\r\n";
esp_err_t get_handler(httpd_req_t *req){
httpd_resp_send(req, mainpage, HTTPD_RESP_USE_STRLEN);
return ESP_OK;
}
esp_err_t post_handler(httpd_req_t *req){
//获取数据
char content[100];
int totallen = req->content_len;
size_t recv_size = MIN(req->content_len, sizeof(content));
int len = 0;
do{
len = httpd_req_recv(req, content, recv_size);
totallen-=len;
printf("%s\n", content);
}while(totallen > 0);
//回复数据
httpd_resp_send(req, mainpage2, strlen(mainpage2));
return ESP_OK;
}
//网页设置
httpd_uri_t uri_get = {
.uri = "geturl",
.method = HTTP_GET, //处理的信号
.handler = get_handler, //处理的函数
.user_ctx = NULL
};
httpd_uri_t uri_post = {
.uri = "posturl",
.method = HTTP_POST,
.handler = post_handler,
.user_ctx = NULL
};
httpd_handle_t server_handler(void){
//初始化
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_handle_t server = NULL;
if(httpd_start(&server, &config)==ESP_OK){
//注册两个网页
httpd_register_uri_handler(server, &uri_get);
httpd_register_uri_handler(server, &uri_post);
}
return server;
}
HTTP client实现
域名转IP函数
c
#incldue "lwip/netdb.h"
getaddrinfo