chore(repo): keep only current main snapshot

History squashed to one root commit to permanently drop old branch history and objects.
This commit is contained in:
admin
2026-02-28 16:41:12 +08:00
commit 8df2095acf
89 changed files with 21634 additions and 0 deletions

View File

@@ -0,0 +1,187 @@
#include "rest_server_internal.h"
#include <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "esp_heap_caps.h"
#include "mbedtls/base64.h"
#include "domain.h"
#define REST_SERVER_MAX_BODY_BYTES (4 * 1024 * 1024)
static void *alloc_prefer_psram(size_t size) {
void *ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (ptr == NULL) {
ptr = malloc(size);
}
return ptr;
}
static void *calloc_prefer_psram(size_t n, size_t size) {
void *ptr = heap_caps_calloc(n, size, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
if (ptr == NULL) {
ptr = calloc(n, size);
}
return ptr;
}
bool rest_server_auth_ok(httpd_req_t *req) {
if (strlen(CONFIG_TQ_API_KEY) == 0) {
return true;
}
char buf[96] = {0};
if (httpd_req_get_hdr_value_str(req, "X-API-Key", buf, sizeof(buf)) != ESP_OK) {
return false;
}
return strcmp(buf, CONFIG_TQ_API_KEY) == 0;
}
esp_err_t rest_server_send_json(httpd_req_t *req, const char *status, cJSON *root) {
char *text = cJSON_PrintUnformatted(root);
if (text == NULL) {
return httpd_resp_send_err(req, HTTPD_500_INTERNAL_SERVER_ERROR, "json encode failed");
}
httpd_resp_set_type(req, "application/json");
httpd_resp_set_status(req, status);
esp_err_t err = httpd_resp_sendstr(req, text);
cJSON_free(text);
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_REST_RESPONSES_TOTAL, 1);
return err;
}
esp_err_t rest_server_send_error(httpd_req_t *req, const char *status, const char *message) {
cJSON *root = cJSON_CreateObject();
cJSON_AddBoolToObject(root, "ok", false);
cJSON_AddStringToObject(root, "error", message != NULL ? message : "unknown");
esp_err_t err = rest_server_send_json(req, status, root);
cJSON_Delete(root);
domain_diag_counter_add(DOMAIN_DIAG_COUNTER_REST_ERRORS_TOTAL, 1);
domain_diag_record_error("rest_api", ESP_FAIL, message != NULL ? message : "unknown");
return err;
}
esp_err_t rest_server_read_body(httpd_req_t *req, char **out_body) {
if (out_body == NULL) {
return ESP_ERR_INVALID_ARG;
}
*out_body = NULL;
if (req->content_len <= 0 || req->content_len > REST_SERVER_MAX_BODY_BYTES) {
return ESP_ERR_INVALID_SIZE;
}
char *buf = (char *)calloc_prefer_psram(1, (size_t)req->content_len + 1);
if (buf == NULL) {
return ESP_ERR_NO_MEM;
}
int received = 0;
while (received < req->content_len) {
int ret = httpd_req_recv(req, buf + received, req->content_len - received);
if (ret <= 0) {
free(buf);
return ESP_FAIL;
}
received += ret;
}
*out_body = buf;
return ESP_OK;
}
bool rest_server_parse_uri_u32_tail(const char *uri, uint32_t *out_value) {
if (uri == NULL || out_value == NULL) {
return false;
}
const char *slash = strrchr(uri, '/');
if (slash == NULL || *(slash + 1) == '\0') {
return false;
}
errno = 0;
char *endptr = NULL;
unsigned long val = strtoul(slash + 1, &endptr, 10);
if (errno != 0 || endptr == slash + 1 || *endptr != '\0' || val > UINT32_MAX) {
return false;
}
*out_value = (uint32_t)val;
return true;
}
esp_err_t rest_server_base64_decode_alloc(const char *b64, uint8_t **out_raw, size_t *out_len) {
if (b64 == NULL || out_raw == NULL || out_len == NULL) {
return ESP_ERR_INVALID_ARG;
}
*out_raw = NULL;
*out_len = 0;
size_t decoded_len = 0;
int rc = mbedtls_base64_decode(NULL,
0,
&decoded_len,
(const unsigned char *)b64,
strlen(b64));
if (!(rc == 0 || rc == MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL)) {
return ESP_ERR_INVALID_ARG;
}
uint8_t *buf = (uint8_t *)alloc_prefer_psram(decoded_len);
if (buf == NULL) {
return ESP_ERR_NO_MEM;
}
rc = mbedtls_base64_decode(buf,
decoded_len,
&decoded_len,
(const unsigned char *)b64,
strlen(b64));
if (rc != 0) {
free(buf);
return ESP_ERR_INVALID_ARG;
}
*out_raw = buf;
*out_len = decoded_len;
return ESP_OK;
}
void rest_server_appendf(char *dst, size_t cap, size_t *offset, const char *fmt, ...) {
if (dst == NULL || cap == 0 || offset == NULL || fmt == NULL || *offset >= cap) {
return;
}
va_list ap;
va_start(ap, fmt);
int n = vsnprintf(dst + *offset, cap - *offset, fmt, ap);
va_end(ap);
if (n <= 0) {
return;
}
size_t written = (size_t)n;
if (written >= cap - *offset) {
*offset = cap - 1;
return;
}
*offset += written;
}
bool rest_server_json_bool_with_default(cJSON *item, bool default_value) {
if (item == NULL) {
return default_value;
}
if (cJSON_IsBool(item)) {
return cJSON_IsTrue(item);
}
return default_value;
}