mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-09-02 15:02:51 +08:00
httpd: split the upload fragment handlers out of handle_post()
The tail of handle_post() interleaved the config and firmware upload paths behind one config_upload conditional. Give each path its own function, handle_config_fragment() and handle_firmware_fragment(), and reduce handle_post() to routing. Both handlers keep their own copy of the buffer-and-bounds-check prologue: with SDCC a shared helper costs 2 bytes of direct RAM for the fragment pointer (a spill slot when the parameter lives in xdata, a DSEG home when it does not), and direct RAM is fully allocated. The memory layout is unchanged from the pre-split code.
This commit is contained in:
+76
-60
@@ -503,12 +503,83 @@ uint8_t stream_upload(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_config_fragment(__xdata uint8_t *p)
|
||||||
|
{
|
||||||
|
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
||||||
|
__xdata uint16_t frag_len;
|
||||||
|
uint8_t taken;
|
||||||
|
|
||||||
|
frag_len = uip_len - (p - uip_appdata);
|
||||||
|
if (pre_acc + frag_len >= CONFIG_UPLOAD_BUF) {
|
||||||
|
print_string("Configuration too large, aborting.\n");
|
||||||
|
config_upload = 0;
|
||||||
|
s->tstate = TSTATE_NONE;
|
||||||
|
send_bad_request();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(config_buf + pre_acc, p, frag_len);
|
||||||
|
pre_acc += frag_len;
|
||||||
|
taken = config_take();
|
||||||
|
if (!taken) {
|
||||||
|
s->tstate = TSTATE_MULTIPART;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
config_upload = 0;
|
||||||
|
s->tstate = TSTATE_NONE;
|
||||||
|
if (taken == 2) {
|
||||||
|
send_bad_request();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_firmware_fragment(__xdata uint8_t *p)
|
||||||
|
{
|
||||||
|
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
||||||
|
__xdata uint16_t frag_len, payload_start;
|
||||||
|
|
||||||
|
frag_len = uip_len - (p - uip_appdata);
|
||||||
|
if (pre_acc + frag_len >= CONFIG_UPLOAD_BUF) {
|
||||||
|
print_string("Firmware upload header too large, aborting.\n");
|
||||||
|
config_upload = 0;
|
||||||
|
s->tstate = TSTATE_NONE;
|
||||||
|
send_bad_request();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(config_buf + pre_acc, p, frag_len);
|
||||||
|
pre_acc += frag_len;
|
||||||
|
payload_start = preamble_payload_start(pre_acc);
|
||||||
|
if (!payload_start) {
|
||||||
|
s->tstate = TSTATE_MULTIPART;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dbg_string("Have content octets\n");
|
||||||
|
|
||||||
|
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing fails
|
||||||
|
set_sys_led_state(SYS_LED_FAST);
|
||||||
|
|
||||||
|
crc_value = 0;
|
||||||
|
bindex = 0;
|
||||||
|
write_len = 0;
|
||||||
|
// A verdict is only built once the upload part completes;
|
||||||
|
// clear any stale response so the completion check in the
|
||||||
|
// appcall POST branch cannot send leftovers
|
||||||
|
slen = 0;
|
||||||
|
upload_settings.p = config_buf;
|
||||||
|
upload_settings.bptr = payload_start;
|
||||||
|
upload_settings.plen = pre_acc;
|
||||||
|
stream_upload();
|
||||||
|
|
||||||
|
dbg_string("Done reading first fragment\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void handle_post(void)
|
void handle_post(void)
|
||||||
{
|
{
|
||||||
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
__xdata struct httpd_state * __xdata s = &(uip_conn->appstate);
|
||||||
__xdata uint8_t *p = uip_appdata;
|
__xdata uint8_t *p = uip_appdata;
|
||||||
__xdata uint8_t *request_path = p + 6;
|
__xdata uint8_t *request_path = p + 6;
|
||||||
__xdata uint16_t frag_len, payload_start;
|
|
||||||
|
|
||||||
// Was the multipart header sent in multiple packets?
|
// Was the multipart header sent in multiple packets?
|
||||||
if (s->tstate != TSTATE_MULTIPART) {
|
if (s->tstate != TSTATE_MULTIPART) {
|
||||||
@@ -603,66 +674,11 @@ void handle_post(void)
|
|||||||
send_bad_request();
|
send_bad_request();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (config_upload) {
|
if (config_upload)
|
||||||
frag_len = uip_len - (p - uip_appdata);
|
handle_config_fragment(p);
|
||||||
if (pre_acc + frag_len >= CONFIG_UPLOAD_BUF) {
|
else
|
||||||
print_string("Configuration too large, aborting.\n");
|
handle_firmware_fragment(p);
|
||||||
config_upload = 0;
|
|
||||||
s->tstate = TSTATE_NONE;
|
|
||||||
send_bad_request();
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
memcpy(config_buf + pre_acc, p, frag_len);
|
|
||||||
pre_acc += frag_len;
|
|
||||||
uint8_t taken = config_take();
|
|
||||||
|
|
||||||
if (!taken) {
|
|
||||||
s->tstate = TSTATE_MULTIPART;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
config_upload = 0;
|
|
||||||
s->tstate = TSTATE_NONE;
|
|
||||||
if (taken == 2) {
|
|
||||||
send_bad_request();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
slen = strtox(outbuf, "HTTP/1.1 200 OK\r\nConnection: close\r\n\r\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
frag_len = uip_len - (p - uip_appdata);
|
|
||||||
if (pre_acc + frag_len >= CONFIG_UPLOAD_BUF) {
|
|
||||||
print_string("Firmware upload header too large, aborting.\n");
|
|
||||||
s->tstate = TSTATE_NONE;
|
|
||||||
send_bad_request();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(config_buf + pre_acc, p, frag_len);
|
|
||||||
pre_acc += frag_len;
|
|
||||||
payload_start = preamble_payload_start(pre_acc);
|
|
||||||
if (!payload_start) {
|
|
||||||
s->tstate = TSTATE_MULTIPART;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dbg_string("Have content octets\n");
|
|
||||||
|
|
||||||
flash_init(0); // Re-initialize flash for non-DIO operation, otherwise flashing fails
|
|
||||||
set_sys_led_state(SYS_LED_FAST);
|
|
||||||
|
|
||||||
crc_value = 0;
|
|
||||||
bindex = 0;
|
|
||||||
write_len = 0;
|
|
||||||
// A verdict is only built once the upload part completes;
|
|
||||||
// clear any stale response so the completion check in the
|
|
||||||
// appcall POST branch cannot send leftovers
|
|
||||||
slen = 0;
|
|
||||||
upload_settings.p = config_buf;
|
|
||||||
upload_settings.bptr = payload_start;
|
|
||||||
upload_settings.plen = pre_acc;
|
|
||||||
stream_upload();
|
|
||||||
|
|
||||||
dbg_string("Done reading first fragment\n");
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
send_not_found();
|
send_not_found();
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user