fix: Gesamt-Timeout für HTTP-Anfragen
I2: SO_RCVTIMEO=5s war ein Timeout pro recv(), nicht für die gesamte Anfrage. Ein Client, der 1 Byte alle 4,9 s schickt, konnte den einzigen HTTP-Server-Task damit stundenlang belegen (Spec §7.2 will 5 s pro Header). serve() rechnet jetzt eine absolute Deadline (nl_app_now_ms() + 5000 ms) und setzt SO_RCVTIMEO vor jedem recv() auf die verbleibende Zeit (mindestens 1 ms); ist die Deadline überschritten, wird die Verbindung sofort verworfen. Nicht host-testbar (nl_http_server.c bindet SDK-Sockets ein); über den Firmware-Build verifiziert.
This commit is contained in:
@@ -33,19 +33,35 @@ static void simple_error(int status, const char *msg)
|
||||
strcpy(s_resp.body, msg);
|
||||
}
|
||||
|
||||
#define NL_HTTP_REQUEST_TIMEOUT_MS 5000u
|
||||
|
||||
static void serve(int fd)
|
||||
{
|
||||
struct timeval tv;
|
||||
nl_http_request_t req;
|
||||
nl_http_parse_t pr = NL_HTTP_INCOMPLETE;
|
||||
size_t len = 0, out;
|
||||
uint32_t deadline = nl_app_now_ms() + NL_HTTP_REQUEST_TIMEOUT_MS;
|
||||
|
||||
tv.tv_sec = 5;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
|
||||
setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof tv);
|
||||
/* I2: 5 s is a deadline for the whole header+body read, not a per-recv() timeout -
|
||||
* otherwise a client trickling in 1 byte per <5 s occupies the single server task forever. */
|
||||
while (pr == NL_HTTP_INCOMPLETE && len < sizeof s_buf) {
|
||||
int n = recv(fd, s_buf + len, sizeof s_buf - len, 0);
|
||||
uint32_t now = nl_app_now_ms();
|
||||
uint32_t remaining_ms;
|
||||
int n;
|
||||
|
||||
if ((int32_t)(deadline - now) <= 0)
|
||||
return; /* overall deadline passed: drop silently */
|
||||
remaining_ms = deadline - now;
|
||||
tv.tv_sec = remaining_ms / 1000u;
|
||||
tv.tv_usec = (remaining_ms % 1000u) * 1000u;
|
||||
if (tv.tv_sec == 0 && tv.tv_usec == 0)
|
||||
tv.tv_usec = 1000; /* at least 1 ms */
|
||||
setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
|
||||
n = recv(fd, s_buf + len, sizeof s_buf - len, 0);
|
||||
if (n <= 0)
|
||||
return; /* timeout or closed: drop silently */
|
||||
len += (size_t)n;
|
||||
|
||||
Reference in New Issue
Block a user