Parcourir la source

fix: 修复设置写入 Empty request body 错误 - mongoose body 解析 fallback

Coze-Commit-Type: user
Coze-User-ID: 256649704250362
Coze-Conversation-ID: 11640025
steven_roc il y a 2 mois
Parent
commit
cf14a8e182

+ 10 - 0
mppt_monitor/CHANGELOG.md

@@ -6,6 +6,16 @@
 
 ## [2.1.1] - 2026-08-06
 
+### Bug 修复:设置写入 JSON 解析失败
+
+**问题**: POST `/api/settings` 返回 "Empty request body" 错误
+
+**根因**: mongoose 7.22 的 `hm->body` 字段在某些情况下为空,需要手动从原始消息中提取 body
+
+**修复**:
+1. 添加 fallback 机制:当 `hm->body.buf` 为空时,从 `hm->message` 原始数据中查找 `\r\n\r\n` 分隔符提取 body
+2. 添加详细的 body 解析日志
+
 ### Bug 修复:设置写入 param 字段乱码 (Use-After-Free)
 
 #### 问题

BIN
mppt_monitor/build/mppt_monitor


BIN
mppt_monitor/mppt_data.db


+ 29 - 9
mppt_monitor/src/web_server.c

@@ -145,20 +145,40 @@ static void handle_api_settings(struct mg_connection *c, struct mg_http_message
         return;
     }
 
-    /* Parse JSON body */
-    if (!hm->body.buf || hm->body.len == 0) {
+    /* Parse JSON body - try body field first, then fall back to raw message */
+    char body_buf[2048];
+    size_t body_len = 0;
+
+    if (hm->body.buf && hm->body.len > 0) {
+        body_len = (hm->body.len < sizeof(body_buf) - 1) ? hm->body.len : sizeof(body_buf) - 1;
+        memcpy(body_buf, hm->body.buf, body_len);
+        body_buf[body_len] = '\0';
+    } else {
+        /* Fallback: extract body from raw message after headers */
+        /* Find the end of headers (double CRLF) */
+        const char *raw = hm->message.buf;
+        size_t raw_len = hm->message.len;
+        const char *body_start = strstr(raw, "\r\n\r\n");
+        if (body_start) {
+            body_start += 4; /* Skip \r\n\r\n */
+            body_len = raw_len - (body_start - raw);
+            if (body_len > 0 && body_len < sizeof(body_buf)) {
+                memcpy(body_buf, body_start, body_len);
+                body_buf[body_len] = '\0';
+            } else {
+                body_len = 0;
+            }
+        }
+    }
+
+    printf("[WEB] Settings POST body (%zu bytes): %s\n", body_len, body_len > 0 ? body_buf : "(empty)");
+
+    if (body_len == 0) {
         mg_http_reply(c, 400, "Content-Type: application/json\r\nAccess-Control-Allow-Origin: *\r\n",
                       "{\"error\":\"Empty request body\"}");
         return;
     }
 
-    char body_buf[2048];
-    size_t body_len = (hm->body.len < sizeof(body_buf) - 1) ? hm->body.len : sizeof(body_buf) - 1;
-    memcpy(body_buf, hm->body.buf, body_len);
-    body_buf[body_len] = '\0';
-
-    printf("[WEB] Settings POST body (%zu bytes): %s\n", body_len, body_buf);
-
     cJSON *req = cJSON_Parse(body_buf);
     if (!req) {
         printf("[WEB] Settings JSON parse failed for body: %s\n", body_buf);