mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
httpd: parse a configuration upload once the whole request has arrived
Saving the configuration works in Chrome and fails in Firefox, and the difference is only how each browser splits the request. The handler erased the config sector as soon as the request started and then parsed the multipart body one TCP segment at a time, which requires every boundary and every part header to fall inside a single segment. Firefox splits inside a part header, so the parser lost its place and the erased sector was left holding a truncated body or nothing at all. A single-burst scripted post lost the whole body the same way. The configuration is limited to two kilobytes, so the whole request body now accumulates in xdata and is parsed only after the closing boundary has arrived. The parts are walked in one pass, the part carrying a filename is written to a freshly erased sector, and the client receives a 200 instead of the previous silent close. No segmentation can confuse this, since the parser only ever sees a complete body. Locating the closing boundary first also bounds the walk over the parts, since none can lie beyond it, so the length of the buffer is no longer the bound and the test for the two trailing dashes is unnecessary. The walk matches at offsets inside a buffer that is not terminated, so neither existing helper fits: strcmp() goes on to compare the byte after the match and is_word_x() demands a separator there. Add strstart() and strstart_x() for that case, and use strlen_x() for the boundary length. The firmware upload path still streams, since a megabyte cannot be buffered, and is untouched.
This commit is contained in:
@@ -164,6 +164,8 @@ uint16_t strlen_x(register __xdata const char *s);
|
||||
uint16_t strtox(register __xdata uint8_t *dst, register __code const char *s);
|
||||
uint16_t strcpy(register __xdata uint8_t *dst, register const char *s);
|
||||
char strcmp(register __xdata const uint8_t *a, register __code const uint8_t *b);
|
||||
bool strstart(__xdata const uint8_t *a, __code const uint8_t *b);
|
||||
bool strstart_x(__xdata const uint8_t *a, __xdata const uint8_t *b);
|
||||
void tcpip_output(void);
|
||||
uint8_t read_flash(uint8_t bank, __code uint8_t *addr);
|
||||
void get_random_32(void);
|
||||
|
||||
Reference in New Issue
Block a user