mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-04 21:24:32 +02:00
examples: Add example to demonstrate use of low level APIs for GET and POST requests
Use buffer to accumulate data of response from event handler and print the response on console Demonstrate use of user_data field in esp_http_client_config_t to get response body
This commit is contained in:
@@ -22,6 +22,7 @@
|
||||
#include "esp_http_client.h"
|
||||
|
||||
#define MAX_HTTP_RECV_BUFFER 512
|
||||
#define MAX_HTTP_OUTPUT_BUFFER 2048
|
||||
static const char *TAG = "HTTP_CLIENT";
|
||||
|
||||
/* Root cert for howsmyssl.com, taken from howsmyssl_com_root_cert.pem
|
||||
@@ -39,6 +40,8 @@ extern const char howsmyssl_com_root_cert_pem_end[] asm("_binary_howsmyssl_com
|
||||
|
||||
esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||
{
|
||||
static char *output_buffer; // Buffer to store response of http request from event handler
|
||||
static int output_len; // Stores number of bytes read
|
||||
switch(evt->event_id) {
|
||||
case HTTP_EVENT_ERROR:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_ERROR");
|
||||
@@ -54,20 +57,49 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||
break;
|
||||
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)) {
|
||||
// Write out data
|
||||
// printf("%.*s", evt->data_len, (char*)evt->data);
|
||||
// If user_data buffer is configured, copy the response into the buffer
|
||||
if (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;
|
||||
}
|
||||
|
||||
break;
|
||||
case HTTP_EVENT_ON_FINISH:
|
||||
ESP_LOGD(TAG, "HTTP_EVENT_ON_FINISH");
|
||||
if (output_buffer != NULL) {
|
||||
// Response is accumulated in output_buffer. Uncomment the below line to print the accumulated response
|
||||
// ESP_LOG_BUFFER_HEX(TAG, output_buffer, output_len);
|
||||
free(output_buffer);
|
||||
output_buffer = NULL;
|
||||
output_len = 0;
|
||||
}
|
||||
break;
|
||||
case HTTP_EVENT_DISCONNECTED:
|
||||
ESP_LOGI(TAG, "HTTP_EVENT_DISCONNECTED");
|
||||
int mbedtls_err = 0;
|
||||
esp_err_t err = esp_tls_get_and_clear_last_error(evt->data, &mbedtls_err, NULL);
|
||||
if (err != 0) {
|
||||
if (output_buffer != NULL) {
|
||||
free(output_buffer);
|
||||
output_buffer = NULL;
|
||||
output_len = 0;
|
||||
}
|
||||
ESP_LOGI(TAG, "Last esp error code: 0x%x", err);
|
||||
ESP_LOGI(TAG, "Last mbedtls failure: 0x%x", mbedtls_err);
|
||||
}
|
||||
@@ -78,9 +110,11 @@ esp_err_t _http_event_handler(esp_http_client_event_t *evt)
|
||||
|
||||
static void http_rest_with_url(void)
|
||||
{
|
||||
char local_response_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0};
|
||||
esp_http_client_config_t config = {
|
||||
.url = "http://httpbin.org/get",
|
||||
.event_handler = _http_event_handler,
|
||||
.user_data = local_response_buffer, // Pass address of local buffer to get response
|
||||
};
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
|
||||
@@ -93,11 +127,13 @@ static void http_rest_with_url(void)
|
||||
} else {
|
||||
ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
ESP_LOG_BUFFER_HEX(TAG, local_response_buffer, strlen(local_response_buffer));
|
||||
|
||||
// POST
|
||||
const char *post_data = "field1=value1&field2=value2";
|
||||
const char *post_data = "{\"field1\":\"value1\"}";
|
||||
esp_http_client_set_url(client, "http://httpbin.org/post");
|
||||
esp_http_client_set_method(client, HTTP_METHOD_POST);
|
||||
esp_http_client_set_header(client, "Content-Type", "application/json");
|
||||
esp_http_client_set_post_field(client, post_data, strlen(post_data));
|
||||
err = esp_http_client_perform(client);
|
||||
if (err == ESP_OK) {
|
||||
@@ -511,6 +547,69 @@ static void https_with_invalid_url(void)
|
||||
esp_http_client_cleanup(client);
|
||||
}
|
||||
|
||||
/*
|
||||
* http_native_request() demonstrates use of low level APIs to connect to a server,
|
||||
* make a http request and read response. Event handler is not used in this case.
|
||||
* Note: This approach should only be used in case use of low level APIs is required.
|
||||
* The easiest way is to use esp_http_perform()
|
||||
*/
|
||||
static void http_native_request(void)
|
||||
{
|
||||
char output_buffer[MAX_HTTP_OUTPUT_BUFFER] = {0}; // Buffer to store response of http request
|
||||
int content_length = 0;
|
||||
esp_http_client_config_t config = {
|
||||
.url = "http://httpbin.org/get",
|
||||
};
|
||||
esp_http_client_handle_t client = esp_http_client_init(&config);
|
||||
|
||||
// GET Request
|
||||
esp_http_client_set_method(client, HTTP_METHOD_GET);
|
||||
esp_err_t err = esp_http_client_open(client, 0);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Failed to open HTTP connection: %s", esp_err_to_name(err));
|
||||
} else {
|
||||
content_length = esp_http_client_fetch_headers(client);
|
||||
if (content_length < 0) {
|
||||
ESP_LOGE(TAG, "HTTP client fetch headers failed");
|
||||
} else {
|
||||
int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
|
||||
if (data_read >= 0) {
|
||||
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
|
||||
esp_http_client_get_status_code(client),
|
||||
esp_http_client_get_content_length(client));
|
||||
ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer));
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to read response");
|
||||
}
|
||||
}
|
||||
}
|
||||
esp_http_client_close(client);
|
||||
|
||||
// POST Request
|
||||
const char *post_data = "{\"field1\":\"value1\"}";
|
||||
esp_http_client_set_url(client, "http://httpbin.org/post");
|
||||
esp_http_client_set_method(client, HTTP_METHOD_POST);
|
||||
esp_http_client_set_header(client, "Content-Type", "application/json");
|
||||
err = esp_http_client_open(client, strlen(post_data));
|
||||
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, post_data, strlen(post_data));
|
||||
if (wlen < 0) {
|
||||
ESP_LOGE(TAG, "Write failed");
|
||||
}
|
||||
int data_read = esp_http_client_read_response(client, output_buffer, MAX_HTTP_OUTPUT_BUFFER);
|
||||
if (data_read >= 0) {
|
||||
ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
|
||||
esp_http_client_get_status_code(client),
|
||||
esp_http_client_get_content_length(client));
|
||||
ESP_LOG_BUFFER_HEX(TAG, output_buffer, strlen(output_buffer));
|
||||
} else {
|
||||
ESP_LOGE(TAG, "Failed to read response");
|
||||
}
|
||||
}
|
||||
esp_http_client_cleanup(client);
|
||||
}
|
||||
|
||||
static void http_test_task(void *pvParameters)
|
||||
{
|
||||
@@ -530,6 +629,7 @@ static void http_test_task(void *pvParameters)
|
||||
http_perform_as_stream_reader();
|
||||
https_async();
|
||||
https_with_invalid_url();
|
||||
http_native_request();
|
||||
|
||||
ESP_LOGI(TAG, "Finish http example");
|
||||
vTaskDelete(NULL);
|
||||
|
Reference in New Issue
Block a user