Skip to content

Commit

Permalink
Merge branch 'feature/esp_http_server_esp_events' into 'master'
Browse files Browse the repository at this point in the history
esp_http_server: Added support for esp_events

See merge request espressif/esp-idf!21132
  • Loading branch information
mahavirj committed Dec 21, 2022
2 parents 9748158 + 0885d85 commit 9a7dd9a
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 1 deletion.
2 changes: 1 addition & 1 deletion components/esp_http_server/CMakeLists.txt
Expand Up @@ -7,7 +7,7 @@ idf_component_register(SRCS "src/httpd_main.c"
"src/util/ctrl_sock.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "src/port/esp32" "src/util"
REQUIRES http_parser # for http_parser.h
REQUIRES esp_event http_parser # for http_parser.h
PRIV_REQUIRES lwip mbedtls esp_timer)

target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
24 changes: 24 additions & 0 deletions components/esp_http_server/include/esp_http_server.h
Expand Up @@ -14,13 +14,37 @@
#include <http_parser.h>
#include <sdkconfig.h>
#include <esp_err.h>
#include <esp_event.h>

#ifdef __cplusplus
extern "C" {
#endif

#define ESP_HTTPD_DEF_CTRL_PORT (32768) /*!< HTTP Server control socket port*/

ESP_EVENT_DECLARE_BASE(ESP_HTTP_SERVER_EVENT);

/**
* @brief HTTP Server events id
*/
typedef enum {
HTTP_SERVER_EVENT_ERROR = 0, /*!< This event occurs when there are any errors during execution */
HTTP_SERVER_EVENT_START, /*!< This event occurs when HTTP Server is started */
HTTP_SERVER_EVENT_ON_CONNECTED, /*!< Once the HTTP Server has been connected to the client, no data exchange has been performed */
HTTP_SERVER_EVENT_ON_HEADER, /*!< Occurs when receiving each header sent from the client */
HTTP_SERVER_EVENT_HEADERS_SENT, /*!< After sending all the headers to the client */
HTTP_SERVER_EVENT_ON_DATA, /*!< Occurs when receiving data from the client */
HTTP_SERVER_EVENT_SENT_DATA, /*!< Occurs when an ESP HTTP server session is finished */
HTTP_SERVER_EVENT_DISCONNECTED, /*!< The connection has been disconnected */
HTTP_SERVER_EVENT_STOP, /*!< This event occurs when HTTP Server is stopped */
} esp_http_server_event_id_t;

/** Argument structure for HTTP_SERVER_EVENT_ON_DATA and HTTP_SERVER_EVENT_SENT_DATA event */
typedef struct {
int fd; /*!< Session socket file descriptor */
int data_len; /*!< Data length */
} esp_http_server_event_data;

/*
note: esp_https_server.h includes a customized copy of this
initializer that should be kept in sync
Expand Down
6 changes: 6 additions & 0 deletions components/esp_http_server/src/esp_httpd_priv.h
Expand Up @@ -544,6 +544,12 @@ esp_err_t httpd_sess_trigger_close_(httpd_handle_t handle, struct sock_db *sessi
* @}
*/

/**
* @brief Function to dispatch events in default event loop
*
*/
void esp_http_server_dispatch_event(int32_t event_id, const void* event_data, size_t event_data_size);

#ifdef __cplusplus
}
#endif
Expand Down
14 changes: 14 additions & 0 deletions components/esp_http_server/src/httpd_main.c
Expand Up @@ -30,6 +30,16 @@ typedef struct {

static const char *TAG = "httpd";

ESP_EVENT_DEFINE_BASE(ESP_HTTP_SERVER_EVENT);

void esp_http_server_dispatch_event(int32_t event_id, const void* event_data, size_t event_data_size)
{
esp_err_t err = esp_event_post(ESP_HTTP_SERVER_EVENT, event_id, event_data, event_data_size, portMAX_DELAY);
if (err != ESP_OK) {
ESP_LOGE(TAG, "Failed to post esp_http_server event: %s", esp_err_to_name(err));
}
}

static esp_err_t httpd_accept_conn(struct httpd_data *hd, int listen_fd)
{
/* If no space is available for new session, close the least recently used one */
Expand Down Expand Up @@ -101,6 +111,7 @@ static esp_err_t httpd_accept_conn(struct httpd_data *hd, int listen_fd)
goto exit;
}
ESP_LOGD(TAG, LOG_FMT("complete"));
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_ON_CONNECTED, &new_fd, sizeof(int));
return ESP_OK;
exit:
close(new_fd);
Expand Down Expand Up @@ -507,6 +518,8 @@ esp_err_t httpd_start(httpd_handle_t *handle, const httpd_config_t *config)
}

*handle = (httpd_handle_t)hd;
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_START, NULL, 0);

return ESP_OK;
}

Expand Down Expand Up @@ -556,5 +569,6 @@ esp_err_t httpd_stop(httpd_handle_t handle)
vSemaphoreDelete(hd->ctrl_sock_semaphore);
#endif
httpd_delete(hd);
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_STOP, NULL, 0);
return ESP_OK;
}
1 change: 1 addition & 0 deletions components/esp_http_server/src/httpd_parse.c
Expand Up @@ -401,6 +401,7 @@ static esp_err_t cb_headers_complete(http_parser *parser)

parser_data->status = PARSING_BODY;
ra->remaining_len = r->content_len;
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_ON_HEADER, &(ra->sd->fd), sizeof(int));
return ESP_OK;
}

Expand Down
1 change: 1 addition & 0 deletions components/esp_http_server/src/httpd_sess.c
Expand Up @@ -370,6 +370,7 @@ void httpd_sess_delete(struct httpd_data *hd, struct sock_db *session)
} else {
close(session->fd);
}
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_DISCONNECTED, &session->fd, sizeof(int));

// clear all contexts
httpd_sess_clear_ctx(session);
Expand Down
18 changes: 18 additions & 0 deletions components/esp_http_server/src/httpd_txrx.c
Expand Up @@ -281,13 +281,19 @@ esp_err_t httpd_resp_send(httpd_req_t *r, const char *buf, ssize_t buf_len)
if (httpd_send_all(r, cr_lf_seperator, strlen(cr_lf_seperator)) != ESP_OK) {
return ESP_ERR_HTTPD_RESP_SEND;
}
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_HEADERS_SENT, &(ra->sd->fd), sizeof(int));

/* Sending content */
if (buf && buf_len) {
if (httpd_send_all(r, buf, buf_len) != ESP_OK) {
return ESP_ERR_HTTPD_RESP_SEND;
}
}
esp_http_server_event_data evt_data = {
.fd = ra->sd->fd,
.data_len = buf_len,
};
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_SENT_DATA, &evt_data, sizeof(esp_http_server_event_data));
return ESP_OK;
}

Expand Down Expand Up @@ -369,6 +375,12 @@ esp_err_t httpd_resp_send_chunk(httpd_req_t *r, const char *buf, ssize_t buf_len
if (httpd_send_all(r, "\r\n", strlen("\r\n")) != ESP_OK) {
return ESP_ERR_HTTPD_RESP_SEND;
}
esp_http_server_event_data evt_data = {
.fd = ra->sd->fd,
.data_len = buf_len,
};
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_SENT_DATA, &evt_data, sizeof(esp_http_server_event_data));

return ESP_OK;
}

Expand Down Expand Up @@ -465,6 +477,7 @@ esp_err_t httpd_resp_send_err(httpd_req_t *req, httpd_err_code_t error, const ch
}
}
#endif
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_ERROR, &error, sizeof(httpd_err_code_t));

return ret;
}
Expand Down Expand Up @@ -532,6 +545,11 @@ int httpd_req_recv(httpd_req_t *r, char *buf, size_t buf_len)
}
ra->remaining_len -= ret;
ESP_LOGD(TAG, LOG_FMT("received length = %d"), ret);
esp_http_server_event_data evt_data = {
.fd = ra->sd->fd,
.data_len = ret,
};
esp_http_server_dispatch_event(HTTP_SERVER_EVENT_ON_DATA, &evt_data, sizeof(esp_http_server_event_data));
return ret;
}

Expand Down
17 changes: 17 additions & 0 deletions docs/en/api-reference/protocols/esp_http_server.rst
Expand Up @@ -158,6 +158,23 @@ Websocket Server
The HTTP server component provides websocket support. The websocket feature can be enabled in menuconfig using the :ref:`CONFIG_HTTPD_WS_SUPPORT` option. Please refer to the :example:`protocols/http_server/ws_echo_server` example which demonstrates usage of the websocket feature.


Event Handling
--------------

ESP HTTP Server has various events for which a handler can be triggered by :doc:`the Event Loop library <../system/esp_event>` when the particular event occurs. The handler has to be registered using :cpp:func:`esp_event_handler_register`. This helps in event handling for ESP HTTP Server.
:cpp:enum:`esp_http_server_event_id_t` has all the events which can happen for ESP HTTP Server.

Expected data type for different ESP HTTP Server events in 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``

API Reference
-------------

Expand Down

0 comments on commit 9a7dd9a

Please sign in to comment.