Программирование ARM ESP32 HTTP Server Sat, November 15 2025  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.


ESP32 HTTP Server Печать
Добавил(а) microsin   

Компонент HTTP Server предоставляет возможность запуска облегченного web-сервера на ESP32. Ниже приведены подробные инструкции по использованию API, предоставляемого HTTP-сервером:

httpd_start(): создает экземпляр HTTP-сервера, выделяет ему память/ресурсы в зависимости от заданной конфигурации и выдаёт дескриптор экземпляру сервера. На сервере имеется прослушивающий сокет (TCP) для HTTP-трафика и управляющий сокет (UDP) для управляющих сигналов, которые выбираются циклически (по алгоритму round robin) в цикле задач сервера (server task loop). Приоритет задачи сервера и размер её стека конфигурируются во время создания экземпляра сервера путем передачи структуры httpd_config_t в вызов httpd_start(). TCP-трафик обрабатывается как HTTP-запросы, и, в зависимости от запрошенного URI, вызываются зарегистрированные пользователем обработчики, которые должны отправлять HTTP-пакеты ответов.

httpd_stop(): остановит сервер по предоставленному дескриптору и освободит любые выделенные для него ресурсы и память. Это блокирующая функция, которая сначала сигнализирует halt для задачи сервера, и затем ждет завершения этой задачи. При остановке задача закрывает все открытые соединения, удаляет зарегистрированные обработчики URI и сбрасывает все данные контекста сеанса в пустое состояние.

httpd_register_uri_handler(): обработчик URI регистрируется передачей объекта типа структуры httpd_uri_t, в которой заполнены поля имя ссылки (uri name), тип метода (method type, например HTTP_GET/HTTP_POST/HTTP_PUT и т. п.), указатель на функцию типа esp_err_t *handler (httpd_req_t *req) и указатель user_ctx на пользовательские контекстные данные.

URI (Uniform Resource Identifier) это универсальный идентификатор ресурса.

URI — более общее понятие, которое включает в себя:

- URL (Uniform Resource Locator) - указывает МЕСТОПОЛОЖЕНИЕ ресурса
- URN (Uniform Resource Name) - указывает ИМЯ ресурса

Все URL являются URI, но не все URI являются URL.

Примеры URI в вебе:

https://example.com/products/123
http://api.example.com/users
/images/logo.png
/api/v1/data
/about

Для ESP HTTP-сервера URI это путь и параметры, которые определяют, какой обработчик должен выполниться.

Примеры URI для регистрации обработчиков:

// Обработчик для главной страницы
URI: "/"
Метод: GET

// Обработчик для получения данных датчика
URI: "/api/temperature"
Метод: GET

// Обработчик для отправки команд
URI: "/api/control"
Метод: POST

// Обработчик для статических файлов
URI: "/images/*"
Метод: GET

Структура URI:

https://example.com:8080/api/v1/users?id=123#section
┌────────────────────┬─────────────────────────┬────────────────┐
│       Часть        │         Пример          │ Роль           |
├────────────────────┼─────────────────────────┼────────────────┤
│ Схема              │ https://                │ Протокол       
│ Домен              │ example.com             │ Сервер         
│ Порт               │ :8080                   │ Порт сервера   
│ Путь (Path)        │ /api/v1/users           │ ✅ Это то, что 
│                    │                         │ обрабатывает   
│                    │                         │ ваш сервер!    
│ Параметры (Query)  │ ?id=123                 │ Доп. данные    
│ Фрагмент           │ #section                │ Якорь          |
└────────────────────┴─────────────────────────┴────────────────┘

Когда на ESP HTTP-сервере регистрируют URI-обработчики (handlers), тем самым говорят серверу:

> "Когда приходит HTTP-запрос с методом GET на путь `/api/data` — вызови вот эту мою функцию-обработчик"

URI в этом контексте это путь запроса, который определяет, какой код должен выполниться для обработки конкретного запроса. Т. е. URI — это "адрес" в вашем приложении, который определяет, какая логика должна выполниться.

[Примеры приложений]

Пример protocols/http_server/simple демонстрирует, как обрабатывать произвольные длины контента, читать заголовки запроса и параметры запроса URL, и устанавливать заголовки ответа.

Пример protocols/http_server/advanced_tests демонстрирует, как использовать HTTP-сервер для продвинутого тестирования.

Persistent Connections. HTTP-сервер поддерживает постоянные соединения (persistent connections), позволяющие повторно использовать одно и то же соединение (сессию) для нескольких транзакций, сохраняя при этом контекстно-зависимые данные сессии. Данные контекста могут быть выделены динамически обработчиком, и в этом случае может потребоваться указать специальную пользовательскую функцию для освобождения этих данных, когда соединение/сессия закрывается.

Пример Persistent Connections:

/* Пользовательская функция для освобождения контекста */
void free_ctx_func(void *ctx) {
/* Какие-нибудь дополнительные действия, которые могут потребоваться
для освобождения ресурсов */
free(ctx); }
esp_err_t adder_post_handler(httpd_req_t *req) {
/* Создание контекста сессии, если он еще недоступен */
if (! req->sess_ctx) {
req->sess_ctx = malloc(sizeof(ANY_DATA_TYPE)); /*!< Указатель на данные контекста */
req->free_ctx = free_ctx_func; /*!< Функция для освобождения
данных контекста */
}

/* Доступ к данным контекста */
ANY_DATA_TYPE *ctx_data = (ANY_DATA_TYPE *)req->sess_ctx;

/* Ответ */
...............
...............
...............

return ESP_OK; }

См. пример в каталоге protocols/http_server/persistent_sockets. Этот пример демонстрирует, как настроить и использовать HTTP-сервер для persistent sockets, позволяя получить независимые сессии или контексты для каждого отдельного клиента.

WebSocket Server. Компонент HTTP-сервера предоставляет поддержку WebSocket. Фича WebSocket может быть разрешена в menuconfig с помощью опции CONFIG_HTTPD_WS_SUPPORT.

menuconfig WebSocket enable

Пример protocols/http_server/ws_echo_server демонстрирует, как создать WebSocket echo-сервер, используя HTTP-сервер, который запускается в локальной сети и требует для взаимодействия клиента WebSocket, отправляя обратно в виде эха принятые кадры WebSocket.

Обработка ошибок. У ESP HTTP-сервера есть различные события, для которых библиотека Event Loop [2] может запустить обработчик при возникновении определённого события. Обработчик должен быть зарегистрирован с помощью esp_event_handler_register(). В перечислении esp_http_server_event_id_t обозначены все события, которые могут произойти для ESP HTTP-сервера.

/** * @brief   Идентификаторы событий HTTP-сервера */
typedef enum {
HTTP_SERVER_EVENT_ERROR = 0, /*!< Любая ошибка во время выполнения */
HTTP_SERVER_EVENT_START, /*!< При старте HTTP-сервера */
HTTP_SERVER_EVENT_ON_CONNECTED, /*!< Подключение клиента, без выполнения обмена данными */
HTTP_SERVER_EVENT_ON_HEADER, /*!< При получении каждого заголовка, отправленного клиентом */
HTTP_SERVER_EVENT_HEADERS_SENT, /*!< После отправки всех заголовков клиенту */
HTTP_SERVER_EVENT_ON_DATA, /*!< Когда приняты данные от клиента */
HTTP_SERVER_EVENT_SENT_DATA, /*!< Когда завершается сессия */
HTTP_SERVER_EVENT_DISCONNECTED, /*!< При разрыве соединения */
HTTP_SERVER_EVENT_STOP, /*!< При остановке HTTP-сервера */ } esp_http_server_event_id_t;

Ожидаемые типы данных для различных событий ESP HTTP-сервера, обрабатываемых в event loop:

HTTP_SERVER_EVENT_ERROR:        httpd_err_code_t
HTTP_SERVER_EVENT_START:        NULL
HTTP_SERVER_EVENT_ON_CONNECTED: int
HTTP_SERVER_EVENT_ON_HEADER:    int
HTTP_SERVER_EVENT_HEADERS_SENT: int
HTTP_SERVER_EVENT_ON_DATA:      esp_http_server_event_data
HTTP_SERVER_EVENT_SENT_DATA:    esp_http_server_event_data
HTTP_SERVER_EVENT_DISCONNECTED: int
HTTP_SERVER_EVENT_STOP:         NULL

Обслуживание файлов. Пример protocols/http_server/file_serving демонстрирует, как создать простой файловый сервер HTTP, с возможностью как выгрузки (upload), так и загрузки (download) файлов.

Captive Portal. Пример protocols/http_server/captive_portal демонстрирует два метода для создания портала захвата (captive portal), который направляет пользователей на страницу аутентификации перед посещением других страниц, используя либо DNS-запросы и перенаправление HTTP-запросов, либо современный метод, включающий поле в предложении DHCP.

Асинхронные обработчики. Пример protocols/http_server/async_handlers демонстрирует, как обрабатывать несколько долго выполняющихся запросов к HTTP-серверу, использующих разные URI для асинхронных запросов (asynchronous requests), быстрых запросов (quick requests) и главной страницы (index page).

RESTful API. Пример protocols/http_server/restful_server демонстрирует, как реализовать RESTful API сервер и HTTP-сервер с пользовательским интерфейсом браузера (frontend browser UI), а также разрабатывает несколько API для извлечения ресурсов, используя mDNS для парсинга доменного имени и развертывания web-страницы на хосте разработки (host PC) с помощью технологии семихостинга, или на SPI flash, или на карте SD.

URI-обработчики. HTTP-сервер позволяет вам регистрировать URI-обработчики для обработки разных HTTP-запросов. Каждый обработчик (URI handler) привязывается к определенному URI и HTTP-методу (GET, POST, и т. п.). Функция обработчика вызывается всякий раз, когда поступает запрос, соответствующий URI и методу.

Функция обработчика должна вернуть значение esp_err_t.

esp_err_t my_uri_handler(httpd_req_t *req)
{
// Обработка запроса
// ...
// Возврат ESP_OK, если запрос был успешно обработан
return ESP_OK;

// Возврат кода ошибки, чтобы закрыть соединение
// return ESP_FAIL; }

void register_uri_handlers(httpd_handle_t server) {
httpd_uri_t my_uri = {
.uri = "/my_uri",
.method = HTTP_GET,
.handler = my_uri_handler,
.user_ctx = NULL
};
httpd_register_uri_handler(server, &my_uri); }

В этом примере функция-обработчик my_uri_handler обрабатывает запросы для URI /my_uri. Если обработчик вернул ESP_OK, то соединение остается открытым. Если обработчик возвратит любое другое значение, то соединение закрывается. Это поведение позволит приложению обслуживать закрытие соединения, основываясь на определенных событиях или условиях.

[Справочник по API esp_http_server]

Файл заголовка: components/esp_http_server/include/esp_http_server.h.

Этот файл заголовка может быть подключен директивой:

#include "esp_http_server.h"

Этот заголовочный файл является частью API, предоставляемого компонентом esp_http_server. Для декларации, что ваш компонент (а приложение это тоже компонент) зависит от esp_http_server, добавьте в свой CMakeLists.txt:

REQUIRES esp_http_server

.. или:

PRIV_REQUIRES esp_http_server

Ниже во врезках приведено описание API-функций.

esp_err_t httpd_start (httpd_handle_t *handle, const httpd_config_t *config);

Запустит web-сервер. Создается экземпляр HTTP-сервера и выделяется память/ресурсы для него, в зависимости от указанной конфигурации.

Пример использования:

// Функция, запускающая web-сервер
httpd_handle_t start_webserver(void)
{
// Генерация конфигурации по умолчанию:
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
// Пустой дескриптор для http_server
httpd_handle_t server = NULL;

// Запуск httpd-сервера:
if (httpd_start(&server, &config) == ESP_OK)
{
// Регистрация URI-обработчиков:
httpd_register_uri_handler(server, &uri_get);
httpd_register_uri_handler(server, &uri_post);
}

// Если сервер не запустился, то дескриптор server будет равен NULL
return server; }

Параметры:

config -- [in] Конфигурация для нового экземпляра сервера.
handle -- [out] Дескриптор для нового созданного экземпляра сервера. == NULL в случае ошибки.

Возвращаемые значения:

ESP_OK: экземпляр сервера успешно создан
ESP_ERR_INVALID_ARG: недопустимые аргументы (NULL в параметре config?)
ESP_ERR_HTTPD_ALLOC_MEM: не получилось выделить память для экземпляра сервера
ESP_ERR_HTTPD_TASK: не получилось запустить задачу сервера

esp_err_t httpd_stop (httpd_handle_t handle);

Остановит web-сервер. Освобождается память/ресурсы, используемые экземпляром HTTP-сервера, и этот экземпляр удаляется. После удаления, дескриптор удаленного сервера больше не может использоваться для доступа к этому экземпляру.

Пример использования:

// Функция для остановки web-сервера
void stop_webserver(httpd_handle_t server) {
// Проверка, что дескриптор не NULL
if (server != NULL) {
// Остановка httpd сервера
httpd_stop(server);
} }

Параметры:

handle -- [in] Дескриптор сервера, возвращенный вызовом httpd_start.

Возвращаемое значение:

ESP_OK: сервер успешно остановлен.
ESP_ERR_INVALID_ARG: аргумент server == NULL.

esp_err_t httpd_sess_set_recv_override (httpd_handle_t hd,
int sockfd,
httpd_recv_func_t recv_func);

Переопределит функцию приема веб-сервера (по FD, файловому дескриптору сессии). Эта же функция используется для чтения пакетов HTTP-запросов.

Замечание: эта API-функция предполагается для вызова либо из контекста http-сессии, либо из API, где sockfd является допустимым параметром, либо из обработчика URI, где sockfd получен вызовом httpd_req_to_sockfd().

Параметры:

hd -- [in] дескриптор экземпляра сервера HTTPD.
sockfd -- [in] Session socket FD (файловый дескриптор сокета сессии).
recv_func -- [in] функция приема для установки в этой сессии.

Возвращаемые значения:

ESP_OK: замена успешно зарегистрирована.
ESP_ERR_INVALID_ARG: Null-аргументы.

esp_err_t httpd_sess_set_send_override (httpd_handle_t hd,
int sockfd,
httpd_send_func_t send_func);

Переопределит функцию передачи web-сервера (по FD, файловому дескриптору сессии). Эта же функция используется для отправки ответа на любой HTTP-запрос.

Замечание: подразумевается, что эта API-функция вызывается либо из контекста http-сессии, либо из API, где sockfd является допустимым параметром, либо из обработчика URI, где sockfd получен вызовом httpd_req_to_sockfd().

Параметры:

hd -- [in] дескриптор экземпляра сервера HTTPD.
sockfd -- [in] Session socket FD (файловый дескриптор сокета сессии).
send_func -- [in] функция отправки для установки в этой сессии.

Возвращаемые значения:

ESP_OK: замена успешно зарегистрирована.
ESP_ERR_INVALID_ARG: Null-аргументы.

esp_err_t httpd_sess_set_pending_override (httpd_handle_t hd,
int sockfd,
httpd_pending_func_t pending_func);

Переопределение функции ожидания веб-сервера (по сеансовому FD). Эта функция переопределяет функцию ожидания веб-сервера. Используется для проверки наличия ожидающих байтов в сокете.

Замечание: эта API-функция подразумевается для вызова либо из контекста http-сессии, либо из API, где sockfd является допустимым параметром, либо из URI-обработчика, где sockfd получен вызовом httpd_req_to_sockfd().

Параметры:

hd -- [in] дескриптор экземпляра сервера HTTPD.
sockfd -- [in] Session socket FD (файловый дескриптор сокета сессии).
pending_func -- [in] функция ожидания для установки в этой сессии.

Возвращаемые значения:

ESP_OK: замена успешно зарегистрирована.
ESP_ERR_INVALID_ARG: Null-аргументы.

esp_err_t httpd_req_async_handler_begin (httpd_req_t *r, httpd_req_t **out);

Запустит асинхронный запрос. Эта функция может быть вызвана в обработчике запроса, чтобы получить копию запроса, которая может использоваться в асинхронном потоке (async thread).

Замечание: эта функция нужна для того, чтобы одновременно обрабатывать несколько запросов. Пример использования см. в examples/protocols/http_server/async_handlers.

Вы должны вызвать httpd_req_async_handler_complete(), когда завершили работу с этим запросом.

Параметры:

r -- [in] Запрос для создания асинхронной копии.
out -- [out] Новый созданный запрос, который может быть использован в async thread.

Возвращаемое значение ESP_OK: асинхронный запрос был успешно создан.

esp_err_t httpd_req_async_handler_complete (httpd_req_t *r);

Пометит асинхронный запрос как завершенный. Этот вызов:

● Освободит память запроса.
● Отказывается от владения нижележащим сокетом, чтобы его можно было использовать повторно.
● Позволит http-серверу закрыть наш сокет при необходимости (lru_purge_enable).

Замечание: если асинхронные запросы не помечаются как завершенные, то иногда сервер не сможет принимать входящие соединения. В этом случае сервер будет выводить в лог сообщение об ошибке "httpd_accept_conn: error in accept (23)".

Параметры:

r -- [in] Запрос пометки асинхронной работы как завершенной.

Возвращаемое значение ESP_OK: асинхронный запрос был помечен как завершенный.

int httpd_req_to_sockfd (httpd_req_t *r);

Получение дескриптора сокета (Socket Descriptor) из HTTP-запроса.

Эта API-функция возвратит дескриптор сокета сессии, для которой был выполнен URI-обработчик на приеме HTTP-запроса. Это полезно, когда пользователь хочет вызвать функции, которые требуют файловый дескриптор сессии (socket fd) сессии, из URI-обработчика, например: httpd_sess_get_ctx(), httpd_sess_trigger_close(), httpd_sess_update_lru_counter().

Замечание: предполагается, что эта API-функция вызывается только из контекста URI-обработчика, где httpd_req_t* допустимый указатель запроса.

Параметры:

r -- [in] Запрос, дескриптор сокета которого необходимо найти.

Возвращаемые значения:

Дескриптор сокета: socket descriptor для этого запроса.
-1: недопустимый/NULL указатель запроса.

int httpd_req_recv (httpd_req_t *r, char *buf, size_t buf_len);

API для чтения данных содержимого из HTTP-запроса.

Эта функция прочитает данные содержимого запроса (HTTP content data) в предоставленный буфер buf. Используйте поле content_len структуры httpd_req_t, чтобы узнать длину извлекаемых данных. Если content_len слишком большое для буфера, то пользователь может сделать несколько вызов этой функции, каждый раз извлекая buf_len байт, при этом указатель на данные содержимого внутренне инкрементируется на это же значение.

Замечания:

● Предполагается, что эта API-функция вызывается только из контекста URI-обработчика, где httpd_req_t* является допустимым указателем запроса.
● Если возвращается ошибка, обработчик URI должен далее вернуть ошибку. Это гарантирует, что ошибочный сокет будет закрыт и очищен веб-сервером.
● В настоящее время Chunked Encoding не поддерживается (см. врезку ниже).

Параметры:

r -- [in] Запрос, на который формируется ответ.
buf -- [in] Указатель на буфер, куда должны быть прочитаны данные.
buf_len -- [in] Длина предоставленного буфера.

Возвращаемые значения:

N: количество байт, успешно прочитанных в буфер.
0: параметр длины буфера 0, или соединение закрыто на удаленной стороне.
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket recv().
HTTPD_SOCK_ERR_FAIL: не восстановимая ошибка при вызове socket recv().

"В настоящее время Chunked Encoding не поддерживается" означает, что в настоящее время HTTP-сервер не поддерживает механизм передачи данных по частям (chunked encoding).

[Что такое Chunked Encoding]

Chunked Transfer Encoding — метод передачи HTTP-данных, при котором тело ответа или запроса разбивается на отдельные "чанки" (куски). Каждый чанк имеет свой размер и передается отдельно.

[Как работает Chunked Encoding]

Обычная передача:

Content-Length: 245
[все 245 байт данных сразу]

Chunked Encoding:

Transfer-Encoding: chunked

5
Hello
6
 World
0

- `5` — размер первого чанка (5 байт)
- `Hello` — данные первого чанка
- `6` — размер второго чанка (6 байт)  
- ` World` — данные второго чанка
- `0` — маркер окончания передачи

[Что это значит для ESP HTTP-сервера]

Ограничения:

1. Только фиксированный размер: сервер ожидает, что клиент укажет точный размер данных в заголовке `Content-Length`.
2. Нет потоковой передачи: нельзя передавать данные по частям без знания общего размера.
3. Все данные сразу: необходимо знать полный размер данных до начала передачи.

Пример проблемы:

// Если клиент отправит запрос с Transfer-Encoding: chunked
// httpd_req_recv() не сможет его корректно обработать esp_err_t my_handler(httpd_req_t *req) {
char buf[100];
int ret = httpd_req_recv(req, buf, sizeof(buf));
// При chunked encoding это может работать некорректно }

[Практические последствия]

Что МОЖЕТ ESP HTTP сервер:
- Принимать запросы с заголовком `Content-Length`
- Читать данные известного размера через `httpd_req_recv()`
- Обрабатывать статические файлы известного размера

Что НЕ МОЖЕТ ESP HTTP сервер:
- Принимать данные в потоковом режиме (например, видеостриминг)
- Обрабатывать запросы, где размер данных неизвестен заранее
- Работать с некоторыми типами прокси и клиентов, использующих chunked encoding

[Обходные пути]

Если нужно передавать данные неизвестного размера, можно:

1. Использовать другой протокол: WebSockets, MQTT
2. Буферизировать данные: сначала собрать все данные, потом отправить с `Content-Length`
3. Использовать multipart/form-data: для загрузки файлов

[Почему это важно]

Если клиент отправит запрос с `Transfer-Encoding: chunked`, то ESP HTTP-сервер:

- Не поймет формат данных
- Вернет ошибку при чтении
- Закроет соединение (как рекомендует документация)

size_t httpd_req_get_hdr_value_len (httpd_req_t *r, const char *field);

Поиск поля в заголовках запроса и возврат длины строки его значения.

Замечания:

● Предполагается, что эта API-функция вызывается только из контекста URI-обработчика, где httpd_req_t* это допустимый указатель запроса.
● Как только была вызвана API-функция httpd_resp_send(), все заголовки запроса выпиливаются, так что они должны быть копированы в отдельные буфера, если их данные могут потребоваться позже.

Параметры:

r -- [in] Запрос, на который формируется ответ.
field -- [in] Полез заголовка, которое ищется в запросе.

Возвращаемые значения:

Длина: если поле найдено в URL запроса.
0: поле не найдено / недопустимый запрос / Null-аргументы.

esp_err_t httpd_req_get_hdr_value_str (httpd_req_t *r,
const char *field,
char *val,
size_t val_size);

Получение значения строки поля из заголовков запроса.

Замечания:

● Предполагается, что эта API-функция вызывается только из контекста URI-обработчика, где httpd_req_t* это допустимый указатель запроса.
● Как только была вызвана API-функция httpd_resp_send(), все заголовки запроса выпиливаются, так что они должны быть копированы в отдельные буфера, если их данные могут потребоваться позже.
● Если размер выходных данных больше, чем входной буфер, то значение обрезается с сопровождением кода ошибки обрезки в возвращаемом значении.
● Используйте httpd_req_get_hdr_value_len(), чтобы узнать правильную длину буфера.

Параметры:

r -- [in] Запрос, на который формируется ответ.
field -- [in] Поле, которое ищется в заголовке.
val -- [out] Указатель на буфер, куда копируется значение поля, если это поле найдено.
val_size -- [in] Размер пользовательского буфера "val".

Возвращаемые значения:

ESP_OK: поле найдено в заголовке запроса, и его значение было скопировано в буфер val.
ESP_ERR_NOT_FOUND: поле не найдено.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый указатель HTTP-запроса.
ESP_ERR_HTTPD_RESULT_TRUNC: строка значения была обрезана.

size_t httpd_req_get_url_query_len (httpd_req_t *r);

Извлекает длину строки запроса из URL-адреса запроса.

Замечание: подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.

Параметры:

r -- [in] Запрос, на который формируется ответ.

Возвращаемые значения:

длина: запрос найден в URL.
0: запрос не найден / Null-аргументы / недопустимый запрос / uri пустой.

esp_err_t httpd_req_get_url_query_str (httpd_req_t *r, char *buf, size_t buf_len);

Извлечет строку запроса из URL-адреса запроса.

Замечания:

● В настоящее время пользователь может извлечь полную строку запроса URL, но её декодирование он должен выполнить самостоятельно. Заголовки запроса можно прочитать с помощью httpd_req_get_hdr_value_str(), чтобы узнать 'Content-Type' (например Content-Type: application/x-www-form-urlencoded), тогда нужно применить подходящий алгоритм декодирования.
● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Если выходной размер больше входного буфера, то значение строки обрезается, сопровождаясь соответствующим кодом ошибки в возвращаемом значении.
● Перед вызовом этой функции можно сделать вызов httpd_req_get_url_query_len(), чтобы предварительно узнать длину строки запроса, и по этой длине выделить буфер правильного размера (обычно этот размер равен длине строки запроса + 1 для байта null-терминатора) для сохранения строки запроса.

Параметры:

r -- [in] Запрос, на который формируется ответ.
buf -- [out] Указатель на буфер, куда будет копироваться строка запроса (если она найдена).
buf_len -- [in] Длина выходного буфера.

Возвращаемые значения:

ESP_OK: запрос найден в URL-адресе запроса и скопирован в буфер.
ESP_FAIL: uri пуст.
ESP_ERR_NOT_FOUND: запрос не найден.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый указатель HTTP-запроса.
ESP_ERR_HTTPD_RESULT_TRUNC: строка запроса обрезана.

esp_err_t httpd_query_key_value (const char *qry,
const char *key,
char *val,
size_t val_size);

Вспомогательная функция для получения тега URL-запроса из строки запроса типа param1=val1¶m2=val2.

Замечания:

● Компоненты строки запроса (ключи и значения) не декодированы (not URLdecoded). Пользователь должен проверить поле 'Content-Type' в заголовках запроса, и затем в зависимости от указанного кодирования (URLencoded или что-то другое) применить подходящий алгоритм декодирования.
● Если фактическая длина значения больше, чем val_size, то значение будет обрезано, сопровождаясь соответствующим кодом ошибки возвращаемого значения.

Параметры:

qry -- [in] Указатель на строку запроса.
key -- [in] Ключ, который ищется в строке запроса.
val -- [out] Указатель на буфер, в который должно быть помещено значение, если ключ key найден.
val_size -- [in] Размер буфера пользователя val.

Возвращаемые значения:

ESP_OK: ключ найден в строке URL-запроса, и его значение было скопировано в буфер.
ESP_ERR_NOT_FOUND: ключ не найден.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESULT_TRUNC: строка значения была обрезана.

esp_err_t httpd_req_get_cookie_val (httpd_req_t *req,
const char *cookie_name,
char *val,
size_t *val_size);

Получит строку значения cookie-файла из заголовков запроса «Cookie» по имени cookie.

Параметры:

req -- [in] Указатель на HTTP-запрос.
cookie_name -- [in] Имя cookie, которое ищется в запросе.
val -- [out] Указатель на буфер, в который значение cookie будет копироваться, если cookie найден.
val_size -- [inout] Указатель на размер буфера пользователя val. Эта переменная будет содержать длину cookie, если возвращаемое значение ESP_OK, и требуемую длину буфера, если возвращаемое значение ESP_ERR_HTTPD_RESULT_TRUNC.

Возвращаемые значения:

ESP_OK: ключ найден в строке cookie, и значение скопировано в буфер.
ESP_ERR_NOT_FOUND: ключ не найден.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESULT_TRUNC: значение строки обрезано.
ESP_ERR_NO_MEM: ошибка выделения памяти.

bool httpd_uri_match_wildcard (const char *uri_template,
const char *uri_to_match,
size_t match_upto);

Проверка, соответствует ли URI предоставленному шаблону wildcard.

Шаблон может оканчиваться на '?' чтобы сделать предыдущий символ опциональным (обычно слеш), '*' для совпадения wildcard, и '?*' чтобы сделать предыдущий символ опциональным, и обеспечить совпадение, если что-то идет дальше.

Примеры:

* совпадет с любым значением.
/api/? совпадет с /api и /api/
/api/* (без backslash) совпадет с /api/ и /api/status, но не с /api или /ap
/api/?* или /api/*? (без backslash) совпадет с /api/, /api/status, а также /api, но не с /apix или /ap

Специальные символы '?' и '*' в любом месте шаблона будут восприниматься буквально.

Параметры:

uri_template -- [in] URI template (шаблон)
uri_to_match -- [in] URI для проверки на совпадение
match_upto -- [in] сколько символов в буфере URI проверять (может быть завершающая строка запроса, и т. п.)

Возвращаемое значение: true если было обнаружено совпадение.

esp_err_t httpd_resp_send (httpd_req_t *r,
const char *buf,
ssize_t buf_len);

API-функция для отправки полного HTTP-ответа.

Отправит данные в качестве HTTP-ответа на запрос. Подразумевается, что вы подготовили полный готовый запрос в одном буфере. Если вы хотите послать ответ последовательными кусками, то используйте вместо этого httpd_resp_send_chunk().

Если код статуса и тип содержимого не были заданы, по умолчанию будет отправлен код статуса 200 OK и тип содержимого как text/html. Вы можете вызвать следующие функции перед этим API для настройки заголовков ответа: httpd_resp_set_status() — для установки строки статуса HTTP, httpd_resp_set_type() — для установки типа содержимого, httpd_resp_set_hdr() — для добавления любых дополнительных значений полей в заголовок ответа.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● После вызова этой API-функции на запрос выдается ответ.
● Никаких дополнительных данных не может быть отправлено для запроса.
● После вызова этой API-функции все заголовки запроса выпиливаются, так что необходимо их предварительно копировать в отдельные буферы, если они позже могут понадобиться.

Параметры:

r -- [in] Запрос, на который посылается ответ.
buf -- [in] Буфер, из которого извлекается содержимое.
buf_len -- [in] Длина буфера, HTTPD_RESP_USE_STRLEN для использования strlen().

Возвращаемые значения:

ESP_OK: пакет ответа успешно отправлен.
ESP_ERR_INVALID_ARG: Null в указателе на запрос.
ESP_ERR_HTTPD_RESP_HDR: необходимые заголовки слишком велики для внутреннего буфера.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

esp_err_t httpd_resp_send_chunk (httpd_req_t *r,
const char *buf,
ssize_t buf_len);

API для отправки HTTP-ответа по частям.

Эта API-функция отправит данные в качестве HTTP-ответа на запрос. Будет использоваться кодирование по частям и отправка ответа в виде фрагментов. Если весь ответ находится в одном буфере, используйте вместо этого функцию httpd_resp_send().

Если код статуса и тип контента не заданы, по умолчанию будут отправлены код статуса 200 OK и тип контента в формате text/html. Для настройки заголовков ответа перед этим API можно вызвать следующие функции: httpd_resp_set_status() — для установки строки статуса HTTP, httpd_resp_set_type() — для установки типа контента, httpd_resp_set_hdr() — для добавления любых дополнительных значений полей в заголовок ответа.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Когда вы завершили отправку всех ваших фрагментов ответа на запрос, то необходимо вызвать эту функцию, где в параметре buf_len указан 0.
● После вызова этой API-функции все заголовки запроса выпиливаются, так что необходимо их предварительно копировать в отдельные буферы, если они позже могут понадобиться.

Параметры:

r -- [in] Запрос, на который посылается ответ.
buf -- [in] Указатель на буфер, где сохранены данные.
buf_len -- [in] Длина буфера, HTTPD_RESP_USE_STRLEN для использования strlen().

Возвращаемые значения:

ESP_OK: был успешно отправлен фрагмент ответа.
ESP_ERR_INVALID_ARG: Null в указателе на запрос.
ESP_ERR_HTTPD_RESP_HDR: необходимые заголовки слишком велики для внутреннего буфера.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

static inline esp_err_t httpd_resp_sendstr_chunk (httpd_req_t *r, const char *str);

API для отправки строки в качестве фрагмента HTTP-ответа.

Эта API-функция просто вызовет httpd_resp_send_chunk с длиной буфера, установленной на длину строки. Подразумевается, что строка в буфере содержит байт null-терминатора.

Параметры:

r -- [in] Запрос, на который посылается ответ.
str -- [in] Строка для отправки в теле ответа (NULL для завершения пакета ответа).

Возвращаемые значения:

ESP_OK: при успешной отправке пакета ответа.
ESP_ERR_INVALID_ARG: Null в указателе на запрос.
ESP_ERR_HTTPD_RESP_HDR: необходимые заголовки слишком велики для внутреннего буфера.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

esp_err_t httpd_resp_set_status (httpd_req_t *r, const char *status);

API для установки HTTP status code.

Эта API-функция установит статус HTTP-ответа в указанное значение. По умолчанию посылается '200 OK' в качестве ответа.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Эта функция только устанавливает статус в указанное значение. Этот статус не будет отправлен, пока не будет выполнена API-функция отправки.
● Обеспечьте достоверность буфера status до возврата из функции отправки.

Параметры:

r -- [in] Запрос, на который формируется ответ.
status -- [in] Код статуса HTTP для ответа.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый указатель на запрос.

esp_err_t httpd_resp_set_type (httpd_req_t *r, const char *type);

API для установки типа контента (HTTP content type).

Эта API-функция установит поле 'Content Type' ответа на запрос. По умолчанию content type 'text/html'.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Эта функция только устанавливает тип контента в указанное значение. Этот статус не будет отправлен, пока не будет выполнена API-функция отправки.
● Обеспечьте достоверность буфера строки type до возврата из функции отправки.

Параметры:

r -- [in] Запрос, на который формируется ответ.
type -- [in] Content Type ответа.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый указатель на запрос.

esp_err_t httpd_resp_set_hdr (httpd_req_t *r, const char *field, const char *value);

API для добавления любых дополнительных заголовков.

Эта API-функция установит поля дополнительного заголовка, который необходимо послать в ответе на запрос.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Заголовок не будет отправлен, пока не будет выполнена API-функция отправки.
● Максимальное допустимое количество дополнительных заголовков ограничвается значением max_resp_headers в структуре config.
● Обеспечьте достоверность буфера строк field и value до возврата из функции отправки.

Параметры:

r -- [in] Запрос, на который формируется ответ.
field -- [in] Имя поля в заголовке HTTP.
value -- [in] Значение этого заголовка HTTP.

Возвращаемые значения:

ESP_OK: успешно присоединен новый заголовок.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESP_HDR: общее количество дополнительных заголовков превысило допустимое значение.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый указатель на запрос.

esp_err_t httpd_resp_send_err (httpd_req_t *req,
httpd_err_code_t error,
const char *msg);

Функция для отправки кода ошибки в ответе на HTTP-запрос.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Как только вызвана эта API-функция, все заголовки запроса выпиливаются, так что они должны быть скопированы в отдельный буфер, если понадобятся впоследствии.
● Если вы хотите послать дополнительные данные в теле ответа, то напрямую используйте низкоуровневые функции.

Параметры:

req -- [in] Указатель на HTTP-запрос, для которого надо послать ответ.
error -- [in] Тип отправляемой ошибки.
msg -- [in] Строка сообщения об ошибке (передайте NULL для отправки сообщения по умолчанию).

Возвращаемые значения:

ESP_OK: был успешно отправлен пакет ответа.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

esp_err_t httpd_resp_send_custom_err (httpd_req_t *req,
const char *status,
const char *msg);

API-функция для отправки пользовательского кода ошибки в ответ на HTTP-запрос.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Как только вызвана эта API-функция, все заголовки запроса выпиливаются, так что они должны быть скопированы в отдельный буфер, если понадобятся впоследствии.
● Если вы хотите послать дополнительные данные в теле ответа, то напрямую используйте низкоуровневые функции.

Параметры:

req -- [in] Указатель на HTTP-запрос, для которого надо послать ответ.
status -- [in] Статус ошибки для отправки.
msg -- [in] Строка сообщения об ошибке.

Возвращаемые значения:

ESP_OK: был успешно отправлен пакет ответа.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

static inline esp_err_t httpd_resp_send_404 (httpd_req_t *r);

Вспомогательная функция для HTTP 404.

Отправит сообщение об ошибке HTTP 404. Если вы хотите послать дополнительные данные в теле ответа, то напрямую используйте низкоуровневые функции.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Как только вызвана эта API-функция, все заголовки запроса выпиливаются, так что они должны быть скопированы в отдельный буфер, если понадобятся впоследствии.

Параметры:

r -- [in] Указатель на HTTP-запрос, для которого надо послать ответ.

Возвращаемые значения:

ESP_OK: был успешно отправлен пакет ответа.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

static inline esp_err_t httpd_resp_send_408 (httpd_req_t *r);

Вспомогательная функция для HTTP 408.

Отправит сообщение об ошибке HTTP 408. Если вы хотите послать дополнительные данные в теле ответа, то напрямую используйте низкоуровневые функции.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Как только вызвана эта API-функция, все заголовки запроса выпиливаются, так что они должны быть скопированы в отдельный буфер, если понадобятся впоследствии.

Параметры:

r -- [in] Указатель на HTTP-запрос, для которого надо послать ответ.

Возвращаемые значения:

ESP_OK: был успешно отправлен пакет ответа.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

static inline esp_err_t httpd_resp_send_500 (httpd_req_t *r);

Вспомогательная функция для HTTP 500.

Отправит сообщение об ошибке HTTP 500. Если вы хотите послать дополнительные данные в теле ответа, то напрямую используйте низкоуровневые функции.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Как только вызвана эта API-функция, все заголовки запроса выпиливаются, так что они должны быть скопированы в отдельный буфер, если понадобятся впоследствии.

Параметры:

r -- [in] Указатель на HTTP-запрос, для которого надо послать ответ.

Возвращаемые значения:

ESP_OK: был успешно отправлен пакет ответа.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_RESP_SEND: ошибка при отправке необработанных данных.
ESP_ERR_HTTPD_INVALID_REQ: недопустимый запрос.

int httpd_send (httpd_req_t *r, const char *buf, size_t buf_len);

Отправка необработанных (raw) данных HTTP.

Вызовите эту API-функцию, если хотите сами сконструировать свой пакет ответа. При использовании этого метода все основные заголовки, например HTTP version, Status Code, Content Type и Length, Encoding, и т. д. придется создавать вручную, а разделители HTTP (CRLF) необходимо будет правильно разместить для разделения подразделов пакета ответа HTTP.

Если установлена функция переопределения отправки, то в конечном итоге будет вызвана эта функция для отправки данных.

Замечания:

● Подразумевается, что эта API-функция вызывается только из контекста URI-обработчика, где указатель запроса httpd_req_t* достоверный.
● Если ответ не имеет корректной HTTP-структуры (что теперь в зоне ответственности пользователя), то нет гарантии, что он будет распознан клиентом. В большинстве случаев вам не придётся вызывать этот API, так что лучше использовать один из следующих методов: httpd_resp_send() или httpd_resp_send_chunk().

Параметры:

r -- [in] Запрос, на который формируется ответ.
buf -- [in] Буфер, откуда вычитывается полный пакет, сконструированный пользователем.
buf_len -- [in] Длина буфера.

Возвращаемые значения:

Bytes: количество успешно отправленных байт.
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket send().
HTTPD_SOCK_ERR_FAIL: невосстановимая ошибка при вызове socket send().

int httpd_socket_send (httpd_handle_t hd,
int sockfd,
const char *buf,
size_t buf_len,
int flags);

Низкоуровневый API для отправки данных на предоставленном сокете.

Эта функция внутренне вызывает функцию отправки по умолчанию, или функцию, зарегистрированную httpd_sess_set_send_override().

Замечание: не рекомендуется использовать это API в любом обработчике запроса. Эта API-функция предназначена для особых продвинутых случаев, когда некоторые асинхронные данные необходимо передать через сокет.

Параметры:

hd -- [in] экземпляр сервера.
sockfd -- [in] файловый дескриптор сокета сессии.
buf -- [in] буфер с байтами для отправки.
buf_len -- [in] размер отправляемых данных.
flags -- [in] флаги для функции send().

Возвращаемые значения:

Bytes: количество успешно отправленных байт.
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket send().
HTTPD_SOCK_ERR_FAIL: невосстановимая ошибка при вызове socket send().

int httpd_socket_recv (httpd_handle_t hd,
int sockfd,
char *buf,
size_t buf_len,
int flags);

Низкоуровневый API для приема данных из предоставленного сокета.

Эта функция внутренне вызывает функцию приема по умолчанию, или функцию, зарегистрированную httpd_sess_set_recv_override().

Замечание: не рекомендуется использовать это API в любом обработчике запроса. Эта API-функция предназначена для особых продвинутых случаев, когда требуется некая асинхронная коммуникация.

Параметры:

hd -- [in] экземпляр сервера.
sockfd -- [in] файловый дескиптор сокета сессии.
buf -- [in] буфер для приема данных.
buf_len -- [in] размер буфера.
flags -- [in] флаги для функции recv().

Возвращаемые значения:

Bytes: количество успешно принятых байт.
0: нулевой параметр длины буфера или соединение закрыто на удаленной стороне.
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket recv().
HTTPD_SOCK_ERR_FAIL: невосстановимая ошибка при вызове socket recv().

esp_err_t httpd_register_err_handler (httpd_handle_t handle,
httpd_err_code_t error,
httpd_err_handler_func_t handler_fn);

Функция для регистрации обработчиков ошибок (HTTP error handlers).

Эта функция привязывает функцию обработчика к любому поддерживаемому коду ошибки httpd_err_code_t. См. далее описание прототипа функции httpd_err_handler_func_t.

Параметры:

handle -- [in] дескриптор сервера HTTP.
error -- [in] тип ошибки.
handler_fn -- [in] реализованная пользователем функция обработчика (передайте здесь NULL для снятия ранее установленного обработчика).

Возвращаемые значения:

ESP_OK: обработчик был успешно зарегистрирован.
ESP_ERR_INVALID_ARG: недопустимый код ошибки или дескриптор сервера.

esp_err_t httpd_ws_recv_frame (httpd_req_t *req,
httpd_ws_frame_t *pkt,
size_t max_len);

Прием и парсинг кадра WebSocket.

Замечание: вызов httpd_ws_recv_frame() с max_len == 0 выдаст фактический размер кадра в pkt->len. Пользователь может динамически выделить пространство для pkt->payload на эту длину, и еще раз вызвать httpd_ws_recv_frame() для получения реальных данных. См. соответствующий пример для использования.

Параметры:

req -- [in] текущий запрос.
pkt -- [out] пакет WebSocket.
max_len -- [in] максимальная длина для приема.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_FAIL: произошли ошибки сокета.
ESP_ERR_INVALID_STATE: рукопожатие уже было сделано заранее.
ESP_ERR_INVALID_ARG: недопустимый аргумент (null или non-WebSocket).

esp_err_t httpd_ws_send_frame (httpd_req_t *req, httpd_ws_frame_t *pkt);

Конструирует и отправляет кадр WebSocket.

Параметры:

req -- [in] текущий запрос.
pkt -- [in] кадр WebSocket.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_FAIL: произошли ошибки сокета.
ESP_ERR_INVALID_STATE: рукопожатие уже было сделано заранее.
ESP_ERR_INVALID_ARG: недопустимый аргумент (null или non-WebSocket).

esp_err_t httpd_ws_send_frame_async (httpd_handle_t hd,
int fd,
httpd_ws_frame_t *frame);

Низкоуровневая отправка кадра WebSocket вне области текущего запроса с использованием внутренне настроенной функции отправки httpd.

Этот API редко следует вызывать напрямую, за исключением асинхронной отправки с использованием httpd_queue_work.

Параметры:

hd -- [in] данные экземпляра сервера.
fd -- [in] дескриптор сокета для отправки данных.
frame -- [in] кадр WebSocket.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_FAIL: произошли ошибки сокета.
ESP_ERR_INVALID_STATE: рукопожатие уже было сделано заранее.
ESP_ERR_INVALID_ARG: недопустимый аргумент (null или non-WebSocket).

httpd_ws_client_info_t httpd_ws_get_fd_info (httpd_handle_t hd, int fd);

Проверяет предоставленный дескриптор сокета, принадлежит ли он какому-либо активному клиенту данного экземпляра сервера и активен ли протокол websoket.

Параметры:

hd -- [in] данные экземпляра сервера.
fd -- [in] дескриптор сокета.

Возвращаемые значения:

HTTPD_WS_CLIENT_INVALID: этот fd не клиент этого httpd.
HTTPD_WS_CLIENT_HTTP: этот fd активный клиент, протокол не WS.
HTTPD_WS_CLIENT_WEBSOCKET: этот fd активный клиент, протокол WS.

esp_err_t httpd_ws_send_data (httpd_handle_t handle,
int socket,
httpd_ws_frame_t *frame);

Синхронно отправит данные в указанный websocket.

Параметры:

handle -- [in] данные экземпляра сервера.
socket -- [in] дескриптор сокета.
frame -- [in] кадр Websocket.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_FAIL: когда произошли ошибки сокета.
ESP_ERR_NO_MEM: не получилось выделить память.

esp_err_t httpd_ws_send_data_async (httpd_handle_t handle,
int socket,
httpd_ws_frame_t *frame,
transfer_complete_cb callback,
void *arg);

Асинхронно отправит данные в указанный websocket.

Параметры:

handle -- [in] данные экземпляра сервера.
socket -- [in] дескриптор сокета.
frame -- [in] кадр Websocket.
callback -- [in] функция обратного вызова, запускаемая после отправки данных.
arg -- [in] пользовательские данные, передаваемые в предоставленный callback.

Возвращаемые значения:

ESP_OK: при успехе.
ESP_FAIL: когда произошли ошибки сокета.
ESP_ERR_NO_MEM: не получилось выделить память.

esp_err_t httpd_register_uri_handler (httpd_handle_t handle,
const httpd_uri_t *uri_handler);

Регистрирует URI-обработчик. Пример использования:

esp_err_t my_uri_handler(httpd_req_t* req)
{
// Прием, обработка и отправка
....
....
....

// Обработка ситуации ошибки
if (....) {
// Возврат ошибки для закрытия сессии
return ESP_FAIL;
}

// При успехе
return ESP_OK; }

// Структура URI-обработчика httpd_uri_t my_uri {
.uri = "/my_uri/path/xyz",
.method = HTTP_GET,
.handler = my_uri_handler,
.user_ctx = NULL };

// Регистрация обработчика
if (httpd_register_uri_handler(server_handle, &my_uri) != ESP_OK) {
// Если произошла ошибка регистрации обработчика
.... }

Замечание: URI-обработчики могут быть зарегистрированы во время выполнения (real time) пока достоверен дескриптор сервера.

Параметры:

handle -- [in] дескриптор экземпляра сервера HTTPD.
uri_handler -- [in] указатель на обработчик, который должен быть зарегистрирован.

Возвращаемые значения:

ESP_OK: обработчик успешно зарегистрирован.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_HTTPD_HANDLERS_FULL: если не осталось слотов для нового обработчика.
ESP_ERR_HTTPD_HANDLER_EXISTS: если у обработчика такой же URI и метод уже зарегистрирован.

esp_err_t httpd_unregister_uri_handler (httpd_handle_t handle,
const char *uri,
httpd_method_t method);

Отменит регистрацию URI-обработчика.

Параметры:

handle -- [in] дескриптор экземпляра сервера HTTPD.
uri -- [in] строка URI.
method -- [in] метод HTTP.

Возвращаемые значения:

ESP_OK: обработчик был успешно дерегистрирован.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_NOT_FOUND: обработчик с указанным URI и метод не найдены.

esp_err_t httpd_unregister_uri (httpd_handle_t handle, const char *uri);

Отменит все URI-обработчики с указанной строкой uri.

Параметры:

handle -- [in] дескриптор экземпляра сервера HTTPD.
uri -- [in] строка URI, указывающая все обработчики, которые должны быть дерегистрированы.

Возвращаемые значения:

ESP_OK: были успешно дерегистрированы все такие обработчики.
ESP_ERR_INVALID_ARG: Null-аргументы.
ESP_ERR_NOT_FOUND: нет обработчиков, зарегистрированных с указанной строкой uri.

esp_err_t httpd_queue_work (httpd_handle_t handle,
httpd_work_fn_t work,
void *arg);

Постановка в очередь функции на выполнение в контексте HTTPD.

Эта API-функция ставит в очередь функцию work для асинхронного выполнения.

Замечание: некоторые протоколы требуют, чтобы web-сервер генерировал некие асинхронные данные и посылал их на постоянно открытое соединение. Эта фича как раз для использования с такими протоколами.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
work -- [in] указатель на функцию для выполнения в контексте HTTPD.
arg -- [in] указатель на аргументы, которые должны быть переданы в эту функцию.

Возвращаемые значения:

ESP_OK: функция work успешно поставлена в очередь.
ESP_FAIL: ошибка в ctrl socket.
ESP_ERR_INVALID_ARG: Null-аргументы.

void *httpd_sess_get_ctx (httpd_handle_t handle, int sockfd);

Получит контекст сессии из дескриптора сокета.

Обычно если контекст сессии создан, он доступен для URI-обработчиков через структуру httpd_req_t. Однако бывают случаи, когда send/receive функции web-сервера могут требовать контекст (например, для доступа к ключевой информации и т. п.). Поскольку функция send/receive располагает только дескриптором сокета, этот API предоставляет им возможность получить контекст сессии.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
sockfd -- [in] дескриптор сокета, для которого должен быть извлечен контекст.

Возвращаемые значения:

void*: указатель на контекст, связанный с этой сессией.
NULL: пустой контекст / недопустимый handle / недопустимый fd сокета.

void httpd_sess_set_ctx (httpd_handle_t handle,
int sockfd,
void *ctx,
httpd_free_ctx_fn_t free_fn);

Установит контекст сеанса по дескриптору сокета.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
sockfd -- [in] дескриптор сокета, для которого должен быть установлен контекст.
ctx -- [in] объект контекста для назначения сессии.
free_fn -- [in] функция, которая должна быть вызвана для освобождения контекста.

void *httpd_sess_get_transport_ctx (httpd_handle_t handle, int sockfd);

Получит 'transport' контекст по дескриптору сокета.

Этот контекст используется для функций send/receive, например для обслуживания контекста SSL. См. также httpd_sess_get_ctx().

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
sockfd -- [in] дескриптор сокета, для которого должен быть извлечен контекст.

Возвращаемые значения:

void*: указатель на контекст транспорта, связанный с этой сессией.
NULL: пустой контекст / недопустимый handle / недопустимый fd сокета.

void httpd_sess_set_transport_ctx (httpd_handle_t handle,
int sockfd,
void *ctx,
httpd_free_ctx_fn_t free_fn);

Установит контекст 'transport' по дескриптору сокета.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
sockfd -- [in] дескриптор сокета, для которого должен быть установлен контекст.
ctx -- [in] объект контекста транспорта для назначения сессии.
free_fn -- [in] функция, которая должна быть вызвана для освобождения контекста транспорта.

void *httpd_get_global_user_ctx (httpd_handle_t handle);

Получит глобальный контекст пользователя HTTPD (он был установлен в структуре config сервера).

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.

Возвращаемое значение: глобальный контекст пользователя.

void *httpd_get_global_transport_ctx (httpd_handle_t handle);

Получит глобальный контекст транспорта HTTPD (он был установлен в структуре config сервера).

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.

Возвращаемое значение: глобальный контекст транспорта.

esp_err_t httpd_sess_trigger_close (httpd_handle_t handle, int sockfd);

Инициирует закрытие httpd-сессии извне.

Замечание: вызов этой API-функции требуется только в специальных случаях, когда какое-то приложение требует асинхронно закрыть сессию клиента httpd.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
sockfd -- [in] дескриптор сокета, сессия которого закрывается.

Возвращаемые значения:

ESP_OK: успешно инициированное закрытие.
ESP_FAIL: сбой при постановке в очередь.
ESP_ERR_NOT_FOUND: fd сокета не найден.
ESP_ERR_INVALID_ARG: Null-аргументы.

esp_err_t httpd_sess_update_lru_counter (httpd_handle_t handle, int sockfd);

Обновит счетчик LRU для указанного сокета. LRU расшифровывается как Least Recently Used, т. е. "последний использованный".

Счетчики LRU, внутренне связанные с каждой сессией, предназначены для мониторинга, как часто проходит трафик через сессию. Когда разрешена очистка этих счетчиков (LRU purge), если клиент запрашивает соединение, но достигнут максимум сокетов/сессий, то сессия, у которой самый ранний счетчик LRU, закроется автоматически.

Обновление счетчика LRU вручную предотвращает очистку сокета логикой LRU, даже когда на нем некоторое время не было трафика. Это полезно, когда все открытые сокеты/сессии часто обмениваются трафиком, но пользователь специально хочет, чтобы одна из сессий оставалась открытой, независимо от того, когда через неё последний раз передавался пакет.

Замечание: вызов этой API-функции необходим только когда разрешена опция LRU Purge Enable.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
sockfd -- [in] дескриптор сокета для сессии, у которой должен быть обновлен счетчик LRU.

Возвращаемое значение:

ESP_OK: сокет найден и счетчик LRU его сессии обновлен.
ESP_ERR_NOT_FOUND: сокет не найден.
ESP_ERR_INVALID_ARG: Null-аргументы.

esp_err_t httpd_get_client_list (httpd_handle_t handle,
size_t *fds,
int *client_fds);

Возвратит список текущих дескрипторов сокетов активных сессий.

Замечание: размер предоставленного массива должен быть равен или больше количества открытых сокетов, сконфигурированных полем max_open_sockets в структуре httpd_config_t structure при инициализации сервера.

Параметры:

handle -- [in] дескриптор сервера, возвращенный из httpd_start.
fds -- [inout] In: размер предоставленного массива client_fds.
                    Out: количество допустимых fds клиента, возвращенных в client_fds.
client_fds -- [out] массив fds клиентов.

Возвращаемые значения:

ESP_OK: успешно получен список сессий.
ESP_ERR_INVALID_ARG: неправильные аргументы или список больше, чем предоставленный массив.

[Используемые структуры (esp_http_server.h)]

/** Структура аргумента для событий HTTP_SERVER_EVENT_ON_DATA
и HTTP_SERVER_EVENT_SENT_DATA event */
typedef struct {
int fd; /*!< файловый дескриптор сокета сессии */
int data_len; /*!< длина данных */ } esp_http_server_event_data;

/**
* @brief Структура конфигурации HTTP-сервера
*
* @note Используйте HTTPD_DEFAULT_CONFIG() для инициализации конфигурации
* в значения по умолчанию, и затем по необходимости модифицируйте
* только те поля, которые специально влияют на ваш сценарий использования.
*/
typedef struct httpd_config {
unsigned task_priority; /*!< Приоритет задачи FreeRTOS в которой работает сервер */
size_t stack_size; /*!< Максимальный размер стека задачи сервера */
BaseType_t core_id; /*!< Идентификатор ядра сервера HTTP, который будет запущен */
uint32_t task_caps; /*!< Особенности памяти для использования при выделении
пространства стека задачи HTTP-сервера */

/**
* Номер TCP-порта для приема и передачи трафика HTTP
*/
uint16_t server_port;

/**
* Номер UDP-порта для асинхронного обмена сигналами управления между различными
* компонентами сервера.
*/
uint16_t ctrl_port;
uint16_t max_open_sockets; /*!< Максимальное количество сокетов/клиентов, открытых
в любое время (3 сокета резервируются для внутренней
работы сервера HTTP) */
uint16_t max_uri_handlers; /*!< Максимальное количество обработчиков URI */
uint16_t max_resp_headers; /*!< Максимально допустимое количество дополнительных
заголовков в HTTP-ответе */
uint16_t backlog_conn; /*!< Количество backlog-соединений (см. примечание (1)) */
bool lru_purge_enable; /*!< Разрешить закрывать "Least Recently Used" соединение */
uint16_t recv_wait_timeout; /*!< Таймаут для функции приема (в секундах)*/
uint16_t send_wait_timeout; /*!< Таймаут для функции отправки (в секундах)*/

/**
* Глобальный контекст пользователя.
*
* Это поле может использоваться для сохранения произвольных данных пользователя
* в контексте сервера. Это значение может быть получено через дескриптор сервера
* как доступное в структуре httpd_req_t struct.
*
* При выключении сервер освободит контекст пользователя вызовом free()
* на поле global_user_ctx field. Если вы хотите использовать пользовательскую
* функцию для освобождения глобального контекста пользователя, то
* укажите её в поле global_user_ctx_free_fn.
*/
void * global_user_ctx;

/**
* Функция для освобождения глобального контекста пользователя.
*/
httpd_free_ctx_fn_t global_user_ctx_free_fn;

/**
* Глобальный контекст транспорта.
*
* Это данные подобны global_user_ctx, но они используются для кодирования
* или шифрования сессии (например, для хранения контекста SSL).
* Они будут освобождены вызовом free(), если не была специально предоставлена
* пользовательская функция global_transport_ctx_free_fn.
*/
void * global_transport_ctx;

/**
* Функция освобождения глобального контекста транспорта.
*/
httpd_free_ctx_fn_t global_transport_ctx_free_fn;
bool enable_so_linger; /*!< разрешение/запрет linger (см. примечание (2)) */
int linger_timeout; /*!< таймаут linger (в секундах) */
bool keep_alive_enable; /*!< Разрешит keep-alive таймаут */
int keep_alive_idle; /*!< Keep-alive время ожидания. По умолчанию 5 (секунд) */
int keep_alive_interval;/*!< Keep-alive время интервала. По умолчанию 5 (секунд) */
int keep_alive_count; /*!< Keep-alive счетчик повторов отправки пакета.
По умолчанию 3 */

/**
* Пользовательский callback открытия сессии.
*
* Вызывается на новом сокете сессии сразу после accept(), но перед чтением любых данных.
*
* Это возможность настроить, например, SSL-шифрование с помощью global_transport_ctx
* и переопределения сеансов send/recv/pending.
*
* Если контекст нуждается в поддержке между этими функциями, сохраните его в сессии,
* используя httpd_sess_set_transport_ctx(), и извлекайте контекст позже вызовом
* httpd_sess_get_transport_ctx().
*
* Возврат значения, отличающегося от ESP_OK, приведет к немедленному закрытию нового сокета.
*/
httpd_open_func_t open_fn;

/**
* Пользовательский callback закрытия сессии.
*
* Вызывается, когда сессия удаляется, перед освобождением контекстов пользователя
* и транспорта, и перед закрытием сокета. Это то место, куда помещают пользовательский
* de-init код, общий для всех сокетов.
*
* Сервер закроет сокет только в том случае, если не установлен пользовательский callback
* закрытия сессии. Если используется пользовательский callback, то в нем должна быть
* вызвана close(sockfd) для большинства случаев.
*
* Если здесь освобождаются контексты пользователя или транспорта, то установите
* их указатели в NULL, тогда сервер не будет их освобождать повторно.
* * Эта функция вызывается для всех прерванных сессий, включая те, у которых сокет был
* закрыт сетевым стеком, то есть дескриптор файла может быть больше недействительным.
*/ httpd_close_func_t close_fn;

/**
* Функция совпадения URI.
*
* Вызывается, когда происходит поиск соответствия URI:
* 1) обработчик запросов которого должен быть выполнен сразу
* после успешного анализа HTTP-запроса
* 2) для предотвращения дублирования при регистрации нового
* обработчика URI с помощью httpd_register_uri_handler()
*
* Доступны опции:
* 1) NULL: внутренне выполняемая базовая проверка на совпадение
* с помощью strncmp()
* 2) httpd_uri_match_wildcard(): используется URI wildcard matcher
*
* Пользователи могут реализовать свои собственные функции проверки
* совпадения (см. описание прототипа функции httpd_uri_match_func_t).
*/
httpd_uri_match_func_t uri_match_fn; } httpd_config_t;

Примечание (1): Backlog-соединения (также называемые "очередью ожидающих соединений") - это максимальное количество TCP-соединений, которые могут находиться в состоянии ожидания принятия сервером, когда он уже обрабатывает максимальное количество активных соединений.

Как это работает:

1. Сервер слушает на определенном порту.
2. Клиенты устанавливают соединение через трехстороннее рукопожатие TCP.
3. Соединение переходит в состояние `SYN_RECEIVED` и помещается в очередь backlog.
4. Сервер принимает соединение из backlog-очереди, когда готов его обработать.

На практике:

- Когда сервер занят обработкой существующих соединений, новые входящие соединения попадают в backlog-очередь.
- Если очередь заполнена, новые соединения будут отклоняться.
- Размер backlog влияет на устойчивость сервера к пиковым нагрузкам.

Пример настройки в ESP-IDF:

httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.backlog_conn = 10;  // Очередь из 10 ожидающих соединений

// Если приходит 11-е соединение, когда сервер занят и очередь полна,
// оно будет немедленно отклонено

Типичные значения:

- Маленькие значения (3-10) - для устройств с ограниченными ресурсами.
- Средние значения (10-50) - для большинства встраиваемых систем.
- Большие значения (50+) - для серверов, ожидающих высокие нагрузки.

В контексте HTTP-сервера на ESP32 параметр backlog_conn помогает справляться с кратковременными всплесками запросов, не теряя соединения.

Примечание (2): Linger (задержка) это опция сокета, которая определяет поведение при закрытии TCP-сокета, когда в буфере остаются не переданные данные.

Без linger (enable_so_linger = false):

- При вызове close() система немедленно возвращает управление
- ОС в фоне пытается отправить оставшиеся данные
- Соединение закрывается, даже если данные не доставлены

При разрешенном linger (enable_so_linger = true):

- При вызове close() система блокирует выполнение на linger_timeout секунд
- ОС пытается отправить все данные из буфера
- Если данные отправлены до истечения таймаута - соединение закрывается корректно
- Если таймаут истек - соединение принудительно разрывается

Практический пример:

httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.enable_so_linger = true;
config.linger_timeout = 5;  // Ждать до 5 секунд

// При закрытии соединения:
// 1. Система попытается отправить все оставшиеся HTTP-данные
// 2. Если за 5 секунд не успеет - соединение будет принудительно закрыто

Когда использовать:

✅ Включить linger:
- Важные HTTP-ответы, которые должны быть доставлены
- Критичные данные, которые нельзя потерять
- Когда клиент должен получить полный ответ

❌ Выключить linger:
- Высоконагруженные серверы (помогает избегать блокировок)
- Реaltime-приложения, где важна скорость
- Когда потеря части данных допустима

В контексте HTTP-сервера Linger помогает гарантировать, что клиент получит полный HTTP-ответ перед закрытием соединения, особенно при медленных сетях или больших объемах данных.

/**
* @brief Структура данных запроса HTTP */
typedef struct httpd_req {
httpd_handle_t handle; /*!< дескриптор экземпляра сервера */
int method; /*!< Тип HTTP-запроса, -1 если не поддерживаемый метод,
HTTP_ANY для wildcard-метода универсальной поддержки */
const char uri[HTTPD_MAX_URI_LEN + 1]; /*!< URI этого запроса (1 доп. байт для null-терминатора) */
size_t content_len; /*!< длина тела запроса */
void *aux; /*!< внутренне используемые данные */

/**
* Указатель на контекст пользователя, переданный при регистрации URI.
*/
void *user_ctx;

/**
* Указатель на контекст сессии (Session Context Pointer)
*
* Контекст сессии. Контексты сохраняются между 'сессиями' для указанного открытого
* TCP-соединения. В одной сессии может быть несколько запросов и ответов.
* Web-сервер обеспечит постоянный контекст между всеми этими запросами и ответами.
*
* По умолчанию это NULL. URI-обработчики могут установить это поле в осмысленное значение.
*
* Если нижележащий сокет закрывается, и этот указатель не NULL, то web-сервер освободит
* контекст вызовом free(), если не была установлена функция free_ctx.
*/
void *sess_ctx;

/**
* Указатель на хук освобождения контекста.
*
* Функция для освобождения контекста сессии.
*
* Если сокет web-сервера закрывается, он освободит контекст сессии вызовом free()
* на поле sess_ctx. Если вы хотите иметь пользовательскую функцию для освобождения
* контекста, то укажите её в этом месте.
*/
httpd_free_ctx_fn_t free_ctx;

/**
* Флаг, показывающий, должны ли быть игнорированы изменения контекста сессии.
*
* По умолчанию, если вы меняете sess_ctx в каком-то URI-обработчике, то http-сервер
* будет внутренне освобождать предыдущий контекст (если он не NULL) после возврата
* из URI-обработчика. Если вы хотите сами управлять выделением / изменением
* выделения / освобождением sess_ctx, то установите этот флаг в true, тогда
* сервер не будет выполнять соответствующие проверки контекста. Контекст будет
* очищен сервером (вызовом free_ctx или free()) только если сокет закрывается.
*/
bool ignore_sess_ctx_changes; } httpd_req_t;

/**
* @brief Структура для URI-обработчика
*/
typedef struct httpd_uri {
const char *uri; /*!< URI для обработки */
httpd_method_t method; /*!< Метод, поддерживаемый URI, HTTP_ANY для
универсального wildcard-метода */

/**
* Обработчик для вызова поддерживаемого метода запроса. Он должен возвратить
* ESP_OK, или иначе нижележащий сокет будет закрыт.
*/
esp_err_t (*handler)(httpd_req_t *r);

/**
* Указатель на данные контекста пользователя, которые будут доступны для обработчика
*/
void *user_ctx;

#ifdef CONFIG_HTTPD_WS_SUPPORT
/**
* Флаг, показывающий конечную точку WebSocket.
* Если этот флаг true, то метод должен быть HTTP_GET. Иначе handshake не будет обработан.
*/
bool is_websocket;

/**
* Флаг, показывающий, что кадры управления (PING, PONG, CLOSE) также переданы в обработчик.
* Это используется, если необходима пользовательская обработка кадров управления.
*/
bool handle_ws_control_frames;

/**
* Указатель на суб-протокол, поддерживаемый URI
*/
const char *supported_subprotocol;
#endif } httpd_uri_t;

/**
* @brief Формат кадра WebSocket
*/
typedef struct httpd_ws_frame {
bool final; /*!< Конечный кадр:
Для принятых кадров это поле показывает, был ли установлен
флаг `FIN`.
Для передаваемых кадров это поле используется только если
также установлена опция `fragmented`. Если `fragmented` == false,
то по умолчанию флаг `FIN` устанавливается, делая ws_frame
кадром полного/не фрагментированного сообщения (esp_http_server
не делает автоматическую фрагментацию сообщений) */
bool fragmented; /*!< Показывает, что кадр, выделенный для передачи, это фрагмент
сообщения, так что флаг `FIN` устанавливается вручную
в соответствии с опцией `final`. Этот флаг никогда не
устанавливается для принятых сообщений */
httpd_ws_type_t type; /*!< Тип кадра WebSocket */
uint8_t *payload; /*!< Предварительно выделенный буфер данных */
size_t len; /*!< Длина данных WebSocket */ } httpd_ws_frame_t;

[Используемые макросы (esp_http_server.h)]

HTTP_ANY

HTTPD_SOCK_ERR_FAIL

HTTPD_SOCK_ERR_INVALID

HTTPD_SOCK_ERR_TIMEOUT

HTTPD_200 HTTP Response 200

HTTPD_204 HTTP Response 204

HTTPD_207 HTTP Response 207

HTTPD_400 HTTP Response 400

HTTPD_404 HTTP Response 404

HTTPD_408 HTTP Response 408

HTTPD_500 HTTP Response 500

HTTPD_TYPE_JSON HTTP Content type JSON

HTTPD_TYPE_TEXT HTTP Content type text/HTML

HTTPD_TYPE_OCTET HTTP Content type octext-stream

ESP_HTTPD_DEF_CTRL_PORT HTTP Server control socket port

HTTPD_DEFAULT_CONFIG() 

ESP_ERR_HTTPD_BASE Начальное значение кодов ошибок HTTPD

ESP_ERR_HTTPD_HANDLERS_FULL Задействован все слоты зарегистрированных URI-обработчиков.

ESP_ERR_HTTPD_HANDLER_EXISTS URI-обработчик с таким же методом и целевым URI уже зарегистрирован.

ESP_ERR_HTTPD_INVALID_REQ Недопустимый указатель запроса.

ESP_ERR_HTTPD_RESULT_TRUNC Строка результата обрезана.

ESP_ERR_HTTPD_RESP_HDR Поле заголовка ответа больше, чем поддерживается.

ESP_ERR_HTTPD_RESP_SEND Произошла ошибка при отправке пакета ответа.

ESP_ERR_HTTPD_ALLOC_MEM Не получилось динамически выделить память для ресурса.

ESP_ERR_HTTPD_TASK Не получилось запустить задачу/поток сервера.

HTTPD_RESP_USE_STRLEN 

[Используемые определения типа]

typedef void *httpd_handle_t
Дескриптор HTTP-сервера. У каждого экземпляра сервера будет уникальный дескриптор.

typedef enum http_method httpd_method_t
Обертка типа метода HTTP над перечислением http_method, доступным в библиотеке http_parser.

typedef void (*httpd_free_ctx_fn_t)(void *ctx)
Прототип функции для освобождения данных контекста (если она присутствует). Параметр ctx [in] указывает на освобождаемый объект.

typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd)
Прототип функции для открытия сессии. Вызывается немедленно после того, как сокет был открыт, для установки функций send/recv и других параметров сокета.

Параметры:
hd: [in] экземпляр сервера
sockfd: [in] файловый дескриптор сокета сессии

Возвращаемое значение:
ESP_OK: при успехе. Любое другое значение сигнализирует, что сервер немедленно закроет сокет.

typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd)
Прототип функции для закрытия сессии.

Замечание:  существует возможность, что в этой точке дескриптор сокета недопустимый, эта функция вызывается для всех завершенных сессий. Обеспечьте правильную обработку кодов возврата.

Параметры:
hd: [in] экземпляр сервера
sockfd: [in] файловый дескриптор сокета сессии

typedef bool (*httpd_uri_match_func_t) (const char *reference_uri,
                                        const char *uri_to_match,
                                        size_t match_upto)
Прототип функции проверки совпадения URI.

Параметры:
reference_uri: [in] образцовый URI/шаблон, на соответствие которому проверяется другой URI.
uri_to_match: [in] URI/шаблон, совпадающий с образцовым URI/шаблоном.
match_upto: [in] для указания реальной длины uri_to_match по которому применяется алгоритм проверки соответствия (максимальное значение это strlen(uri_to_match), независимо от длины reference_uri)

Возвращаемое значение: true при обнаруженном совпадении.

typedef struct httpd_config httpd_config_t
Структура конфигурации HTTP-сервера.

Замечание: используйте HTTPD_DEFAULT_CONFIG() для инициализации конфигурации в состояние по умолчанию, и затем модифицируйте те поля, которые специально нужны для вашего случая применения.

typedef int (*httpd_send_func_t)(httpd_handle_t hd,
                                 int sockfd,
                                 const char *buf,
                                 size_t buf_len,
                                 int flags)
Прототип для низкоуровневой функции отправки HTTPD.

Замечание: предоставленная пользователем функция должна внутри себя обрабатывать ошибки, в зависимости от установленного значения errno, и возвращать специальные коды HTTPD_SOCK_ERR_ codes, которые в конечном итоге будут переданы как возвращаемые значения функции httpd_send().

Параметры:
hd: [in] экземпляр сервера
sockfd: [in] файловый дескриптор сокета сессии
buf: [in] буфер для отправляемых байт
buf_len: [in] размер данных
flags: [in] флаги для функции send()

Возвращаемые значения:
Bytes: количество успешно отправленных байт.
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket send().
HTTPD_SOCK_ERR_FAIL: невосстановимая ошибка при вызове socket send().

typedef int (*httpd_recv_func_t)(httpd_handle_t hd,
                                 int sockfd, char *buf,
                                 size_t buf_len,
                                 int flags)
Прототип для низкоуровневой функции приема HTTPD.

Замечание: предоставленная пользователем функция должна внутри себя обрабатывать ошибки, в зависимости от установленного значения errno, и возвращать специальные коды HTTPD_SOCK_ERR_ codes, которые в конечном итоге будут переданы как возвращаемые значения функции httpd_req_recv().

Параметры:
hd: [in] экземпляр сервера
sockfd: [in] файловый дескриптор сокета сессии
buf: [in] буфер для принимаемых байт
buf_len: [in] размер данных
flags: [in] флаги для функции recv()

Возвращаемые значения:
Bytes: количество успешно принятых байт.
0: длина параметра длины буфера 0 / соединение закрыто на удаленной стороне.
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket recv().
HTTPD_SOCK_ERR_FAIL: невосстановимая ошибка при вызове socket recv().

typedef int (*httpd_pending_func_t)(httpd_handle_t hd, int sockfd)
Прототип для низкоуровневой функции HTTPD "get pending bytes" (получение ожидающих байт).

Замечание: предоставленная пользователем функция должна внутри себя обрабатывать ошибки, в зависимости от установленного значения errno, и возвращать специальные коды HTTPD_SOCK_ERR_ codes, которые будут соответственно обрабатываться в задаче сервера.

Параметры:
hd: [in] экземпляр сервера
sockfd: [in] файловый дескриптор сокета сессии

Возвращаемые значения:
Bytes: количество байт, ожидающих приема
HTTPD_SOCK_ERR_INVALID: недопустимые аргументы.
HTTPD_SOCK_ERR_TIMEOUT: таймаут/прервано при вызове socket pending().
HTTPD_SOCK_ERR_FAIL: невосстановимая ошибка при вызове socket pending().

typedef esp_err_t (*httpd_err_handler_func_t)(httpd_req_t *req,
                                              httpd_err_code_t error)
Прототип функции для обработки ошибок HTTP.

Эта функция вызывается при ошибках HTTP, генерируемых при внутренней обработке HTTP-запроса. Это используется для переопределения поведения по умолчанию для ошибки, при котором посылаются ответы HTTP error и закрывается нижележащий сокет.

Замечания:

● Если функция реализована, то сервер не будет автоматически посылать коды ответа HTTP error, так что httpd_resp_send_err() должна вызываться внутри этой функции, если пользователю нужно генерировать ответы HTTP error.
● При вызове не гарантируется достоверность полей uri, method, content_len и user_ctx параметра httpd_req_t, поскольку HTTP-запрос может быть частично получен/проанализирован.
● Эта функция должна возвратить ESP_OK, если нижележащий сокет должен сохраняться открытым. Любое другое значение будет гарантировать закрытие сокета. Возвращаемое значение игнорируется, когда ошибка типа HTTPD_500_INTERNAL_SERVER_ERROR и сокет все равно закрыт.

Параметры:
req: [in] HTTP-запрос, для которого должна быть обработана ошибка
error: [in] тип ошибки

Возвращаемые значения:
ESP_OK: ошибка была успешно обработана
ESP_FAIL: сбой, показывающий что нижележащий сокет должен быть закрыт.

typedef struct httpd_ws_frame httpd_ws_frame_t
Формат кадра WebSocket.

typedef void (*transfer_complete_cb)(esp_err_t err, int socket, void *arg)
Функция обратного вызова (callback) завершения транзакции.

typedef struct httpd_req httpd_req_t
Структура данных запроса HTTP.

typedef struct httpd_uri httpd_uri_t
Структура для URI-обработчика.

typedef void (*httpd_work_fn_t)(void *arg)
Прототип рабочей функции сервера (HTTPD work). Подробности см. в описании функции httpd_queue_work() []. Параметр arg: [in] задает аргументы для этой work-функции.

[Используемые перечисления (esp_http_server.h)]

/**
* @brief Коды ошибки, отправляемые как HTTP-ответ в случае ошибок,
* возникающих при обработке HTTP-запроса
*/
typedef enum {
/* Код для любых неожиданных ошибок во время парсинга, наподобие неожиданных
* переходов между состояниями или необработанных ошибок.
*/
HTTPD_500_INTERNAL_SERVER_ERROR = 0,

/* Для методов, не поддерживаемых http_parser. В настоящее время
* http_parser останавливает парсинг, когда встречаются такие методы,
* и тогда сервер отвечает вместо этого ошибкой 400 Bad Request.
*/
HTTPD_501_METHOD_NOT_IMPLEMENTED,

/* Когда HTTP-версия не 1.1 или 1.0 */
HTTPD_505_VERSION_NOT_SUPPORTED,

/* Возвращается, когда http_parser остановил парсинг из-за некорректного
* синтаксиса запроса, не поддерживаемого метода в URI запроса или
* из-за фрагментированного encoding / upgrade поля, присутствующего
* в заголовках
*/
HTTPD_400_BAD_REQUEST,

/* Этот ответ означает, что клиент должен себя аутентифицировать, чтобы
* получить ответ на запрос.
*/
HTTPD_401_UNAUTHORIZED,

/* Клиент не имеет прав для доступа к содержимому, так что сервер
* отказался от предоставления запрошенного ресурса. В отличие
* от ошибки 401, сервер идентифицировал клиента.
*/
HTTPD_403_FORBIDDEN,

/* Когда запрошенный URI не найден */
HTTPD_404_NOT_FOUND,

/* Когда URI найден, но запрошен метод без обработчика */
HTTPD_405_METHOD_NOT_ALLOWED,

/* Предназначен для таймаута приема. В нестоящее время также посылается
* и для других ошибок приема. Клиент должен подразумевать, что сервер
* немедленно закроет соединение после ответа этим кодом.
*/
HTTPD_408_REQ_TIMEOUT,

/* Предназначено для ответа на фрагментарное кодирование, которое
* в настоящий момент не поддерживается. Хотя необработанный http_parser
* callback возвратит в ответ на фрагментированный запрос ошибку
* "400 Bad Request".
*/
HTTPD_411_LENGTH_REQUIRED,

/* Пришедшая полезная нагрузка слишком велика */
HTTPD_413_CONTENT_TOO_LARGE,

/* Длина URI больше, чем CONFIG_HTTPD_MAX_URI_LEN */
HTTPD_414_URI_TOO_LONG,

/* Секция заголовков больше, чем CONFIG_HTTPD_MAX_REQ_HDR_LEN */
HTTPD_431_REQ_HDR_FIELDS_TOO_LARGE,

/* Используется внутренне для получения общего количества кодов ошибок */
HTTPD_ERR_CODE_MAX } httpd_err_code_t;

/**
* @brief Перечисление для типов пакета WebSocket (Opcode в заголовке)
* @note Подробности см. в RFC6455 Section 5.4.
*/
typedef enum {
HTTPD_WS_TYPE_CONTINUE = 0x0,
HTTPD_WS_TYPE_TEXT = 0x1,
HTTPD_WS_TYPE_BINARY = 0x2,
HTTPD_WS_TYPE_CLOSE = 0x8,
HTTPD_WS_TYPE_PING = 0x9,
HTTPD_WS_TYPE_PONG = 0xA } httpd_ws_type_t;

/**
* @brief Перечисление для описания информации клиента
*/
typedef enum {
HTTPD_WS_CLIENT_INVALID = 0x0,
HTTPD_WS_CLIENT_HTTP = 0x1,
HTTPD_WS_CLIENT_WEBSOCKET = 0x2, } httpd_ws_client_info_t;

/**
* @brief Идентификаторы событий HTTP-сервера
*/
typedef enum {
HTTP_SERVER_EVENT_ERROR = 0, /*!< Возникает при любой ошибке во время выполнения */
HTTP_SERVER_EVENT_START, /*!< При старте HTTP-сервера */
HTTP_SERVER_EVENT_ON_CONNECTED, /*!< Клиент соединился с HTTP-сервером, передачи данных еще не было */
HTTP_SERVER_EVENT_ON_HEADER, /*!< При получении каждого заголовка, отправленного клиентом */
HTTP_SERVER_EVENT_HEADERS_SENT, /*!< После отправки всех заголовков клиенту */
HTTP_SERVER_EVENT_ON_DATA, /*!< При получении данных от клиента */
HTTP_SERVER_EVENT_SENT_DATA, /*!< При завершении сесии ESP HTTP-сервера */
HTTP_SERVER_EVENT_DISCONNECTED, /*!< При разрыве соединения */
HTTP_SERVER_EVENT_STOP, /*!< При остановке HTTP-сервера */ } esp_http_server_event_id_t;

[Ссылки]

1. ESP32 HTTP Server site:espressif.com.
2. ESP-IDF Event Loop Library.

 

Добавить комментарий


Защитный код
Обновить

Top of Page