飛書文檔http://https://x509p6c8to.feishu.cn/docx/doxcn8qjiNXmw2r3vBEdc7XCBCh
源碼參考:
/home/kemp/work/esp/esp-idf/examples/protocols/https_request
源碼下載方式參考:
源碼下載方式
獲取網站ca證書
openssl s_client -showcerts -connect api.seniverse.com:443 </dev/null
復制-----BEGIN CERTIFICATE-----后內容到pem文件
-----END CERTIFICATE-----1 s:C = US, O = DigiCert Inc, CN = RapidSSL TLS DV RSA Mixed SHA256 2020 CA-1i:C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA
-----BEGIN CERTIFICATE-----
MIIFUTCCBDmgAwIBAgIQB5g2A63jmQghnKAMJ7yKbDANBgkqhkiG9w0BAQsFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0yMDA3MTYxMjI1MjdaFw0yMzA1MzEyMzU5NTlaMFkxCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxMzAxBgNVBAMTKlJhcGlkU1NMIFRMUyBE
ViBSU0EgTWl4ZWQgU0hBMjU2IDIwMjAgQ0EtMTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBANpuQ1VVmXvZlaJmxGVYotAMFzoApohbJAeNpzN+49LbgkrM
Lv2tblII8H43vN7UFumxV7lJdPwLP22qa0sV9cwCr6QZoGEobda+4pufG0aSfHQC
QhulaqKpPcYYOPjTwgqJA84AFYj8l/IeQ8n01VyCurMIHA478ts2G6GGtEx0ucnE
fV2QHUL64EC2yh7ybboo5v8nFWV4lx/xcfxoxkFTVnAIRgHrH2vUdOiV9slOix3z
5KPs2rK2bbach8Sh5GSkgp2HRoS/my0tCq1vjyLJeP0aNwPd3rk5O8LiffLev9j+
UKZo0tt0VvTLkdGmSN4h1mVY6DnGfOwp1C5SK0MCAwEAAaOCAgswggIHMB0GA1Ud
DgQWBBSkjeW+fHnkcCNtLik0rSNY3PUxfzAfBgNVHSMEGDAWgBQD3lA1VtFMu2bw
o+IbG8OXsj3RVTAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0lBBYwFAYIKwYBBQUHAwEG
CCsGAQUFBwMCMBIGA1UdEwEB/wQIMAYBAf8CAQAwNAYIKwYBBQUHAQEEKDAmMCQG
CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wewYDVR0fBHQwcjA3
oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0R2xvYmFsUm9v
dENBLmNybDA3oDWgM4YxaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0
R2xvYmFsUm9vdENBLmNybDCBzgYDVR0gBIHGMIHDMIHABgRVHSAAMIG3MCgGCCsG
AQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGKBggrBgEFBQcC
AjB+DHxBbnkgdXNlIG9mIHRoaXMgQ2VydGlmaWNhdGUgY29uc3RpdHV0ZXMgYWNj
ZXB0YW5jZSBvZiB0aGUgUmVseWluZyBQYXJ0eSBBZ3JlZW1lbnQgbG9jYXRlZCBh
dCBodHRwczovL3d3dy5kaWdpY2VydC5jb20vcnBhLXVhMA0GCSqGSIb3DQEBCwUA
A4IBAQAi49xtSOuOygBycy50quCThG45xIdUAsQCaXFVRa9asPaB/jLINXJL3qV9
J0Gh2bZM0k4yOMeAMZ57smP6JkcJihhOFlfQa18aljd+xNc6b+GX6oFcCHGr+gsE
yPM8qvlKGxc5T5eHVzV6jpjpyzl6VEKpaxH6gdGVpQVgjkOR9yY9XAUlFnzlOCpq
sm7r2ZUKpDfrhUnVzX2nSM15XSj48rVBBAnGJWkLPijlACd3sWFMVUiKRz1C5PZy
el2l7J/W4d99KFLSYgoy5GDmARpwLc//fXfkr40nMY8ibCmxCsjXQTe0fJbtrrLL
yWQlk9VDV296EI/kQOJNLVEkJ54P
-----END CERTIFICATE-----
---
Server certificate
subject=CN = *.seniverse.com
Makefile添加證書
EMBED_TXTFILES "server_root_cert.pem"
/home/kemp/work/esp/DesktopScreen/main/component.mk添加
COMPONENT_EMBED_TXTFILES := server_root_cert.pem
代碼實現:
/* HTTPS GET Example using plain mbedTLS sockets** Contacts the howsmyssl.com API via TLS v1.2 and reads a JSON* response.** Adapted from the ssl_client1 example in mbedtls.** Original Copyright (C) 2006-2016, ARM Limited, All Rights Reserved, Apache 2.0 License.* Additions Copyright (C) Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD, Apache 2.0 License.*** Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at**???? http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_netif.h"#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
#include "lwip/netdb.h"
#include "lwip/dns.h"
#include "cJSON.h"#include "esp_tls.h"#define WEB_SERVER "api.seniverse.com"
#define WEB_URL "https://api.seniverse.com/v3/weather/now.json?key=SmazqPcltzTft-X3v&location=guangzhou&language=zh-Hans&unit=c"#define WEB_BILIBILI_SERVER "api.bilibili.com"
#define WEB_BILIBILI_URL "https://api.bilibili.com/x/relation/stat?vmid=383943678&jsonp=jsonp"static const char *TAG = "example";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";static const char *REQUEST_BILIBILI = "GET " WEB_BILIBILI_URL " HTTP/1.0\r\n""Host: "WEB_BILIBILI_SERVER"\r\n""User-Agent: esp-idf/1.0 esp32\r\n""\r\n";/* Root cert for howsmyssl.com, taken from server_root_cert.pemThe PEM file was extracted from the output of this command:openssl s_client -showcerts -connect www.howsmyssl.com:443 </dev/nullThe CA root cert is the last cert given in the chain of certs.To embed it in the app binary, the PEM file is namedin the component.mk COMPONENT_EMBED_TXTFILES variable.
*/
extern const uint8_t server_root_cert_pem_start[] asm("_binary_server_root_cert_pem_start");
extern const uint8_t server_root_cert_pem_end[]?? asm("_binary_server_root_cert_pem_end");extern const uint8_t server_root_cert_bilibili_pem_start[] asm("_binary_server_root_cert_bilibili_pem_start");
extern const uint8_t server_root_cert_bilibili_pem_end[]?? asm("_binary_server_root_cert_bilibili_pem_end");static void https_get_task(void *pvParameters)
{char buf[512];int ret, len;int flags = 0;while(1) {//設置證書esp_tls_cfg_t cfg = {.cacert_buf? = server_root_cert_pem_start,.cacert_bytes = server_root_cert_pem_end - server_root_cert_pem_start,};esp_tls_cfg_t bilibili_cfg = {.cacert_buf? = server_root_cert_bilibili_pem_start,.cacert_bytes = server_root_cert_bilibili_pem_end - server_root_cert_bilibili_pem_start,};//創建tls連接struct esp_tls *tls;if(flags == 0){tls = esp_tls_conn_http_new(WEB_URL, &cfg);}else{tls = esp_tls_conn_http_new(WEB_BILIBILI_URL, &bilibili_cfg);}if(tls != NULL) {ESP_LOGI(TAG, "Connection established...");} else {ESP_LOGE(TAG, "Connection failed...");goto exit;}size_t written_bytes = 0;if(flags == 0){flags = 1;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));}else{flags = 0;do {ret = esp_tls_conn_write(tls,REQUEST_BILIBILI + written_bytes,strlen(REQUEST_BILIBILI) - 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_BILIBILI));??}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 = 15; countdown >= 0; countdown--) {ESP_LOGI(TAG, "%d...", countdown);vTaskDelay(1000 / portTICK_PERIOD_MS);}ESP_LOGI(TAG, "Starting again!");}
}void ds_https_request_init(void)
{xTaskCreate(&https_get_task, "https_get_task", 8192, NULL, 5, NULL);
}