ESP HTTP Client

Overview

esp_http_client provides an API for making HTTP/S requests from ESP-IDF programs. The steps to use this API for an HTTP request are:

  • esp_http_client_init(): To use the HTTP client, the first thing we must do is create an esp_http_client by pass into this function with the esp_http_client_config_t configurations. Which configuration values we do not define, the library will use default.
  • esp_http_client_perform(): The esp_http_client argument created from the init function is needed. This function performs all operations of the esp_http_client, from opening the connection, sending data, downloading data and closing the connection if necessary. All related events will be invoked in the event_handle (defined by esp_http_client_config_t). This function performs its job and blocks the current task until it’s done
  • esp_http_client_cleanup(): After completing our esp_http_client’s task, this is the last function to be called. It will close the connection (if any) and free up all the memory allocated to the HTTP client

Application Example

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;
}

esp_http_client_config_t config = {
   .url = "http://httpbin.org/redirect/2",
   .event_handle = _http_event_handle,
};
esp_http_client_handle_t client = esp_http_client_init(&config);
esp_err_t err = esp_http_client_perform(client);

if (err == ESP_OK) {
   ESP_LOGI(TAG, "Status = %d, content_length = %d",
           esp_http_client_get_status_code(client),
           esp_http_client_get_content_length(client));
}
esp_http_client_cleanup(client);

Persistent Connections

Persistent connections means that the HTTP client can re-use the same connection for several transfers. If the server does not request to close the connection with the Connection: close header, the new transfer with sample ip address, port, and protocol.

To allow the HTTP client to take full advantage of persistent connections, you should do as many of your file transfers as possible using the same handle.

Persistent Connections example

esp_err_t err;
esp_http_client_config_t config = {
    .url = "http://httpbin.org/get",
};
esp_http_client_handle_t client = esp_http_client_init(&config);
// first request
err = esp_http_client_perform(client);

// second request
esp_http_client_set_url(client, "http://httpbin.org/anything")
esp_http_client_set_method(client, HTTP_METHOD_DELETE);
esp_http_client_set_header(client, "HeaderKey", "HeaderValue");
err = esp_http_client_perform(client);

esp_http_client_cleanup(client);

HTTPS

The HTTP client supports SSL connections using mbedtls, with the url configuration starting with https scheme (or transport_type = HTTP_TRANSPORT_OVER_SSL). HTTPS support can be configured via :ref:CONFIG_ENABLE_HTTPS (enabled by default)..

Note

By providing information using HTTPS, the library will use the SSL transport type to connect to the server. If you want to verify server, then need to provide additional certificate in PEM format, and provide to cert_pem in esp_http_client_config_t

HTTPS example

static void https()
{
    esp_http_client_config_t config = {
        .url = "https://www.howsmyssl.com",
        .cert_pem = howsmyssl_com_root_cert_pem_start,
    };
    esp_http_client_handle_t client = esp_http_client_init(&config);
    esp_err_t err = esp_http_client_perform(client);

    if (err == ESP_OK) {
        ESP_LOGI(TAG, "Status = %d, content_length = %d",
                esp_http_client_get_status_code(client),
                esp_http_client_get_content_length(client));
    }
    esp_http_client_cleanup(client);
}

HTTP Stream

Some applications need to open the connection and control the reading of the data in an active manner. the HTTP client supports some functions to make this easier, of course, once you use these functions you should not use the esp_http_client_perform() function with that handle, and esp_http_client_init() alway to called first to get the handle. Perform that functions in the order below:

Perform HTTP request as Stream reader

Check the example function http_perform_as_stream_reader at protocols/esp_http_client.

HTTP Authentication

The HTTP client supports both Basic and Digest Authentication. By providing usernames and passwords in url or in the username, password of config entry. And with auth_type = HTTP_AUTH_TYPE_BASIC, the HTTP client takes only 1 perform to pass the authentication process. If auth_type = HTTP_AUTH_TYPE_NONE, but there are username and password in the configuration, the HTTP client takes 2 performs. The first time it connects to the server and receives the UNAUTHORIZED header. Based on this information, it will know which authentication method to choose, and perform it on the second.

Config authentication example with URI

esp_http_client_config_t config = {
    .url = "http://user:passwd@httpbin.org/basic-auth/user/passwd",
    .auth_type = HTTP_AUTH_TYPE_BASIC,
};

Config authentication example with username, password entry

esp_http_client_config_t config = {
    .url = "http://httpbin.org/basic-auth/user/passwd",
    .username = "user",
    .password = "passwd",
    .auth_type = HTTP_AUTH_TYPE_BASIC,
};

HTTP Client example: protocols/esp_http_client.

API Reference

Functions

esp_http_client_handle_t esp_http_client_init(const esp_http_client_config_t *config)

Start a HTTP session This function must be the first function to call, and it returns a esp_http_client_handle_t that you must use as input to other functions in the interface. This call MUST have a corresponding call to esp_http_client_cleanup when the operation is complete.

Return
  • esp_http_client_handle_t
  • NULL if any errors
Parameters
  • config: The configurations, see http_client_config_t

esp_err_t esp_http_client_perform(esp_http_client_handle_t client)

Invoke this function after esp_http_client_init and all the options calls are made, and will perform the transfer as described in the options. It must be called with the same esp_http_client_handle_t as input as the esp_http_client_init call returned. esp_http_client_perform performs the entire request in either blocking or non-blocking manner. By default, the API performs request in a blocking manner and returns when done, or if it failed, and in non-blocking manner, it returns if EAGAIN/EWOULDBLOCK or EINPROGRESS is encountered, or if it failed. And in case of non-blocking request, the user may call this API multiple times unless request & response is complete or there is a failure. To enable non-blocking esp_http_client_perform(), is_async member of esp_http_client_config_t must be set while making a call to esp_http_client_init() API. You can do any amount of calls to esp_http_client_perform while using the same esp_http_client_handle_t. The underlying connection may be kept open if the server allows it. If you intend to transfer more than one file, you are even encouraged to do so. esp_http_client will then attempt to re-use the same connection for the following transfers, thus making the operations faster, less CPU intense and using less network resources. Just note that you will have to use esp_http_client_set_** between the invokes to set options for the following esp_http_client_perform.

Note
You must never call this function simultaneously from two places using the same client handle. Let the function return first before invoking it another time. If you want parallel transfers, you must use several esp_http_client_handle_t. This function include esp_http_client_open -> esp_http_client_write -> esp_http_client_fetch_headers -> esp_http_client_read (and option) esp_http_client_close.
Return
  • ESP_OK on successful
  • ESP_FAIL on error
Parameters
  • client: The esp_http_client handle

esp_err_t esp_http_client_set_url(esp_http_client_handle_t client, const char *url)

Set URL for client, when performing this behavior, the options in the URL will replace the old ones.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle
  • url: The url

esp_err_t esp_http_client_set_post_field(esp_http_client_handle_t client, const char *data, int len)

Set post data, this function must be called before esp_http_client_perform. Note: The data parameter passed to this function is a pointer and this function will not copy the data.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle
  • data: post data pointer
  • len: post length

int esp_http_client_get_post_field(esp_http_client_handle_t client, char **data)

Get current post field information.

Return
Size of post data
Parameters
  • client: The client
  • data: Point to post data pointer

esp_err_t esp_http_client_set_header(esp_http_client_handle_t client, const char *key, const char *value)

Set http request header, this function must be called after esp_http_client_init and before any perform function.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle
  • key: The header key
  • value: The header value

esp_err_t esp_http_client_get_header(esp_http_client_handle_t client, const char *key, char **value)

Get http request header. The value parameter will be set to NULL if there is no header which is same as the key specified, otherwise the address of header value will be assigned to value parameter. This function must be called after esp_http_client_init.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle
  • key: The header key
  • value: The header value

esp_err_t esp_http_client_set_method(esp_http_client_handle_t client, esp_http_client_method_t method)

Set http request method.

Return
ESP_OK
Parameters
  • client: The esp_http_client handle
  • method: The method

esp_err_t esp_http_client_delete_header(esp_http_client_handle_t client, const char *key)

Delete http request header.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle
  • key: The key

esp_err_t esp_http_client_open(esp_http_client_handle_t client, int write_len)

This function will be open the connection, write all header strings and return.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle
  • write_len: HTTP Content length need to write to the server

int esp_http_client_write(esp_http_client_handle_t client, const char *buffer, int len)

This function will write data to the HTTP connection previously opened by esp_http_client_open()

Return
  • (-1) if any errors
  • Length of data written
Parameters
  • client: The esp_http_client handle
  • buffer: The buffer
  • len: This value must not be larger than the write_len parameter provided to esp_http_client_open()

int esp_http_client_fetch_headers(esp_http_client_handle_t client)

This function need to call after esp_http_client_open, it will read from http stream, process all receive headers.

Return
  • (0) if stream doesn’t contain content-length header, or chunked encoding (checked by esp_http_client_is_chunked response)
  • (-1: ESP_FAIL) if any errors
  • Download data length defined by content-length header
Parameters
  • client: The esp_http_client handle

bool esp_http_client_is_chunked_response(esp_http_client_handle_t client)

Check response data is chunked.

Return
true or false
Parameters
  • client: The esp_http_client handle

int esp_http_client_read(esp_http_client_handle_t client, char *buffer, int len)

Read data from http stream.

Return
  • (-1) if any errors
  • Length of data was read
Parameters
  • client: The esp_http_client handle
  • buffer: The buffer
  • len: The length

int esp_http_client_get_status_code(esp_http_client_handle_t client)

Get http response status code, the valid value if this function invoke after esp_http_client_perform

Return
Status code
Parameters
  • client: The esp_http_client handle

int esp_http_client_get_content_length(esp_http_client_handle_t client)

Get http response content length (from header Content-Length) the valid value if this function invoke after esp_http_client_perform

Return
  • (-1) Chunked transfer
  • Content-Length value as bytes
Parameters
  • client: The esp_http_client handle

esp_err_t esp_http_client_close(esp_http_client_handle_t client)

Close http connection, still kept all http request resources.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle

esp_err_t esp_http_client_cleanup(esp_http_client_handle_t client)

This function must be the last function to call for an session. It is the opposite of the esp_http_client_init function and must be called with the same handle as input that a esp_http_client_init call returned. This might close all connections this handle has used and possibly has kept open until now. Don’t call this function if you intend to transfer more files, re-using handles is a key to good performance with esp_http_client.

Return
  • ESP_OK
  • ESP_FAIL
Parameters
  • client: The esp_http_client handle

esp_http_client_transport_t esp_http_client_get_transport_type(esp_http_client_handle_t client)

Get transport type.

Return
  • HTTP_TRANSPORT_UNKNOWN
  • HTTP_TRANSPORT_OVER_TCP
  • HTTP_TRANSPORT_OVER_SSL
Parameters
  • client: The esp_http_client handle

Structures

struct esp_http_client_event

HTTP Client events data.

Public Members

esp_http_client_event_id_t event_id

event_id, to know the cause of the event

esp_http_client_handle_t client

esp_http_client_handle_t context

void *data

data of the event

int data_len

data length of data

void *user_data

user_data context, from esp_http_client_config_t user_data

char *header_key

For HTTP_EVENT_ON_HEADER event_id, it’s store current http header key

char *header_value

For HTTP_EVENT_ON_HEADER event_id, it’s store current http header value

struct esp_http_client_config_t

HTTP configuration.

Public Members

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

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 Certification, PEM format as string, if the client requires to verify server

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 redirection number, using default value if zero

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 buffer size (both send and receive)

void *user_data

HTTP user_data context

bool is_async

Set asynchronous mode

Macros

DEFAULT_HTTP_BUF_SIZE
ESP_ERR_HTTP_BASE

Starting number of HTTP error codes

ESP_ERR_HTTP_MAX_REDIRECT

The error exceeds the number of HTTP redirects

ESP_ERR_HTTP_CONNECT

Error open the HTTP connection

ESP_ERR_HTTP_WRITE_DATA

Error write HTTP data

ESP_ERR_HTTP_FETCH_HEADER

Error read HTTP header from server

ESP_ERR_HTTP_INVALID_TRANSPORT

There are no transport support for the input scheme

ESP_ERR_HTTP_CONNECTING

HTTP connection hasn’t been established yet

ESP_ERR_HTTP_EAGAIN

Mapping of errno EAGAIN to esp_err_t

Type Definitions

typedef struct esp_http_client *esp_http_client_handle_t
typedef struct esp_http_client_event *esp_http_client_event_handle_t
typedef struct esp_http_client_event esp_http_client_event_t

HTTP Client events data.

typedef esp_err_t (*http_event_handle_cb)(esp_http_client_event_t *evt)

Enumerations

enum esp_http_client_event_id_t

HTTP Client events id.

Values:

HTTP_EVENT_ERROR = 0

This event occurs when there are any errors during execution

HTTP_EVENT_ON_CONNECTED

Once the HTTP has been connected to the server, no data exchange has been performed

HTTP_EVENT_HEADER_SENT

After sending all the headers to the server

HTTP_EVENT_ON_HEADER

Occurs when receiving each header sent from the server

HTTP_EVENT_ON_DATA

Occurs when receiving data from the server, possibly multiple portions of the packet

HTTP_EVENT_ON_FINISH

Occurs when finish a HTTP session

HTTP_EVENT_DISCONNECTED

The connection has been disconnected

enum esp_http_client_transport_t

HTTP Client transport.

Values:

HTTP_TRANSPORT_UNKNOWN = 0x0

Unknown

HTTP_TRANSPORT_OVER_TCP

Transport over tcp

HTTP_TRANSPORT_OVER_SSL

Transport over ssl

enum esp_http_client_method_t

HTTP method.

Values:

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
enum esp_http_client_auth_type_t

HTTP Authentication type.

Values:

HTTP_AUTH_TYPE_NONE = 0

No authention

HTTP_AUTH_TYPE_BASIC

HTTP Basic authentication

HTTP_AUTH_TYPE_DIGEST

HTTP Disgest authentication