httpd: keep a continued upload away from the cmd and login handlers

handle_post() takes the request path from byte 6 of the segment it is
given. For the first segment of a POST that is the path, but for a later
segment of a multipart upload it is whatever part of the file happens to
sit there. The cmd and login handlers were matched before the multipart
state was checked, so a segment of a config or firmware upload with
"cmd " at that offset ran the rest of the segment as CLI commands, and
one with "login " there aborted the upload with 400.

Check for an upload in progress, and for new upload and config requests,
before looking at cmd and login. A new POST cannot match both sets of
words, so nothing changes for requests that are not uploads.
This commit is contained in:
d00f committed 2026-09-15 09:57:49 +02:00
1 parent 2f005d2993
commit 18b28edcbb
1 file changed
+17 -17
+17 -17
View File
@@ -777,7 +777,23 @@ void handle_post(void)
dbg_string("Multipart request\n"); dbg_string("Multipart request\n");
} }
if (is_word(request_path, "cmd")) { if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
dbg_string("POST upload/config request\n");
if (!authenticated) {
send_unauthorized();
return;
}
if (!boundary[0]) {
dbg_string("Bad request, no boundary!\n");
send_bad_request();
return;
}
if (config_upload)
handle_config_fragment(p);
else
handle_firmware_fragment(p);
return;
} else if (is_word(request_path, "cmd")) {
p += 4; p += 4;
if (!authenticated) { if (!authenticated) {
send_unauthorized(); send_unauthorized();
@@ -803,22 +819,6 @@ void handle_post(void)
return; return;
run_login_body(p); run_login_body(p);
return; return;
} else if (s->tstate == TSTATE_MULTIPART || is_word(request_path, "upload") || is_word(request_path, "config")) {
dbg_string("POST upload/config request\n");
if (!authenticated) {
send_unauthorized();
return;
}
if (!boundary[0]) {
dbg_string("Bad request, no boundary!\n");
send_bad_request();
return;
}
if (config_upload)
handle_config_fragment(p);
else
handle_firmware_fragment(p);
return;
} else { } else {
send_not_found(); send_not_found();
return; return;