hotfix: decode chunked transfer encoding in proxy LLM path

The proxy path (llm_http_via_proxy) stripped HTTP headers but did not
decode chunked transfer-encoding, leaving hex size prefixes in the body
and causing cJSON_Parse to fail with 0 bytes text.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
crispyberry
2026-02-28 09:48:15 +08:00
parent 1ccaa09d57
commit f1571118f0

View File

@@ -121,6 +121,54 @@ static void resp_buf_free(resp_buf_t *rb)
rb->cap = 0; rb->cap = 0;
} }
/* ── Chunked transfer encoding decoder ───────────────────────── */
static void resp_buf_decode_chunked(resp_buf_t *rb)
{
if (!rb->data || rb->len == 0) return;
/* Quick check: if body starts with '{' or '[', it's not chunked */
size_t i = 0;
while (i < rb->len && (rb->data[i] == ' ' || rb->data[i] == '\t')) i++;
if (i < rb->len && (rb->data[i] == '{' || rb->data[i] == '[')) return;
/* Try to decode chunked encoding in-place */
char *src = rb->data;
char *dst = rb->data;
char *end = rb->data + rb->len;
while (src < end) {
/* Parse hex chunk size */
char *line_end = strstr(src, "\r\n");
if (!line_end) break;
unsigned long chunk_size = strtoul(src, NULL, 16);
if (chunk_size == 0) break; /* terminal chunk */
src = line_end + 2; /* skip past \r\n after size */
if (src + chunk_size > end) {
/* Incomplete chunk, copy what we have */
size_t avail = end - src;
memmove(dst, src, avail);
dst += avail;
break;
}
memmove(dst, src, chunk_size);
dst += chunk_size;
src += chunk_size;
/* Skip trailing \r\n after chunk data */
if (src + 2 <= end && src[0] == '\r' && src[1] == '\n') {
src += 2;
}
}
rb->len = dst - rb->data;
rb->data[rb->len] = '\0';
}
/* ── HTTP event handler (for esp_http_client direct path) ─────── */ /* ── HTTP event handler (for esp_http_client direct path) ─────── */
static esp_err_t http_event_handler(esp_http_client_event_t *evt) static esp_err_t http_event_handler(esp_http_client_event_t *evt)
@@ -298,6 +346,9 @@ static esp_err_t llm_http_via_proxy(const char *post_data, resp_buf_t *rb, int *
rb->data[rb->len] = '\0'; rb->data[rb->len] = '\0';
} }
/* Decode chunked transfer encoding if present */
resp_buf_decode_chunked(rb);
return ESP_OK; return ESP_OK;
} }