In httpd_parse.c, cb_headers_complete() converted the HTTP parser's
content_length (uint64_t) to the request's content_len (size_t) via an
unsafe cast through (int). On a 32-bit size_t target a Content-Length
above 4 GiB silently truncated, enabling request smuggling where the
server and an upstream proxy disagree on the body length (CWE-681).
Reject any Content-Length above UINT32_MAX with 413 Content Too Large
before any handler runs. UINT32_MAX is the largest body length the
server can represent in size_t content_len on every target, so this is
the maximum the server can support; no configuration knob is needed.
Closes SEC-102
Closes SEC-229
httpd_req_get_hdr_value_str() detected truncation with `val_size < full_size`, where full_size is the strlcpy() return value. strlcpy() returns strlen() of the source (the terminating null is not counted), so truncation actually occurs when strlen(src) >= val_size. At strlen(src) == val_size the value is copied as val_size - 1 chars + NUL (i.e. truncated) yet ESP_OK was returned, so the caller never learned the value was cut.
Use `val_size <= full_size` and correct the misleading comment about strlcpy()'s return value.
Same truncation-reporting class fixed for httpd_cookie_key_value in PR #16202; httpd_req_get_hdr_value_str was missed. No memory-safety impact: strlcpy() null-terminates if val_size > 0.
httpd_stop() and httpd_req_async_handler_complete() both pushed
messages onto the control mbox via cs_send_to_ctrl_sock() without
reserving a slot in ctrl_sock_semaphore. Once the silent-drop fix
made the semaphore unconditional, the bypass became a real bug:
when the mbox is saturated by pending httpd_queue_work() items the
unguarded sendto() can return ENOBUFS, and even when it succeeds it
leaves the semaphore overstating free slots until the consumer
drains the message — a window during which a concurrent
httpd_queue_work() can take a slot but still find the mbox full.
Acquire the semaphore (portMAX_DELAY) before both sends and give it
back on send failure so the take/give invariant is preserved. The
httpd task is the consumer in both paths, so blocking is bounded
and deadlock-free. Reword the stale "no-op give on full" comment in
httpd_process_ctrl_msg() to reflect that only the recv-error path
relies on the cap behavior now.
PONG frames (opcode 0xA) were never dispatched to the user's WebSocket
handler despite an existing comment stating they should be. The dispatch
condition `ra->ws_type < HTTPD_WS_TYPE_CLOSE` excluded PONG (0xA)
since CLOSE is 0x8.
This caused a critical secondary bug: when the server sends PING frames
and the client responds with PONG, httpd_ws_recv_frame() is never
called for the PONG, leaving the remaining frame bytes (second_byte
plus 4-byte mask_key) unconsumed in the TCP buffer. On the next
WebSocket read, these orphaned bytes are misinterpreted as a new frame
header, causing either "WS frame is not properly masked" errors or
EAGAIN timeouts with garbage length values, effectively destroying
the connection.
Add `ra->ws_type == HTTPD_WS_TYPE_PONG` to the dispatch condition so
PONG frames reach the user handler, which calls httpd_ws_recv_frame()
to properly consume the frame bytes from the socket.
Closes https://github.com/espressif/esp-idf/issues/18227
Make it possible to disable http(s) server events. This improves
performance of the server, as http server creates events on every signle
read or write to the socket.
1. In async requests, if the two or more requests are made on same
socket then it used to block the second request.
2. The main thread is used to block on select call. And there done
no FD_SET for particular fd.
Closes https://github.com/espressif/esp-idf/issues/16998
1. If the user wants authenticate the request, then user needs to do
this before upgrading the protocol to websocket.
2. To achieve this, added pre_handshake_callack, which will execute
before handshake, i.e. before switching protocol.
In httpd_register_uri_handler api, for the strdup function failure case was not
checked and not returned any error by freeing previously allocated memory, if the memory
allocation for strdup function did not gets successful.
Closes https://github.com/espressif/esp-idf/issues/15878
1. In httpd_req_async_handler_begin, the httpd_req_aux is locally malloced
and data is done memcpy to local httpd_req_aux from request'ss httpd_req_aux for
async request use-case, this causes scartch pointer from these two structs
pointing to same memory address.
2. In current workflow, the request's sratch buffer is freed in httpd_parse.c
httpd_req_cleanup api. Therefore if the user try to fetch the data (like headers)
from the scratch buffer, data will be not available.
3. Each request should have the deep copy of the scratch buffer. To retrive
the data later.
Closes https://github.com/espressif/esp-idf/issues/15587
res_buf was not freed for the chunk response type in case of
first_chunk_sent true condition.
This commit ensures that resp_buf is freed and few cosmetic
changes are made