ESP32-C3: клиент HTTP |
![]() |
Добавил(а) microsin | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Компонент esp_http_client предоставляет набор API-функций для создания запросов HTTP/HTTPS из приложений ESP-IDF. Для использования клиента HTTP выполните следующие шаги: esp_http_client_init(): создает экземпляр дескриптора клиента esp_http_client_handle_t, т. е. клиента HTTP на основе предоставленной конфигурации esp_http_client_config_t. Эта функция должна быть вызвана первой; подразумеваются значения по умолчанию для параметров конфигурации, которые не были явно определены пользователем. esp_http_client_perform(): выполнит все операции esp_http_client - откроет соединение, осуществит обмен данными и закроет соединение (как это будет необходимо), блокируя выполнение вызывающей задачи до завершения этой функции. Все связанные с вызовом события будут переданы в обработчик (event handler, который был задан в конфигурации esp_http_client_config_t). esp_http_client_cleanup(): закроет соединение (если оно было) и освободит всю память, которая была выделена для экземпляра клиента HTTP. Этот вызов должен быть последней используемой операцией API клиента HTTP. Простой пример приложения, который использует ESP HTTP Client для создания запросов HTTP/HTTPS, можно найти в каталоге protocols/esp_http_client среди примеров ESP-IDF. Базовый запрос HTTP. Посмотрите пример использования функций http_rest_with_url и http_rest_with_hostname_path в приложении примера esp_http_client. Постоянные соединения. Постоянное соединение означает, что клиент HTTP может повторно использовать одно и то же соединение для нескольких обменов данными. Если сервер не запрашивает закрытие соединение через Connection: close заголовка, то соединение на отбрасывается, и вместо этого остается открытым, и будет использоваться для будущих запросов. Чтобы клиент ESP HTTP мог воспользоваться всеми плюсами постоянных соединений, следует выполнить как можно больше запросов, используя один и тот же экземпляр дескриптора. Просмотрите использование функций http_rest_with_url и http_rest_with_hostname_path в приложении примера esp_http_client. Здесь создается одно соединение, и как только оно создано, делается несколько запросов (GET, POST, PUT и т. д.) перед закрытием соединения. Запрос HTTPS. Клиент ESP HTTP поддерживает соединения SSL, используя библиотеку mbedTLS, с конфигурацией url, начинающейся со схемы https, или transport_type, установленным в HTTP_TRANSPORT_OVER_SSL. Поддержка HTTPS может быть сконфигурирована опцией menuconfig CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS (Component config → ESP HTTP client → Enable https, эта опция разрешена по умолчанию). Замечание: при выдаче запросов HTTPS, если нужна проверка сертификата сервера, то нужно предоставить дополнительный корневой сертификат (root certificate) в формате PEM для поля cert_pem структуры конфигурации esp_http_client_config_t. Пользователи также могут использовать ESP x509 Certificate Bundle для проверки сервера, используя для этого поле crt_bundle_attach структуры конфигурации esp_http_client_config_t. См. использование функций https_with_url и https_with_hostname_path для подробностей реализации запроса HTTPS. [HTTP Stream] Некоторым приложениям нужно открыть соединение и активно управлять обменом данными (data streaming). В таких случаях поведение приложения отличается от поведения обычных запросов. Ниже показан пример поведения приложения: esp_http_client_init(): создается дескриптор клиента HTTP. esp_http_client_set_* или esp_http_client_delete_*: модифицируются параметры соединения HTTP (опциональный шаг). esp_http_client_open(): открывается соединение HTTP с параметром write_len (длина содержимого, которое должно быть записано на сервер), устанавливается write_len=0 для соединения read-only. esp_http_client_write(): записываются данные на сервер с максимальной длиной, равной write_len параметра функции esp_http_client_open(); для write_len=0 эту функцию вызывать не нужно. esp_http_client_fetch_headers(): вычитывает заголовки ответа сервера HTTP, после отправки заголовков запроса и данных сервера (если таковые имеются). Возвращает content-length от сервера, и состояние операции может быть проверено esp_http_client_get_status_code(), чтобы получить HTTP status соединения. esp_http_client_read(): чтение HTTP stream. esp_http_client_close(): закрытие соединения. esp_http_client_cleanup(): освобождение связанных ресурсов. Для деталей реализации см. использование функции http_perform_as_stream_reader в приложении примера esp_http_client. [Аутентификация HTTP] Клиент ESP HTTP поддерживает оба вида аутентификации - базовая (Basic Authentication) и с цифровой подписью (Digest Authentication). · Пользователи могут предоставить в имя пользователя (username) и пароль (password) напрямую в тексте ссылки (URL/URI), или заполнить поля username и password в структуре конфигурации esp_http_client_config_t. Для auth_type = HTTP_AUTH_TYPE_BASIC, клиент HTTP выполняет только одну операцию для прохождения процесса аутентификации. · Если auth_type = HTTP_AUTH_TYPE_NONE, но в конфигурации были заполнены поля username и password, то клиент HTTP выполняет две операции. Клиент получит сообщение 401 Unauthorized header в ответ на свою первую попытку подключения к серверу. На основе этой информации клиент примет решение, какой метод аутентификации выбрать для второй операции. Для подробностей реализации просмотрите использование функций http_auth_basic, http_auth_basic_redirect (для Basic Authentication) и http_auth_digest (для Digest Authentication) в приложении примера esp_http_client. Примеры конфигурации аутентификации: Аутентификация в ссылке (URI): esp_http_client_config_t config = { .url = "http://user:passwd@httpbin.org/basic-auth/user/passwd", .auth_type = HTTP_AUTH_TYPE_BASIC, }; Аутентификация путем заполнения полей username и password: esp_http_client_config_t config = { .url = "http://httpbin.org/basic-auth/user/passwd", .username = "user", .password = "passwd", .auth_type = HTTP_AUTH_TYPE_BASIC, }; [Обработка событий] Клиент ESP HTTP поддерживает обработку событий путем запуска обработчика (event handler), соответствующего произошедшему событию. Перечисление esp_http_client_event_id_t содержит все события, которые могли бы произойти при выполнении запроса HTTP клиентом ESP HTTP. Чтобы разрешить обработку событий, вам просто нужно установить указатель на функцию обратного вызова (callback) в поле event_handler структуры конфигурации esp_http_client_config_t. Числовые значения событий кодируются в перечислении esp_http_client_event_id_t: /**
* @brief Идентификаторы событий клиента HTTP
*/
typedef enum { HTTP_EVENT_ERROR = 0, /*!< Это событие происходит, когда при выполнении возникает какая-нибудь ошибка. */ HTTP_EVENT_ON_CONNECTED, /*!< Происходит, когда произошло подключение к серверу HTTP, и еще не передавались никакие данные. */ HTTP_EVENT_HEADERS_SENT, /*!< После отправки всех заголовков с сервера HTTP. */ HTTP_EVENT_HEADER_SENT = HTTP_EVENT_HEADERS_SENT, /*!< Это значение оставлено для сохранения обратной совместимости, и в будущих
версиях ESP-IDF устареет. */ HTTP_EVENT_ON_HEADER, /*!< Происходит при получении каждого из заголовков. */ HTTP_EVENT_ON_DATA, /*!< Происходит при приеме данных с сервера, возможно несколькими порциями для одного пакета. */ HTTP_EVENT_ON_FINISH, /*!< Происходит при завершении сессии HTTP. */ HTTP_EVENT_DISCONNECTED, /*!< Соединение завершено, отключение от сервера HTTP. */ } esp_http_client_event_id_t; Особый интерес представляет, на мой взгляд, событие HTTP_EVENT_ON_HEADER, потому что оно позволяет получить предварительную информацию о запрашиваемом web-ресурсе в виде заголовков. Эта информация может быть довольно полезна, потому что позволяет до загрузки данных ресурса оценить объем закачиваемых данных. Данные заголовков доступны в полях key и value параметра обработчика esp_http_client_event_t *evt. Значение evt->key возвращает имя параметра заголовка, а значение evt->value значение параметра. Ниже приведен пример вывода информации о заголовков в событии HTTP_EVENT_ON_HEADER. Здесь было обращение к файлу firmware прошивки, который находился на сервере и был доступен для загрузки. Заголовок key=content-length, value=1593024 позволяет оценить размер файла в байтах, который предстоит загрузить: I (2322) HTTP_EVENT_ON_HEADER, key=date, value=Thu, 06 Apr 2023 04:45:16 GMT I (2322) HTTP_EVENT_ON_HEADER, key=server, value=uvicorn I (2322) HTTP_EVENT_ON_HEADER, key=content-type, value=application/octet-stream I (2322) HTTP_EVENT_ON_HEADER, key=content-length, value=1593024 I (2332) HTTP_EVENT_ON_HEADER, key=last-modified, value=Wed, 29 Mar 2023 21:39:21 GMT I (2332) HTTP_EVENT_ON_HEADER, key=etag, value=1f5fbadd21103930ea58a0b969b457d9 Диагностика клиента ESP HTTP. Диагностическая информация может помочь разобраться в причине каких-либо проблем. В случае клиента ESP HTTP эта диагностическая информация может быть собрана регистрацией обработчика с библиотекой Event Loop. Этот функционал был добавлен с учетом того, что фреймворк ESP Insights собирается информацию диагностики. Однако этот функционал для целей диагностики также может использоваться без какой-либо зависимости от ESP Insights framework. Обработчик событий может быть зарегистрирован для цикла обработки событий (event loop) с помощью функции esp_event_handler_register(). Ожидаемые типы данных в event loop различных событий клиента HTTP: HTTP_EVENT_ERROR: esp_http_client_handle_t Дескриптор esp_http_client_handle_t, полученный в данных события, будет достоверен до тех пор, пока не будет получено событие HTTP_EVENT_DISCONNECTED. Этот дескриптор должен быть отправлен главным образом для того, чтобы разделять между собой различные соединения клиента, и не должен использоваться для других целей (поскольку это может поменяться на основе состояния соединения клиента). [Справочник API клиента HTTP] Заголовочный файл: components/esp_http_client/include/esp_http_client.h. Ниже в таблице приведен общий список API-функций клиента HTTP. Подробное описание параметров API-функций, структур, типов данных, перечислений и макросов см. в документации [1].
Примечания: (1) Нельзя вызывать эту функцию одновременно из двух мест, используя один и тот же дескриптор клиента esp_http_client_handle_t. Пусть первый вызов завершится, прежде чем делать второй вызов. Если вы хотите делать параллельные транзакции, то должны использовать несколько дескрипторов esp_http_client_handle_t. Эта функция включает вызовы esp_http_client_open -> esp_http_client_write -> esp_http_client_fetch_headers -> esp_http_client_read (и как опция) esp_http_client_close. [Ссылки] 1. ESP-С3 HTTP Client site:espressif.com. |