乐鑫ESP32 https post请求

2024-02-07 08:59
文章标签 https 请求 post esp32 乐鑫

本文主要是介绍乐鑫ESP32 https post请求,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

项目中遇到关于https的应用,例程中只有关于https的get,没有post,原以为只需要简单改动一下就能使用,但是实际调试过程中,发现不能用。 现在记录一下,防止忘记。
原例程是参照https_request_example_main.c文件中

https get

void app_main(void)
{ESP_ERROR_CHECK( nvs_flash_init() );ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());/* This helper function configures Wi-Fi or Ethernet, as selected in menuconfig.* Read "Establishing Wi-Fi or Ethernet Connection" section in* examples/protocols/README.md for more information about this function.*/ESP_ERROR_CHECK(example_connect());xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL);
}

这个是主函数。其中的
ESP_ERROR_CHECK( nvs_flash_init() );
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(example_connect());
分别做了flash初始化,网络初始化,回调事件创建,以及网络连接。
如果已经建立了网络连接可以只调用ESP_ERROR_CHECK(esp_event_loop_create_default());
xTaskCreate(&https_get_task, “https_get_task”, 8192, NULL, 5, NULL);
这两个,就可以直接进行https的相关操作。

static void https_get_task(void *pvParameters)
{char buf[512];int ret, len;while(1) {esp_tls_cfg_t cfg = {.crt_bundle_attach = esp_crt_bundle_attach,};struct esp_tls *tls = esp_tls_conn_http_new(WEB_URL, &cfg);if(tls != NULL) {ESP_LOGI(TAG, "Connection established...");} else {ESP_LOGE(TAG, "Connection failed...");goto exit;}size_t written_bytes = 0;do {ret = esp_tls_conn_write(tls,REQUEST + written_bytes,strlen(REQUEST) - written_bytes);if (ret >= 0) {ESP_LOGI(TAG, "%d bytes written", ret);written_bytes += ret;} else if (ret != ESP_TLS_ERR_SSL_WANT_READ  && ret != ESP_TLS_ERR_SSL_WANT_WRITE) {ESP_LOGE(TAG, "esp_tls_conn_write  returned 0x%x", ret);goto exit;}} while(written_bytes < strlen(REQUEST));ESP_LOGI(TAG, "Reading HTTP response...");do{len = sizeof(buf) - 1;bzero(buf, sizeof(buf));ret = esp_tls_conn_read(tls, (char *)buf, len);if(ret == ESP_TLS_ERR_SSL_WANT_WRITE  || ret == ESP_TLS_ERR_SSL_WANT_READ)continue;if(ret < 0){ESP_LOGE(TAG, "esp_tls_conn_read  returned -0x%x", -ret);break;}if(ret == 0){ESP_LOGI(TAG, "connection closed");break;}len = ret;ESP_LOGD(TAG, "%d bytes read", len);/* Print response directly to stdout as it is read */for(int i = 0; i < len; i++) {putchar(buf[i]);}} while(1);exit:esp_tls_conn_delete(tls);putchar('\n'); // JSON output doesn't have a newline at endstatic int request_count;ESP_LOGI(TAG, "Completed %d requests", ++request_count);for(int countdown = 10; countdown >= 0; countdown--) {ESP_LOGI(TAG, "%d...", countdown);vTaskDelay(1000 / portTICK_PERIOD_MS);}ESP_LOGI(TAG, "Starting again!");}
}
https_get_task()函数中,esp_tls_conn_http_new()是通过url建立https的连接。esp_tls_conn_write()完成传输,即通过TCP协议层传输https的header

http的协议格式
例程中的协议头是这样的。

static const char *REQUEST = "GET " WEB_URL " HTTP/1.0\r\n""Host: "WEB_SERVER"\r\n""User-Agent: esp-idf/1.0 esp32\r\n""\r\n";

这里的WEB_SERVER,WEB_URL是用define定义的。(有一点需要注意的是,这种定义方式在Visual Studio中的C/C++会报错。)
下面的ret = esp_tls_conn_write(tls,
REQUEST + written_bytes,
strlen(REQUEST) - written_bytes);
是循环将header传输到对应的服务器上。
写完以后,开始等待http的回复。
后面进行回复读取:
bzero(buf, sizeof(buf));
ret = esp_tls_conn_read(tls, (char *)buf, len);
bzero()类似于memset(),不过在http当中用的比较多。

https post

但是上面的例程是进行https get请求的,若进行post请求呢?
大多数情况下,post请求都是需要上传参数的。不管是text,xml,还是json。
body应该怎么填的?一开始我是这样做的。

const char *REQUEST = "POST " WEB_URL " HTTP/1.0\r\n""Host: " WEB_SERVER "\r\n""User-Agent: Mozilla/5.0\r\n""Content-Type:application/json\r\n""Accept-Encoding: gzip, deflate\r\n""Connection:keep-alive\r\n""Content-Length:360\r\n""Accept:*/*\r\n""\r\n";"{\r\n	\"appId\":	\"intelligent_cabinet\",\r\n	\"requestId\":	\"01831016-b18c-4a1e-a571\",\r\n	\"version\":	\"2.0\",\r\n	\"timestamp\":	\"1617325383000\",\r\n	\"sign\":	\"ZDJlNGJmZDQ4Y2MyOWNmOTU1ZDcyNTRkNzc3NDQwMzQwNzU1MGY2MQ==\"\r\n}";

格式是按照http的格式填充的,实际测试当中,发现body请求体并没有传到服务器。
后问了乐鑫的FAE,提示可以参考esp_http_client_example.c例程测试。
但是该例程当中也有不少的坑。
首先,这个例程当中包含多个请求方式,并且相当杂乱。

static void http_test_task(void *pvParameters)
{http_rest_with_url();http_rest_with_hostname_path();
#if CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTHhttp_auth_basic();http_auth_basic_redirect();
#endifhttp_auth_digest();http_relative_redirect();http_absolute_redirect();https_with_url();https_with_hostname_path();http_redirect_to_https();http_download_chunk();http_perform_as_stream_reader();https_async();https_with_invalid_url();http_native_request();ESP_LOGI(TAG, "Finish http example");vTaskDelete(NULL);
}

开始使用这个https_with_url();设置了一下,发现用不了,后面又调整了几次,终于发送成功了。
改的例程如下:

void https_with_url(void)
{char *outJson=NULL;char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};char request[512]={'\0'};outJson=rebuild_json();sprintf(request,"%s",outJson);free(outJson);esp_netif_init();esp_event_loop_create_default();esp_http_client_config_t config = {.url ="https://daily-robot.ele.me/bdi.robot_scheduler/v2/openapi/cater/order/prepared",.event_handler = http_event_handler,};esp_http_client_handle_t client = esp_http_client_init(&config);esp_http_client_set_method(client, HTTP_METHOD_POST);esp_http_client_set_header(client, "Content-Type", "application/json");esp_err_t err = esp_http_client_open(client, strlen(request));printf("https_with_url request =%s\n",request);if (err != ESP_OK) {ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));} else {int wlen = esp_http_client_write(client, request, strlen(request));if (wlen < 0) {ESP_LOGE(TAG, "Write failed");}esp_err_t err = esp_http_client_perform(client);if (err == ESP_OK) {ESP_LOGI(TAG, "HTTPS Status = %d, content_length = %d",esp_http_client_get_status_code(client),esp_http_client_get_content_length(client));} else {ESP_LOGE(TAG, "Error perform http request %s", esp_err_to_name(err));}}esp_http_client_cleanup(client);
}

http回复的可以在http_event_handler()函数中的
case HTTP_EVENT_ON_DATA:
后面打印一下:

case HTTP_EVENT_ON_DATA:ESP_LOGD(TAG, "HTTP_EVENT_ON_DATA, len=%d", evt->data_len);/**  Check for chunked encoding is added as the URL for chunked encoding used in this example returns binary data.*  However, event handler can also be used in case chunked encoding is used.*/if (!esp_http_client_is_chunked_response(evt->client)) {// If user_data buffer is configured, copy the response into the bufferif (evt->user_data) {memcpy(evt->user_data + output_len, evt->data, evt->data_len);} else {if (output_buffer == NULL) {output_buffer = (char *) malloc(esp_http_client_get_content_length(evt->client));output_len = 0;if (output_buffer == NULL) {ESP_LOGE(TAG, "Failed to allocate memory for output buffer");return ESP_FAIL;}}memcpy(output_buffer + output_len, evt->data, evt->data_len);}output_len += evt->data_len;}printf("output_buffer=%s\n",output_buffer);break;

可以看收到了回复信息
postman测试回复

跟postman上面的测试结果一致,后面就可以添加自己的数据处理拉,完成。
源码在这里:乐鑫ESP32 http post请求源码修改

这篇关于乐鑫ESP32 https post请求的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687206

相关文章

ESP32 esp-idf esp-adf环境安装及.a库创建与编译

简介 ESP32 功能丰富的 Wi-Fi & 蓝牙 MCU, 适用于多样的物联网应用。使用freertos操作系统。 ESP-IDF 官方物联网开发框架。 ESP-ADF 官方音频开发框架。 文档参照 https://espressif-docs.readthedocs-hosted.com/projects/esp-adf/zh-cn/latest/get-started/index

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

乐鑫 Matter 技术体验日|快速落地 Matter 产品,引领智能家居生态新发展

随着 Matter 协议的推广和普及,智能家居行业正迎来新的发展机遇,众多厂商纷纷投身于 Matter 产品的研发与验证。然而,开发者普遍面临技术门槛高、认证流程繁琐、生产管理复杂等诸多挑战。  乐鑫信息科技 (688018.SH) 凭借深厚的研发实力与行业洞察力,推出了全面的 Matter 解决方案,包含基于乐鑫 SoC 的 Matter 硬件平台、基于开源 ESP-Matter SDK 的一

iOS HTTPS证书不受信任解决办法

之前开发App的时候服务端使用的是自签名的证书,导致iOS开发过程中调用HTTPS接口时,证书不被信任 - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAu

探索蓝牙协议的奥秘:用ESP32实现高质量蓝牙音频传输

蓝牙(Bluetooth)是一种短距离无线通信技术,广泛应用于各种电子设备之间的数据传输。自1994年由爱立信公司首次提出以来,蓝牙技术已经经历了多个版本的更新和改进。本文将详细介绍蓝牙协议,并通过一个具体的项目——使用ESP32实现蓝牙音频传输,来展示蓝牙协议的实际应用及其优点。 蓝牙协议概述 蓝牙协议栈 蓝牙协议栈是蓝牙技术的核心,定义了蓝牙设备之间如何进行通信。蓝牙协议

axios全局封装AbortController取消重复请求

为什么? 问题:为什么axios要配置AbortController?防抖节流不行吗? 分析: 防抖节流本质上是用延时器来操作请求的。防抖是判断延时器是否存在,如果存在,清除延时器,重新开启一个延时器,只执行最后一次请求。节流呢,是判断延时器是否存在,如果存在,直接return掉,直到执行完这个延时器。事实上,这些体验感都不算友好,因为对于用户来说,得等一些时间,尤其是首次请求,不是那么流畅

Xcode7 Https 在plist上添加NSAppTransportSecurity -NSAllowsAtbritraryLoads

Xcode7 创建HTTP请求报错 字数825  阅读8989  评论1  喜欢17 最近在Xcode 7中向服务器发送请求访问JSON数据时, 控制台打印了以下错误信息: Application Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure.

jmeter测试https请求

公司最近在搞全站HTTPS改造,进一步提高网站的安全性,防止运营商劫持。那么,改造完成后,所有前后端的URL将全部为https。 So ,研究下怎么用Jmeter访问https请求呢。 其实很简单, 第一步在jmeter中创建HTTP请求,如下图进行配置,https端口为443; 第二步,在本机浏览器,如Chrome中导入该域名证书,在更多工具-设置-管理证书的地方,找到该证书,导出到本地。然后在

安全科普:理解SSL(https)中的对称加密与非对称加密

今天刚好为站点的后台弄了下https,就来分享我了解的吧。 密码学最早可以追溯到古希腊罗马时代,那时的加密方法很简单:替换字母。 早期的密码学:   古希腊人用一种叫 Scytale 的工具加密。更快的工具是 transposition cipher—:只是把羊皮纸卷在一根圆木上,写下信息,羊皮纸展开后,这些信息就加密完成了。 虽然很容易被解密,但它确实是第一个在现实中应用加密的

OkHttp遇到Https

转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/48129405;  本文出自:【张鸿洋的博客】 一、概述 其实这篇文章理论上不限于okhttp去访问自签名的网站,不过接上篇博文了,就叫这个了。首先要了解的事,okhttp默认情况下是支持https协议的网站的,比如https://www.baidu.com,https