ESP32 IDF development application? esp_http_client example analysis

ESP32 IDF development application? esp_http_client example analysis

    • 1. The blogger’s purpose for writing this technical article:
    • 2. Overview
    • 3. Introduction to esp_http_client related APIs
    • 4. Software design
    • 5. Examples
    • 6. Debugging results


Don’t get lost-Navigation bar
Quickly navigate to find what you want (article directory)


If this article is useful to you, please like and save it. Your support is the motivation for the blogger to persist.

1. The blogger’s purpose of writing this technical article:

(1) How to use esp_http_client api;

2. Overview

The basic concepts of http have been introduced in the previous article. This chapter mainly introduces the use of the api functions encapsulated in the esp_http_client.c file.

3. Introduction to esp_http_client related API

Here we introduce the use of most of the esp_http_client library. For more details, please refer to: For more APIs, refer to esp-idf\components\esp_http_client\include\esp_http_client.h

(1), Initialization of esp_http_client
Let’s take a look at the initialization API first

/**
  * @brief Start HTTP session
  *This function must be the first function to be called, it returns an esp_http_client_handle_t, which you must use as input to other functions in the interface.
  *After the operation is completed, this call must make a corresponding call to esp_http_client_cleanup.
  * @param [in] config configuration, see `http_client_config_t`
  * @return
  *-`esp_http_client_handle_t`
  * - NULL if there were any errors
  */
esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config);

Next, let’s explain what the initialization content is.
Allocate memory for the parameters of the structure esp_http_client_config_t and initialize the data

esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config)
{<!-- -->

    _success = (
                   (client = calloc(1, sizeof(esp_http_client_t))) & amp; & amp;
                   (client->parser = calloc(1, sizeof(struct http_parser))) & amp; & amp;
                   (client->parser_settings = calloc(1, sizeof(struct http_parser_settings))) & amp; & amp;
                   (client->auth_data = calloc(1, sizeof(esp_http_auth_data_t))) & amp; & amp;
                   (client->request = calloc(1, sizeof(esp_http_data_t))) & amp; & amp;
                   (client->request->headers = http_header_init()) & amp; & amp;
                   (client->request->buffer = calloc(1, sizeof(esp_http_buffer_t))) & amp; & amp;
                   (client->response = calloc(1, sizeof(esp_http_data_t))) & amp; & amp;
                   (client->response->headers = http_header_init()) & amp; & amp;
                   (client->response->buffer = calloc(1, sizeof(esp_http_buffer_t)))
               );
. . . . .
    _success = (
                   (client->transport_list = esp_transport_list_init()) & amp; & amp;
                   (tcp = esp_transport_tcp_init()) & amp; & amp;
                   (esp_transport_set_default_port(tcp, DEFAULT_HTTP_PORT) == ESP_OK) & amp; & amp;
                   (esp_transport_list_add(client->transport_list, tcp, "http") == ESP_OK)
}

The tcp callback function is registered in esp_transport_tcp_init

tcp_connect, tcp_read, tcp_write, tcp_close, tcp_poll_read, tcp_poll_write, tcp_destroy
esp_transport_handle_t esp_transport_tcp_init(void)
{<!-- -->
esp_transport_set_func(t, tcp_connect, tcp_read, tcp_write, tcp_close, tcp_poll_read, tcp_poll_write, tcp_destroy);
}

(2). Set url connection API

/**
  * @brief Set the URL for the client. When executing this behavior, the options in the URL will replace the old ones.
  *
  * @param [in]Client esp_http_client handle
  * @param [in] url URL
  *
  * @return
  *-ESP_OK
  *-ESP_FAIL
  */
esp_err_t esp_http_client_set_url(esp_http_client_handle_t client, const char *url);

Parsing esp_http_client_set_url mainly operates on the client->connection_info structure and decomposes the url into each parameter of connection_info.
Structure connection_info_t

typedef struct {<!-- -->
    char *url;
    char *scheme;
    char *host;
    int port;
    char *username;
    char *password;
    char *path;
    char *query;
    char *cert_pem;
    esp_http_client_method_t method;
    esp_http_client_auth_type_t auth_type;
    esp_http_client_transport_t transport_type;
    int max_store_header_size;
} connection_info_t;

(3), set the request method

/**
  * @brief set http request method
  *
  * @param [in]Client esp_http_client handle
  * @param [in] method method
  *
  * @return
  *-ESP_OK
  *-ESP_ERR_INVALID_ARG
  */
esp_err_t esp_http_client_set_method(esp_http_client_handle_t client, esp_http_client_method_t method);
Request method:
/**
 * @brief HTTP method
 */
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_MAX,
} esp_http_client_method_t;

(4). Set post data

/**
  * @brief sets publishing data, this function must be called before `esp_http_client_perform`.
  *Note: The data parameter passed to this function is a pointer, this function does not copy the data
  *
  * @param [in]Client esp_http_client handle
  * @param [in]Data release data pointer
  * @param [in] len post length
  *
  * @return
  *-ESP_OK
  *-ESP_FAIL
  */
esp_err_t esp_http_client_set_post_field(esp_http_client_handle_t client, const char *data, int len);

(5), esp_http_perform obtains the request and completes TCP sending and receiving

/*
 esp_http_client_perform performs the entire request in a blocking or non-blocking manner.
By default, the API performs requests in a blocking manner and returns upon completion,
*/
esp_err_t esp_http_client_perform(esp_http_client_handle_t client);
/**
  * @brief This function will open the connection, write all header strings and return
  *
  * @param [in]Client esp_http_client handle
  * @param [in] write_len HTTP content length needs to be written to the server
  *
  * @return
  *-ESP_OK
  *-ESP_FAIL
  */
esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len);
/**
  * @brief This function needs to be called after esp_http_client_open, it will read from the http stream and process all receiving headers
  *
  * @param [in]Client esp_http_client handle
  *
  * @return
  * - (0) if the stream does not contain a content-length header or chunked encoding (checked by `esp_http_client_is_chunked` response)
  *- (-1: ESP_FAIL) if there are any errors
  */
int esp_http_client_fetch_headers(esp_http_client_handle_t client);

4. Software design

(1) After connecting to wifi, the first step is to fill in the structure. The content of the structure is as follows:

/**
 * @brief HTTP configuration
 */
typedef struct {<!-- -->
    const char *url; /*!< HTTP URL, the information on the URL is the most important, it will cover other fields below */
    const char *host; /*!< Domain name or IP as a string */
    int port; /*!< Port used for connection, default depends on esp_http_client_transport_t (80 or 443) */
    const char *username; /*!< for HTTP authentication */
    const char *password; /*!< used 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), defaults to `/`*/
    const char *query; /*!< HTTP query */
    const char *cert_pem; /*!< SSL server certification, PEM format is a string (if the client requires authentication server) */
    const char *client_cert_pem; /*!< SSL client authentication, PEM format is a string (if the server requires client authentication) */
    const char *client_key_pem; /*!< SSL client key, PEM format as string (if the server requires client authentication) */
    esp_http_client_method_t method; /*!< HTTP method */
    int timeout_ms; /*!< Network timeout (in milliseconds) */
    bool disable_auto_redirect; /*!< Disable HTTP automatic redirection */
    int max_redirection_count;/*!< Maximum number of redirections, if zero, use the default value*/
    http_event_handle_cb event_handler; /*!< HTTP event handling */
    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 transfer buffer size */
    void *user_data; /*!< HTTP user_data context */
    bool is_async; /*!< Set asynchronous mode, currently only supports HTTPS*/
    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 verification of the CN field of the server certificate */
} esp_http_client_config_t;

Assign a value to the structure and register a callback function to detect the status

esp_http_client_config_t config = {
.url = “http://httpbin.org/get”,
.event_handler = _http_event_handler,
};

Initialize the structure and register the tcp read-write connection function

esp_http_client_handle_t client = esp_http_client_init( & amp;config);

esp_http_client defaults to the GET method, other methods are as follows

/**
 * @brief HTTP method
 */
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_MAX,
} esp_http_client_method_t;

GET gets data using esp_http_client_perform function
Use other methods or reset the url using the function:

esp_http_client_set_url(client, "http://httpbin.org/post");
esp_http_client_set_method(client, HTTP_METHOD_POST);

5. Example

static void vTaskHttpGet(void *pvParameters)
{<!-- -->
    //Waiting for a successful connection, or if the connection is already disconnected, this function will always block until there is a connection.
   xEventGroupWaitBits(xCreatedEventGroup_WifiConnect,//Event flag group handle
        WIFI_CONNECTED_BIT, // Wait for bit0 and bit1 to be set
        pdFALSE, //bit0 and bit1 are cleared when TRUE exits, bit0 and bit1 are not cleared when pdFALSE exits
        pdTRUE, //Set to pdTRUE to wait for both bit1 and bit0 to be set, pdFALSE to wait for either bit1 or bit0 to be set
        portMAX_DELAY); //Wait for the delay time and keep waiting
    http_url_test();
    http_hostname_path_test();

    ESP_LOGI(TAG, "Finish http Test");
    vTaskDelete(NULL);
}

Test in task vTaskHttpGet

static void http_url_test(void)
{<!-- -->
    esp_http_client_config_t config = {<!-- -->
        .url = "http://httpbin.org/get",
        .event_handler = _http_event_handler,
    };
    //The parameters of esp_http_client_config_t allocate memory, initialize data, and register the read-write connection callback function of tcp
    esp_http_client_handle_t client = esp_http_client_init( & amp;config);

    // GET, default method
    //Send and receive data
    esp_err_t err = esp_http_client_perform(client);
    if (err == ESP_OK) {<!-- -->
        ESP_LOGI(TAG, "HTTP GET Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {<!-- -->
        ESP_LOGE(TAG, "HTTP GET request failed: %s", esp_err_to_name(err));
    }

    // POST
    const char *post_data = "field1=value1 & amp;field2=value2";
    esp_http_client_set_url(client, "http://httpbin.org/post");
    esp_http_client_set_method(client, HTTP_METHOD_POST);
    esp_http_client_set_post_field(client, post_data, strlen(post_data));
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {<!-- -->
        ESP_LOGI(TAG, "HTTP POST Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {<!-- -->
        ESP_LOGE(TAG, "HTTP POST request failed: %s", esp_err_to_name(err));
    }

    //PUT
    esp_http_client_set_url(client, "http://httpbin.org/put");
    esp_http_client_set_method(client, HTTP_METHOD_PUT);
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {<!-- -->
        ESP_LOGI(TAG, "HTTP PUT Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {<!-- -->
        ESP_LOGE(TAG, "HTTP PUT request failed: %s", esp_err_to_name(err));
    }

    //PATCH
    esp_http_client_set_url(client, "http://httpbin.org/patch");
    esp_http_client_set_method(client, HTTP_METHOD_PATCH);
    esp_http_client_set_post_field(client, NULL, 0);
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {<!-- -->
        ESP_LOGI(TAG, "HTTP PATCH Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {<!-- -->
        ESP_LOGE(TAG, "HTTP PATCH request failed: %s", esp_err_to_name(err));
    }

    //DELETE
    esp_http_client_set_url(client, "http://httpbin.org/delete");
    esp_http_client_set_method(client, HTTP_METHOD_DELETE);
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {<!-- -->
        ESP_LOGI(TAG, "HTTP DELETE Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {<!-- -->
        ESP_LOGE(TAG, "HTTP DELETE request failed: %s", esp_err_to_name(err));
    }

    //HEAD
    esp_http_client_set_url(client, "http://httpbin.org/get");
    esp_http_client_set_method(client, HTTP_METHOD_HEAD);
    err = esp_http_client_perform(client);
    if (err == ESP_OK) {<!-- -->
        ESP_LOGI(TAG, "HTTP HEAD Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    } else {<!-- -->
        ESP_LOGE(TAG, "HTTP HEAD request failed: %s", esp_err_to_name(err));
    }
    //release memory
    esp_http_client_cleanup(client);

}

6. Debugging results

All article source codes: https://download.csdn.net/download/lu330274924/88518092