You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32基于mbedTLS向Firebase发PUT请求返回400,JSON构造求助

问题:STM32+mbedTLS向Firebase Database发送PUT请求返回400错误

环境与现状

  • 基于STM32,结合mbedTLS、LwIP和FreeRTOS实现Firebase Database安全HTTP客户端,用于远程读写传感器数据
  • SSL连接正常,GET请求能成功获取数据,但PUT请求返回400 Bad Request,服务器提示No data supplied

GET请求正常示例

. Verifying peer X.509 certificate... ok

Write to server: 169 bytes written

GET /Command/TV1.json?auth=[DATABASE SECRET] HTTP/1.1
Host: ecu.firebaseio.com
Content-lenght: 0
Connection: Close

< Read from server: 303 bytes read

HTTP/1.1 200 OK
Server: nginx
Date: Mon, 23 Sep 2024 06:39:28 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 16
Connection: close
Access-Control-Allow-Origin: *
Cache-Control: no-cache
Strict-Transport-Security: max-age=31556926; includeSubDomains; preload

{"Status":"OFF"}

GET请求代码:

strcpy(path, "/LAB/Temperatures.json?auth=[Database Secret]");
len = sprintf((char*) buf, "GET %s HTTP/1.1\r\n"
                        "Host: %s\r\n"
                        "Content-lenght: 0\r\n"
                        "Connection: Close\r\n\r\n", path, SERVER_NAME);

while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
{
 if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
    {
    mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
    goto exit;
    }
}

PUT请求错误示例

. Setting up the SSL/TLS structure... ok

. Connecting to ecu.firebaseio.com at port: 443 ... ok

. Performing the SSL/TLS handshake... ok

. Verifying peer X.509 certificate... ok

return (<Write to server: 272 bytes written

PUT /LAB/Temperatures.json?auth=[DATABASE SECRET] HTTP/1.1
Host: ecu.firebaseio.com
Content-Type: application/json
Content-Lenght: 75

{"Enclosure Temperatures" : "23.15", "MCU Temperatures" : "29.00"}

< Read from server: 337 bytes read

HTTP/1.1 400 Bad Request
Server: nginx
Date: Mon, 23 Sep 2024 06:39:12 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 36
Connection: keep-alive
Access-Control-Allow-Origin: *
Cache-Control: no-cache
Strict-Transport-Security: max-age=31556926; includeSubDomains; preload

{
   "error" : "No data supplied."
}
368 bytes read

HTTP/1.1 400 Bad Request
Server: nginx
Date: Mon, 23 Sep 2024 06:39:12 GMT
Content-Type: text/html
Content-Length: 150
Connection: close
Strict-Transport-Security: max-age=31556926; includeSubDomains; preload

<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
../Middlewares/Third_Party/mbedTLS/source/ssl_msg.c:4681: mbedtls_ssl_fetch_input() returned -29312 (-0x7280)
../Middlewares/Third_Party/mbedTLS/source/ssl_msg.c:4046: ssl_get_next_record() returned -29312 (-0x7280)

EOF
)

PUT请求代码:

sprintf(stringToProcess,"{\"Enclosure Temperatures\" : \"%.2f\", \"MCU Temperatures\" : \"%.2f\"}", enclosure_temp, mcu_temp);
strcpy(path, "/LAB/Temperatures.json?auth=[Database Secret]");

len = snprintf((char*) buf, sizeof(buf) -1,  "PUT %s HTTP/1.1\r\n"
                                                    "Host: %s\r\n"
                                                    "Content-Type: application/json\r\n"
                                                    "Content-Lenght: %d\r\n"
                                                    "\r\n"
                                                    "%s\r\n", path, SERVER_NAME, strlen(stringToProcess), stringToProcess);

while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
{
 if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
    {
    mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
    goto exit;
    }
}

问题根源与修复方案

1. HTTP头拼写错误

代码中Content-lenght是拼写错误,正确应为Content-Length(大写L,末尾为th而非ht)。这个错误会导致服务器无法识别请求体长度,进而判定无数据传入。

2. 请求体末尾多余换行符

PUT请求构造时,JSON后额外添加的\r\n会被计入请求体长度,但Content-Length计算的是JSON本身的长度,导致长度不匹配。需去掉该多余换行。

修复后的PUT请求代码

sprintf(stringToProcess,"{\"Enclosure Temperatures\" : \"%.2f\", \"MCU Temperatures\" : \"%.2f\"}", enclosure_temp, mcu_temp);
strcpy(path, "/LAB/Temperatures.json?auth=[Database Secret]");

// 修复Content-Length拼写,移除JSON末尾的\r\n
len = snprintf((char*) buf, sizeof(buf) -1,  "PUT %s HTTP/1.1\r\n"
                                                    "Host: %s\r\n"
                                                    "Content-Type: application/json\r\n"
                                                    "Content-Length: %d\r\n"
                                                    "\r\n"
                                                    "%s", path, SERVER_NAME, strlen(stringToProcess), stringToProcess);

while((ret = mbedtls_ssl_write(&ssl, buf, len)) <= 0)
{
 if(ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)
    {
    mbedtls_printf(" failed\n  ! mbedtls_ssl_write returned %d\n\n", ret);
    goto exit;
    }
}

额外验证建议

  • 打印构造后的buf内容,与Python请求的原始数据包对比,确保HTTP头和请求体完全一致
  • 确认strlen(stringToProcess)计算的长度准确,无额外空白字符

内容的提问来源于stack exchange,提问作者l.g.oasis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 18:35:53