HTTP Server : Add uri_match_fn field in config structure which accepts custom URI matching functions of type httpd_uri_match_func_t and defaults to basic string compare when set to NULL.
Move static uri_matches() function to httpd_uri_match_wildcard() under esp_http_server.h and make it optional.
This commit is contained in:
parent
107f52c4fc
commit
416c55e7f0
2 changed files with 197 additions and 112 deletions
|
@ -49,6 +49,7 @@ initializer that should be kept in sync
|
|||
.global_transport_ctx_free_fn = NULL, \
|
||||
.open_fn = NULL, \
|
||||
.close_fn = NULL, \
|
||||
.uri_match_fn = NULL \
|
||||
}
|
||||
|
||||
#define ESP_ERR_HTTPD_BASE (0x8000) /*!< Starting number of HTTPD error codes */
|
||||
|
@ -61,6 +62,10 @@ initializer that should be kept in sync
|
|||
#define ESP_ERR_HTTPD_ALLOC_MEM (ESP_ERR_HTTPD_BASE + 7) /*!< Failed to dynamically allocate memory for resource */
|
||||
#define ESP_ERR_HTTPD_TASK (ESP_ERR_HTTPD_BASE + 8) /*!< Failed to launch server task/thread */
|
||||
|
||||
/* Symbol to be used as length parameter in httpd_resp_send APIs
|
||||
* for setting buffer length to string length */
|
||||
#define HTTPD_RESP_USE_STRLEN -1
|
||||
|
||||
/* ************** Group: Initialization ************** */
|
||||
/** @name Initialization
|
||||
* APIs related to the Initialization of the web server
|
||||
|
@ -82,7 +87,7 @@ typedef enum http_method httpd_method_t;
|
|||
|
||||
/**
|
||||
* @brief Prototype for freeing context data (if any)
|
||||
* @param[in] ctx : object to free
|
||||
* @param[in] ctx object to free
|
||||
*/
|
||||
typedef void (*httpd_free_ctx_fn_t)(void *ctx);
|
||||
|
||||
|
@ -92,8 +97,8 @@ typedef void (*httpd_free_ctx_fn_t)(void *ctx);
|
|||
* Called immediately after the socket was opened to set up the send/recv functions and
|
||||
* other parameters of the socket.
|
||||
*
|
||||
* @param[in] hd : server instance
|
||||
* @param[in] sockfd : session socket file descriptor
|
||||
* @param[in] hd server instance
|
||||
* @param[in] sockfd session socket file descriptor
|
||||
* @return status
|
||||
*/
|
||||
typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd);
|
||||
|
@ -104,11 +109,26 @@ typedef esp_err_t (*httpd_open_func_t)(httpd_handle_t hd, int sockfd);
|
|||
* @note It's possible that the socket descriptor is invalid at this point, the function
|
||||
* is called for all terminated sessions. Ensure proper handling of return codes.
|
||||
*
|
||||
* @param[in] hd : server instance
|
||||
* @param[in] sockfd : session socket file descriptor
|
||||
* @param[in] hd server instance
|
||||
* @param[in] sockfd session socket file descriptor
|
||||
*/
|
||||
typedef void (*httpd_close_func_t)(httpd_handle_t hd, int sockfd);
|
||||
|
||||
/**
|
||||
* @brief Function prototype for URI matching.
|
||||
*
|
||||
* @param[in] reference_uri URI/template with respect to which the other URI is matched
|
||||
* @param[in] uri_to_match URI/template being matched to the reference URI/template
|
||||
* @param[in] match_upto For specifying the actual length of `uri_to_match` up to
|
||||
* which the matching algorithm is to be applied (The maximum
|
||||
* value is `strlen(uri_to_match)`, independent of the length
|
||||
* of `reference_uri`)
|
||||
* @return true on match
|
||||
*/
|
||||
typedef bool (*httpd_uri_match_func_t)(const char *reference_uri,
|
||||
const char *uri_to_match,
|
||||
size_t match_upto);
|
||||
|
||||
/**
|
||||
* @brief HTTP Server Configuration Structure
|
||||
*
|
||||
|
@ -195,6 +215,24 @@ typedef struct httpd_config {
|
|||
* was closed by the network stack - that is, the file descriptor may not be valid anymore.
|
||||
*/
|
||||
httpd_close_func_t close_fn;
|
||||
|
||||
/**
|
||||
* URI matcher function.
|
||||
*
|
||||
* Called when searching for a matching URI:
|
||||
* 1) whose request handler is to be executed right
|
||||
* after an HTTP request is successfully parsed
|
||||
* 2) in order to prevent duplication while registering
|
||||
* a new URI handler using `httpd_register_uri_handler()`
|
||||
*
|
||||
* Available options are:
|
||||
* 1) NULL : Internally do basic matching using `strncmp()`
|
||||
* 2) `httpd_uri_match_wildcard()` : URI wildcard matcher
|
||||
*
|
||||
* Users can implement their own matching functions (See description
|
||||
* of the `httpd_uri_match_func_t` function prototype)
|
||||
*/
|
||||
httpd_uri_match_func_t uri_match_fn;
|
||||
} httpd_config_t;
|
||||
|
||||
/**
|
||||
|
@ -227,8 +265,8 @@ typedef struct httpd_config {
|
|||
*
|
||||
* @endcode
|
||||
*
|
||||
* @param[in] config : Configuration for new instance of the server
|
||||
* @param[out] handle : Handle to newly created instance of the server. NULL on error
|
||||
* @param[in] config Configuration for new instance of the server
|
||||
* @param[out] handle Handle to newly created instance of the server. NULL on error
|
||||
* @return
|
||||
* - ESP_OK : Instance created successfully
|
||||
* - ESP_ERR_INVALID_ARG : Null argument(s)
|
||||
|
@ -451,11 +489,11 @@ esp_err_t httpd_unregister_uri(httpd_handle_t handle, const char* uri);
|
|||
* HTTPD_SOCK_ERR_ codes, which will eventually be conveyed as
|
||||
* return value of httpd_send() function
|
||||
*
|
||||
* @param[in] hd : server instance
|
||||
* @param[in] sockfd : session socket file descriptor
|
||||
* @param[in] buf : buffer with bytes to send
|
||||
* @param[in] buf_len : data size
|
||||
* @param[in] flags : flags for the send() function
|
||||
* @param[in] hd server instance
|
||||
* @param[in] sockfd session socket file descriptor
|
||||
* @param[in] buf buffer with bytes to send
|
||||
* @param[in] buf_len data size
|
||||
* @param[in] flags flags for the send() function
|
||||
* @return
|
||||
* - Bytes : The number of bytes sent successfully
|
||||
* - HTTPD_SOCK_ERR_INVALID : Invalid arguments
|
||||
|
@ -472,11 +510,11 @@ typedef int (*httpd_send_func_t)(httpd_handle_t hd, int sockfd, const char *buf,
|
|||
* HTTPD_SOCK_ERR_ codes, which will eventually be conveyed as
|
||||
* return value of httpd_req_recv() function
|
||||
*
|
||||
* @param[in] hd : server instance
|
||||
* @param[in] sockfd : session socket file descriptor
|
||||
* @param[in] buf : buffer with bytes to send
|
||||
* @param[in] buf_len : data size
|
||||
* @param[in] flags : flags for the send() function
|
||||
* @param[in] hd server instance
|
||||
* @param[in] sockfd session socket file descriptor
|
||||
* @param[in] buf buffer with bytes to send
|
||||
* @param[in] buf_len data size
|
||||
* @param[in] flags flags for the send() function
|
||||
* @return
|
||||
* - Bytes : The number of bytes received successfully
|
||||
* - 0 : Buffer length parameter is zero / connection closed by peer
|
||||
|
@ -494,8 +532,8 @@ typedef int (*httpd_recv_func_t)(httpd_handle_t hd, int sockfd, char *buf, size_
|
|||
* HTTPD_SOCK_ERR_ codes, which will be handled accordingly in
|
||||
* the server task.
|
||||
*
|
||||
* @param[in] hd : server instance
|
||||
* @param[in] sockfd : session socket file descriptor
|
||||
* @param[in] hd server instance
|
||||
* @param[in] sockfd session socket file descriptor
|
||||
* @return
|
||||
* - Bytes : The number of bytes waiting to be received
|
||||
* - HTTPD_SOCK_ERR_INVALID : Invalid arguments
|
||||
|
@ -744,9 +782,29 @@ esp_err_t httpd_req_get_url_query_str(httpd_req_t *r, char *buf, size_t buf_len)
|
|||
*/
|
||||
esp_err_t httpd_query_key_value(const char *qry, const char *key, char *val, size_t val_size);
|
||||
|
||||
/* Symbol to be used as length parameter in httpd_resp_send APIs
|
||||
* for setting buffer length to string length */
|
||||
#define HTTPD_RESP_USE_STRLEN -1
|
||||
/**
|
||||
* @brief Test if a URI matches the given wildcard template.
|
||||
*
|
||||
* Template may end with "?" to make the previous character optional (typically a slash),
|
||||
* "*" for a wildcard match, and "?*" to make the previous character optional, and if present,
|
||||
* allow anything to follow.
|
||||
*
|
||||
* Example:
|
||||
* - * matches everything
|
||||
* - /foo/? matches /foo and /foo/
|
||||
* - /foo/\* (sans the backslash) matches /foo/ and /foo/bar, but not /foo or /fo
|
||||
* - /foo/?* or /foo/\*? (sans the backslash) matches /foo/, /foo/bar, and also /foo, but not /foox or /fo
|
||||
*
|
||||
* The special characters "?" and "*" anywhere else in the template will be taken literally.
|
||||
*
|
||||
* @param[in] template URI template (pattern)
|
||||
* @param[in] uri URI to be matched
|
||||
* @param[in] len how many characters of the URI buffer to test
|
||||
* (there may be trailing query string etc.)
|
||||
*
|
||||
* @return true if a match was found
|
||||
*/
|
||||
bool httpd_uri_match_wildcard(const char *template, const char *uri, size_t len);
|
||||
|
||||
/**
|
||||
* @brief API to send a complete HTTP response.
|
||||
|
|
|
@ -23,30 +23,13 @@
|
|||
|
||||
static const char *TAG = "httpd_uri";
|
||||
|
||||
static bool httpd_uri_match_simple(const char *uri1, const char *uri2, size_t len2)
|
||||
{
|
||||
return strlen(uri1) == len2 && // First match lengths
|
||||
(strncmp(uri1, uri2, len2) == 0); // Then match actual URIs
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test if a URI matches the given template.
|
||||
*
|
||||
* Template may end with "?" to make the previous character optional (typically a slash),
|
||||
* "*" for a wildcard match, and "?*" to make the previous character optional, and if present,
|
||||
* allow anything to follow.
|
||||
*
|
||||
* Example:
|
||||
* - * matches everything
|
||||
* - /foo/? matches /foo and /foo/
|
||||
* - /foo/\* (sans the backslash) matches /foo/ and /foo/bar, but not /foo or /fo
|
||||
* - /foo/?* or /foo/\*? (sans the backslash) matches /foo/, /foo/bar, and also /foo, but not /foox or /fo
|
||||
*
|
||||
* The special characters "?" and "*" anywhere else in the template will be taken literally.
|
||||
*
|
||||
* @param[in] template - URI template (pattern)
|
||||
* @param[in] uri - tested URI
|
||||
* @param[in] template - how many characters of the URI buffer to test
|
||||
* (there may be trailing query string etc.)
|
||||
*
|
||||
* @return true if a match was found
|
||||
*/
|
||||
static bool uri_matches(const char *template, const char *uri, const unsigned int len)
|
||||
bool httpd_uri_match_wildcard(const char *template, const char *uri, size_t len)
|
||||
{
|
||||
const size_t tpl_len = strlen(template);
|
||||
size_t exact_match_chars = tpl_len;
|
||||
|
@ -57,12 +40,27 @@ static bool uri_matches(const char *template, const char *uri, const unsigned in
|
|||
const bool asterisk = last == '*' || (prevlast == '*' && last == '?');
|
||||
const bool quest = last == '?' || (prevlast == '?' && last == '*');
|
||||
|
||||
/* Minimum template string length must be:
|
||||
* 0 : if neither of '*' and '?' are present
|
||||
* 1 : if only '*' is present
|
||||
* 2 : if only '?' is present
|
||||
* 3 : if both are present
|
||||
*
|
||||
* The expression (asterisk + quest*2) serves as a
|
||||
* case wise generator of these length values
|
||||
*/
|
||||
|
||||
/* abort in cases such as "?" with no preceding character (invalid template) */
|
||||
if (exact_match_chars < asterisk + quest*2) return false;
|
||||
if (exact_match_chars < asterisk + quest*2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* account for special characters and the optional character if "?" is used */
|
||||
exact_match_chars -= asterisk + quest*2;
|
||||
|
||||
if (len < exact_match_chars) return false;
|
||||
if (len < exact_match_chars) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!quest) {
|
||||
if (!asterisk && len != exact_match_chars) {
|
||||
|
@ -71,14 +69,14 @@ static bool uri_matches(const char *template, const char *uri, const unsigned in
|
|||
}
|
||||
/* asterisk allows arbitrary trailing characters, we ignore these using
|
||||
* exact_match_chars as the length limit */
|
||||
return 0 == strncmp(template, uri, exact_match_chars);
|
||||
return (strncmp(template, uri, exact_match_chars) == 0);
|
||||
} else {
|
||||
/* question mark present */
|
||||
if (len > exact_match_chars && template[exact_match_chars] != uri[exact_match_chars]) {
|
||||
/* the optional character is present, but different */
|
||||
return false;
|
||||
}
|
||||
if (0 != strncmp(template, uri, exact_match_chars)) {
|
||||
if (strncmp(template, uri, exact_match_chars) != 0) {
|
||||
/* the mandatory part differs */
|
||||
return false;
|
||||
}
|
||||
|
@ -90,20 +88,47 @@ static bool uri_matches(const char *template, const char *uri, const unsigned in
|
|||
}
|
||||
}
|
||||
|
||||
static int httpd_find_uri_handler(struct httpd_data *hd,
|
||||
const char* uri,
|
||||
httpd_method_t method)
|
||||
/* Find handler with matching URI and method, and set
|
||||
* appropriate error code if URI or method not found */
|
||||
static httpd_uri_t* httpd_find_uri_handler(struct httpd_data *hd,
|
||||
const char *uri, size_t uri_len,
|
||||
httpd_method_t method,
|
||||
httpd_err_resp_t *err)
|
||||
{
|
||||
if (err) {
|
||||
*err = HTTPD_404_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (int i = 0; i < hd->config.max_uri_handlers; i++) {
|
||||
if (hd->hd_calls[i]) {
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] = %s"), i, hd->hd_calls[i]->uri);
|
||||
if ((hd->hd_calls[i]->method == method) && // First match methods
|
||||
uri_matches(hd->hd_calls[i]->uri, uri, strlen(uri))) { // Then match uri strings
|
||||
return i;
|
||||
if (!hd->hd_calls[i]) {
|
||||
break;
|
||||
}
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] = %s"), i, hd->hd_calls[i]->uri);
|
||||
|
||||
/* Check if custom URI matching function is set,
|
||||
* else use simple string compare */
|
||||
if (hd->config.uri_match_fn ?
|
||||
hd->config.uri_match_fn(hd->hd_calls[i]->uri, uri, uri_len) :
|
||||
httpd_uri_match_simple(hd->hd_calls[i]->uri, uri, uri_len)) {
|
||||
/* URIs match. Now check if method is supported */
|
||||
if (hd->hd_calls[i]->method == method) {
|
||||
/* Match found! */
|
||||
if (err) {
|
||||
/* Unset any error that may
|
||||
* have been set earlier */
|
||||
*err = 0;
|
||||
}
|
||||
return hd->hd_calls[i];
|
||||
}
|
||||
/* URI found but method not allowed.
|
||||
* If URI is found later then this
|
||||
* error must be set to 0 */
|
||||
if (err) {
|
||||
*err = HTTPD_405_METHOD_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t httpd_register_uri_handler(httpd_handle_t handle,
|
||||
|
@ -115,11 +140,13 @@ esp_err_t httpd_register_uri_handler(httpd_handle_t handle,
|
|||
|
||||
struct httpd_data *hd = (struct httpd_data *) handle;
|
||||
|
||||
/* Make sure another handler with same URI and method
|
||||
* is not already registered
|
||||
*/
|
||||
/* Make sure another handler with matching URI and method
|
||||
* is not already registered. This will also catch cases
|
||||
* when a registered URI wildcard pattern already accounts
|
||||
* for the new URI being registered */
|
||||
if (httpd_find_uri_handler(handle, uri_handler->uri,
|
||||
uri_handler->method) != -1) {
|
||||
strlen(uri_handler->uri),
|
||||
uri_handler->method, NULL) != NULL) {
|
||||
ESP_LOGW(TAG, LOG_FMT("handler %s with method %d already registered"),
|
||||
uri_handler->uri, uri_handler->method);
|
||||
return ESP_ERR_HTTPD_HANDLER_EXISTS;
|
||||
|
@ -162,15 +189,30 @@ esp_err_t httpd_unregister_uri_handler(httpd_handle_t handle,
|
|||
}
|
||||
|
||||
struct httpd_data *hd = (struct httpd_data *) handle;
|
||||
int i = httpd_find_uri_handler(hd, uri, method);
|
||||
for (int i = 0; i < hd->config.max_uri_handlers; i++) {
|
||||
if (!hd->hd_calls[i]) {
|
||||
break;
|
||||
}
|
||||
if ((hd->hd_calls[i]->method == method) && // First match methods
|
||||
(strcmp(hd->hd_calls[i]->uri, uri) == 0)) { // Then match URI string
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] removing %s"), i, hd->hd_calls[i]->uri);
|
||||
|
||||
if (i != -1) {
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] removing %s"), i, hd->hd_calls[i]->uri);
|
||||
free((char*)hd->hd_calls[i]->uri);
|
||||
free(hd->hd_calls[i]);
|
||||
hd->hd_calls[i] = NULL;
|
||||
|
||||
free((char*)hd->hd_calls[i]->uri);
|
||||
free(hd->hd_calls[i]);
|
||||
hd->hd_calls[i] = NULL;
|
||||
return ESP_OK;
|
||||
/* Shift the remaining non null handlers in the array
|
||||
* forward by 1 so that order of insertion is maintained */
|
||||
for (i += 1; i < hd->config.max_uri_handlers; i++) {
|
||||
if (!hd->hd_calls[i]) {
|
||||
break;
|
||||
}
|
||||
hd->hd_calls[i-1] = hd->hd_calls[i];
|
||||
}
|
||||
/* Nullify the following non null entry */
|
||||
hd->hd_calls[i-1] = NULL;
|
||||
return ESP_OK;
|
||||
}
|
||||
}
|
||||
ESP_LOGW(TAG, LOG_FMT("handler %s with method %d not found"), uri, method);
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
|
@ -185,17 +227,31 @@ esp_err_t httpd_unregister_uri(httpd_handle_t handle, const char *uri)
|
|||
struct httpd_data *hd = (struct httpd_data *) handle;
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < hd->config.max_uri_handlers; i++) {
|
||||
if ((hd->hd_calls[i] != NULL) &&
|
||||
(strcmp(hd->hd_calls[i]->uri, uri) == 0)) {
|
||||
int i = 0, j = 0; // For keeping count of removed entries
|
||||
for (; i < hd->config.max_uri_handlers; i++) {
|
||||
if (!hd->hd_calls[i]) {
|
||||
break;
|
||||
}
|
||||
if (strcmp(hd->hd_calls[i]->uri, uri) == 0) { // Match URI strings
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] removing %s"), i, uri);
|
||||
|
||||
free((char*)hd->hd_calls[i]->uri);
|
||||
free(hd->hd_calls[i]);
|
||||
hd->hd_calls[i] = NULL;
|
||||
found = true;
|
||||
|
||||
j++; // Update count of removed entries
|
||||
} else {
|
||||
/* Shift the remaining non null handlers in the array
|
||||
* forward by j so that order of insertion is maintained */
|
||||
hd->hd_calls[i-j] = hd->hd_calls[i];
|
||||
}
|
||||
}
|
||||
/* Nullify the following non null entries */
|
||||
for (int k = (i - j); k < i; k++) {
|
||||
hd->hd_calls[k] = NULL;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ESP_LOGW(TAG, LOG_FMT("no handler found for URI %s"), uri);
|
||||
}
|
||||
|
@ -205,44 +261,15 @@ esp_err_t httpd_unregister_uri(httpd_handle_t handle, const char *uri)
|
|||
void httpd_unregister_all_uri_handlers(struct httpd_data *hd)
|
||||
{
|
||||
for (unsigned i = 0; i < hd->config.max_uri_handlers; i++) {
|
||||
if (hd->hd_calls[i]) {
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] removing %s"), i, hd->hd_calls[i]->uri);
|
||||
|
||||
free((char*)hd->hd_calls[i]->uri);
|
||||
free(hd->hd_calls[i]);
|
||||
if (!hd->hd_calls[i]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] removing %s"), i, hd->hd_calls[i]->uri);
|
||||
|
||||
/* Alternate implmentation of httpd_find_uri_handler()
|
||||
* which takes a uri_len field. This is useful when the URI
|
||||
* string contains extra parameters that are not to be included
|
||||
* while matching with the registered URI_handler strings
|
||||
*/
|
||||
static httpd_uri_t* httpd_find_uri_handler2(httpd_err_resp_t *err,
|
||||
struct httpd_data *hd,
|
||||
const char *uri, size_t uri_len,
|
||||
httpd_method_t method)
|
||||
{
|
||||
*err = 0;
|
||||
for (int i = 0; i < hd->config.max_uri_handlers; i++) {
|
||||
if (hd->hd_calls[i]) {
|
||||
ESP_LOGD(TAG, LOG_FMT("[%d] = %s"), i, hd->hd_calls[i]->uri);
|
||||
if (uri_matches(hd->hd_calls[i]->uri, uri, uri_len)) {
|
||||
if (hd->hd_calls[i]->method == method) { // Match methods
|
||||
return hd->hd_calls[i];
|
||||
}
|
||||
/* URI found but method not allowed.
|
||||
* If URI IS found later then this
|
||||
* error is to be neglected */
|
||||
*err = HTTPD_405_METHOD_NOT_ALLOWED;
|
||||
}
|
||||
}
|
||||
free((char*)hd->hd_calls[i]->uri);
|
||||
free(hd->hd_calls[i]);
|
||||
hd->hd_calls[i] = NULL;
|
||||
}
|
||||
if (*err == 0) {
|
||||
*err = HTTPD_404_NOT_FOUND;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
esp_err_t httpd_uri(struct httpd_data *hd)
|
||||
|
@ -255,12 +282,11 @@ esp_err_t httpd_uri(struct httpd_data *hd)
|
|||
httpd_err_resp_t err = 0;
|
||||
|
||||
ESP_LOGD(TAG, LOG_FMT("request for %s with type %d"), req->uri, req->method);
|
||||
|
||||
/* URL parser result contains offset and length of path string */
|
||||
if (res->field_set & (1 << UF_PATH)) {
|
||||
uri = httpd_find_uri_handler2(&err, hd,
|
||||
req->uri + res->field_data[UF_PATH].off,
|
||||
res->field_data[UF_PATH].len,
|
||||
req->method);
|
||||
uri = httpd_find_uri_handler(hd, req->uri + res->field_data[UF_PATH].off,
|
||||
res->field_data[UF_PATH].len, req->method, &err);
|
||||
}
|
||||
|
||||
/* If URI with method not found, respond with error code */
|
||||
|
@ -270,7 +296,8 @@ esp_err_t httpd_uri(struct httpd_data *hd)
|
|||
ESP_LOGW(TAG, LOG_FMT("URI '%s' not found"), req->uri);
|
||||
return httpd_resp_send_err(req, HTTPD_404_NOT_FOUND);
|
||||
case HTTPD_405_METHOD_NOT_ALLOWED:
|
||||
ESP_LOGW(TAG, LOG_FMT("Method '%d' not allowed for URI '%s'"), req->method, req->uri);
|
||||
ESP_LOGW(TAG, LOG_FMT("Method '%d' not allowed for URI '%s'"),
|
||||
req->method, req->uri);
|
||||
return httpd_resp_send_err(req, HTTPD_405_METHOD_NOT_ALLOWED);
|
||||
default:
|
||||
return ESP_FAIL;
|
||||
|
|
Loading…
Reference in a new issue