From 6ffd43bcc98a1df9bcd0d5bb3005fe3549235bb2 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Mon, 24 Feb 2025 18:01:22 +0100 Subject: [PATCH] We should not send any content for HTTP codes 1xx, 204 and 304 Signed-off-by: DL6ER --- src/api/auth.c | 2 +- src/api/config.c | 16 ++++++++++++++-- src/api/info.c | 13 +++---------- src/webserver/http-common.c | 25 ++++++++++++++++++++++--- src/webserver/json_macros.h | 8 ++++++-- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/src/api/auth.c b/src/api/auth.c index 62165439f..468fd12e3 100644 --- a/src/api/auth.c +++ b/src/api/auth.c @@ -401,7 +401,7 @@ static int send_api_auth_status(struct ftl_conn *api, const int user_id, const t const int code = delete_session(user_id) ? 204 : 404; // Send empty reply with appropriate HTTP status code - send_http_code(api, "application/json; charset=utf-8", code, ""); + send_http_code(api, NULL, code, ""); return code; } else diff --git a/src/api/config.c b/src/api/config.c index 1fc1e08cb..cdcaba4b3 100644 --- a/src/api/config.c +++ b/src/api/config.c @@ -1008,6 +1008,7 @@ static int api_config_put_delete(struct ftl_conn *api) if(!new_item->c(&new_item->v, new_item->k, errbuf)) { free_config(&newconf); + free_config_path(requested_path); return send_json_error(api, 400, "bad_request", "Invalid value", @@ -1032,6 +1033,7 @@ static int api_config_put_delete(struct ftl_conn *api) // Error 404 if config element not found if(!found) { + free_config(&newconf); cJSON *json = JSON_NEW_OBJECT(); JSON_SEND_OBJECT_CODE(json, 404); } @@ -1039,6 +1041,7 @@ static int api_config_put_delete(struct ftl_conn *api) // Error 400 if unique item already present if(message != NULL) { + free_config(&newconf); return send_json_error(api, 400, "bad_request", message, @@ -1081,8 +1084,17 @@ static int api_config_put_delete(struct ftl_conn *api) // Send empty reply with matching HTTP status code // 201 - Created or 204 - No content - cJSON *json = JSON_NEW_OBJECT(); - JSON_SEND_OBJECT_CODE(json, api->method == HTTP_PUT ? 201 : 204); + if(api->method == HTTP_PUT) + { + cJSON *json = JSON_NEW_OBJECT(); + JSON_SEND_OBJECT_CODE(json, 201); + } + else + { + // 204 - No content + send_http_code(api, NULL, 204, ""); + return 204; + } } // Endpoint /api/config router diff --git a/src/api/info.c b/src/api/info.c index 693f14397..9a690d313 100644 --- a/src/api/info.c +++ b/src/api/info.c @@ -974,16 +974,9 @@ static int api_info_messages_DELETE(struct ftl_conn *api) char *endptr = NULL; long int idval = strtol(token, &endptr, 10); if(errno != 0 || endptr == token || *endptr != '\0' || idval < 0) - { - // Send error reply - free(id); - return send_json_error(api, 400, // 400 Bad Request - "uri_error", - "Invalid ID in path", - api->action_path); - } - - cJSON_AddNumberToObject(ids, "id", idval); + log_warn("API: URI error - skipping invalid ID in path (%s): %s", api->action_path, token); + else + cJSON_AddNumberToArray(ids, idval); // Get next token token = strtok_r(NULL, ",", &saveptr); diff --git a/src/webserver/http-common.c b/src/webserver/http-common.c index 75e687ba4..8c427b73b 100644 --- a/src/webserver/http-common.c +++ b/src/webserver/http-common.c @@ -63,6 +63,10 @@ int send_http_code(struct ftl_conn *api, const char *mime_type, mime_type, strlen(msg)); + // Codes 1xx, 204 and 304 are not allowed to have a body + if(code < 200 || code == 204 || code == 304) + return 0; + return mg_write(api->conn, msg, strlen(msg)); } @@ -88,18 +92,33 @@ int send_json_error_free(struct ftl_conn *api, const int code, const char *key, const char* message, char *hint, const bool free_hint, const bool log) { + // Codes 1xx, 204, and 304 are not allowed to have a body + // Log to the logfile instead + if(code < 200 || code == 204 || code == 304) + { + if(hint != NULL) + log_warn("API: %s (key: %s, hint: %s)", message, key, hint); + else + log_warn("API: %s (key: %s)", message, key); + + return send_http_code(api, NULL, code, ""); + } + if(log) { if(hint != NULL) - log_warn("API: %s (%s)", message, hint); + log_warn("API: %s (key: %s, hint: %s)", message, key, hint); else - log_warn("API: %s", message); + log_warn("API: %s (key: %s)", message, key); } cJSON *error = JSON_NEW_OBJECT(); JSON_REF_STR_IN_OBJECT(error, "key", key); JSON_REF_STR_IN_OBJECT(error, "message", message); - JSON_COPY_STR_TO_OBJECT(error, "hint", hint); + if(hint != NULL) + JSON_COPY_STR_TO_OBJECT(error, "hint", hint); + else + JSON_ADD_NULL_TO_OBJECT(error, "hint"); if(free_hint && hint != NULL) free(hint); diff --git a/src/webserver/json_macros.h b/src/webserver/json_macros.h index 6c12c6509..c6eb6184e 100644 --- a/src/webserver/json_macros.h +++ b/src/webserver/json_macros.h @@ -223,10 +223,14 @@ }) #define JSON_SEND_OBJECT_CODE(object, code)({ \ - if((code) != 204) \ + if((code) < 100 || (code) == 204 || (code) == 304) \ { \ - cJSON_AddNumberToObject(object, "took", double_time() - api->now); \ + /* HTTP codes 1xx, 204 and 304 must not have a body */ \ + send_http_code(api, NULL, code, ""); \ + cJSON_Delete(object); \ + return code; \ } \ + cJSON_AddNumberToObject(object, "took", double_time() - api->now); \ char *json_string = json_formatter(object); \ if(json_string == NULL) \ { \