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:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user