mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-06 11:09:13 +00:00
Fix bugs in new HTTP server MIME body parsing code
Fixes all remaining 'rhizomeprotocol' test failures.
This commit is contained in:
parent
8f60a4ceb5
commit
6ee691b161
119
http_server.c
119
http_server.c
@ -838,7 +838,6 @@ static int http_request_start_body(struct http_request *r)
|
|||||||
assert(r->verb != NULL);
|
assert(r->verb != NULL);
|
||||||
assert(r->path != NULL);
|
assert(r->path != NULL);
|
||||||
assert(r->version_major != 0);
|
assert(r->version_major != 0);
|
||||||
assert(r->version_minor != 0);
|
|
||||||
assert(r->parsed <= r->end);
|
assert(r->parsed <= r->end);
|
||||||
if (r->verb == HTTP_VERB_GET) {
|
if (r->verb == HTTP_VERB_GET) {
|
||||||
// TODO: Implement HEAD requests (only send response header, not body)
|
// TODO: Implement HEAD requests (only send response header, not body)
|
||||||
@ -900,9 +899,9 @@ static int _skip_mime_boundary(struct http_request *r)
|
|||||||
{
|
{
|
||||||
if (!_skip_literal(r, "--") || !_skip_literal(r, r->request_header.boundary))
|
if (!_skip_literal(r, "--") || !_skip_literal(r, r->request_header.boundary))
|
||||||
return 0;
|
return 0;
|
||||||
if (_skip_literal(r, "--") && _skip_optional_space(r) && _skip_crlf(r))
|
if (_skip_literal(r, "--") && _skip_crlf(r))
|
||||||
return 2;
|
return 2;
|
||||||
if (_skip_optional_space(r) && _skip_crlf(r))
|
if (_skip_crlf(r))
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1001,51 +1000,49 @@ static int http_request_parse_body_form_data(struct http_request *r)
|
|||||||
at_start = 1;
|
at_start = 1;
|
||||||
r->form_data_state = PREAMBLE;
|
r->form_data_state = PREAMBLE;
|
||||||
// fall through
|
// fall through
|
||||||
case PREAMBLE:
|
case PREAMBLE: {
|
||||||
if (config.debug.httpd)
|
if (config.debug.httpd)
|
||||||
DEBUGF("PREAMBLE");
|
DEBUGF("PREAMBLE");
|
||||||
while (!_run_out(r)) {
|
const char *start = r->parsed;
|
||||||
const char *end_preamble = r->cursor;
|
for (; at_start || _skip_to_crlf(r); at_start = 0) {
|
||||||
int b;
|
const char *end_preamble = r->cursor;
|
||||||
if ((_skip_crlf(r) || at_start) && (b = _skip_mime_boundary(r))) {
|
int b;
|
||||||
assert(end_preamble >= r->parsed);
|
if ((b = _skip_mime_boundary(r))) {
|
||||||
if (r->form_data.handle_mime_preamble && end_preamble != r->parsed) {
|
assert(end_preamble >= r->parsed);
|
||||||
if (r->debug_flag && *r->debug_flag)
|
if (r->form_data.handle_mime_preamble && end_preamble != r->parsed) {
|
||||||
DEBUGF("handle_mime_preamble(%s length=%zu)",
|
|
||||||
alloca_toprint(50, r->parsed, end_preamble - r->parsed), end_preamble - r->parsed);
|
|
||||||
r->form_data.handle_mime_preamble(r, r->parsed, end_preamble - r->parsed);
|
|
||||||
}
|
|
||||||
_rewind_crlf(r);
|
|
||||||
_commit(r);
|
|
||||||
if (b == 1) {
|
|
||||||
r->form_data_state = HEADER;
|
|
||||||
if (r->form_data.handle_mime_part_start) {
|
|
||||||
if (r->debug_flag && *r->debug_flag)
|
if (r->debug_flag && *r->debug_flag)
|
||||||
DEBUGF("handle_mime_part_start()");
|
DEBUGF("handle_mime_preamble(%s length=%zu)",
|
||||||
r->form_data.handle_mime_part_start(r);
|
alloca_toprint(50, r->parsed, end_preamble - r->parsed), end_preamble - r->parsed);
|
||||||
|
r->form_data.handle_mime_preamble(r, r->parsed, end_preamble - r->parsed);
|
||||||
}
|
}
|
||||||
} else
|
_rewind_crlf(r);
|
||||||
r->form_data_state = EPILOGUE;
|
_commit(r);
|
||||||
return 0;
|
if (b == 1) {
|
||||||
}
|
r->form_data_state = HEADER;
|
||||||
if (!_skip_to_crlf(r)) {
|
if (r->form_data.handle_mime_part_start) {
|
||||||
if (_end_of_content(r)) {
|
if (r->debug_flag && *r->debug_flag)
|
||||||
if (r->debug_flag && *r->debug_flag)
|
DEBUGF("handle_mime_part_start()");
|
||||||
DEBUGF("Malformed HTTP %s form data: missing first boundary", r->verb);
|
r->form_data.handle_mime_part_start(r);
|
||||||
return 400;
|
}
|
||||||
|
} else
|
||||||
|
r->form_data_state = EPILOGUE;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
return 100; // need more data
|
|
||||||
}
|
}
|
||||||
at_start = 0;
|
if (_end_of_content(r)) {
|
||||||
|
if (r->debug_flag && *r->debug_flag)
|
||||||
|
DEBUGF("Malformed HTTP %s form data: missing first boundary", r->verb);
|
||||||
|
return 400;
|
||||||
|
}
|
||||||
|
_commit(r);
|
||||||
|
if (r->parsed > start && r->form_data.handle_mime_preamble) {
|
||||||
|
if (r->debug_flag && *r->debug_flag)
|
||||||
|
DEBUGF("handle_mime_preamble(%s length=%zu)",
|
||||||
|
alloca_toprint(50, start, r->parsed - start), r->parsed - start);
|
||||||
|
r->form_data.handle_mime_preamble(r, start, r->parsed - start);
|
||||||
|
}
|
||||||
|
return 100; // need more data
|
||||||
}
|
}
|
||||||
if (r->cursor > r->parsed && r->form_data.handle_mime_preamble) {
|
|
||||||
if (r->debug_flag && *r->debug_flag)
|
|
||||||
DEBUGF("handle_mime_preamble(%s length=%zu)",
|
|
||||||
alloca_toprint(50, r->parsed, r->cursor - r->parsed), r->cursor - r->parsed);
|
|
||||||
r->form_data.handle_mime_preamble(r, r->parsed, r->cursor - r->parsed);
|
|
||||||
}
|
|
||||||
_commit(r);
|
|
||||||
return 100; // need more data
|
|
||||||
case HEADER: {
|
case HEADER: {
|
||||||
if (config.debug.httpd)
|
if (config.debug.httpd)
|
||||||
DEBUGF("HEADER");
|
DEBUGF("HEADER");
|
||||||
@ -1124,17 +1121,18 @@ static int http_request_parse_body_form_data(struct http_request *r)
|
|||||||
case BODY:
|
case BODY:
|
||||||
if (config.debug.httpd)
|
if (config.debug.httpd)
|
||||||
DEBUGF("BODY");
|
DEBUGF("BODY");
|
||||||
const char *start = r->cursor;
|
const char *start = r->parsed;
|
||||||
while (!_run_out(r)) {
|
while (_skip_to_crlf(r)) {
|
||||||
int b;
|
int b;
|
||||||
const char *eol = r->cursor;
|
const char *end_body = r->cursor;
|
||||||
if (_skip_crlf(r) && (b = _skip_mime_boundary(r))) {
|
_skip_crlf(r);
|
||||||
|
if ((b = _skip_mime_boundary(r))) {
|
||||||
_rewind_crlf(r);
|
_rewind_crlf(r);
|
||||||
_commit(r);
|
_commit(r);
|
||||||
if (r->form_data.handle_mime_body) {
|
if (end_body > start && r->form_data.handle_mime_body) {
|
||||||
if (r->debug_flag && *r->debug_flag)
|
if (r->debug_flag && *r->debug_flag)
|
||||||
DEBUGF("handle_mime_body(%s length=%zu)", alloca_toprint(50, start, eol - start), eol - start);
|
DEBUGF("handle_mime_body(%s length=%zu)", alloca_toprint(80, start, end_body - start), end_body - start);
|
||||||
r->form_data.handle_mime_body(r, start, eol - start); // excluding CRLF at end
|
r->form_data.handle_mime_body(r, start, end_body - start); // excluding CRLF at end
|
||||||
}
|
}
|
||||||
if (r->form_data.handle_mime_part_end) {
|
if (r->form_data.handle_mime_part_end) {
|
||||||
if (r->debug_flag && *r->debug_flag)
|
if (r->debug_flag && *r->debug_flag)
|
||||||
@ -1152,21 +1150,18 @@ static int http_request_parse_body_form_data(struct http_request *r)
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!_skip_to_crlf(r)) {
|
|
||||||
if (_end_of_content(r)) {
|
|
||||||
if (r->debug_flag && *r->debug_flag)
|
|
||||||
DEBUGF("Malformed HTTP %s form data part: missing end boundary", r->verb);
|
|
||||||
return 400;
|
|
||||||
}
|
|
||||||
return 100; // need more data
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (r->cursor > r->parsed && r->form_data.handle_mime_body) {
|
if (_end_of_content(r)) {
|
||||||
if (r->debug_flag && *r->debug_flag)
|
if (r->debug_flag && *r->debug_flag)
|
||||||
DEBUGF("handle_mime_body(%s length=%zu)", alloca_toprint(50, r->parsed, r->cursor - r->parsed), r->cursor - r->parsed);
|
DEBUGF("Malformed HTTP %s form data part: missing end boundary", r->verb);
|
||||||
r->form_data.handle_mime_body(r, r->parsed, r->cursor - r->parsed);
|
return 400;
|
||||||
}
|
}
|
||||||
_commit(r);
|
_commit(r);
|
||||||
|
if (r->parsed > start && r->form_data.handle_mime_body) {
|
||||||
|
if (r->debug_flag && *r->debug_flag)
|
||||||
|
DEBUGF("handle_mime_body(%s length=%zu)", alloca_toprint(80, start, r->parsed - start), r->parsed - start);
|
||||||
|
r->form_data.handle_mime_body(r, start, r->parsed - start);
|
||||||
|
}
|
||||||
return 100; // need more data
|
return 100; // need more data
|
||||||
case EPILOGUE:
|
case EPILOGUE:
|
||||||
if (config.debug.httpd)
|
if (config.debug.httpd)
|
||||||
@ -1227,6 +1222,8 @@ static void http_request_receive(struct http_request *r)
|
|||||||
r->parsed = r->received;
|
r->parsed = r->received;
|
||||||
r->end = r->received + unparsed;
|
r->end = r->received + unparsed;
|
||||||
room = bufend - r->end;
|
room = bufend - r->end;
|
||||||
|
if (r->request_content_remaining != CONTENT_LENGTH_UNKNOWN && room > r->request_content_remaining)
|
||||||
|
room = r->request_content_remaining;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If there is no more buffer space, fail the request.
|
// If there is no more buffer space, fail the request.
|
||||||
|
@ -671,9 +671,6 @@ void rhizome_direct_http_dispatch(rhizome_direct_sync_request *r)
|
|||||||
+m->fileLength
|
+m->fileLength
|
||||||
+strlen("\r\n--")+strlen(boundary)+strlen("--\r\n");
|
+strlen("\r\n--")+strlen(boundary)+strlen("--\r\n");
|
||||||
|
|
||||||
/* XXX For some reason the above is four bytes out, so fix that */
|
|
||||||
content_length+=4;
|
|
||||||
|
|
||||||
int len=snprintf(buffer,8192,template,content_length,boundary);
|
int len=snprintf(buffer,8192,template,content_length,boundary);
|
||||||
len+=snprintf(&buffer[len],8192-len,template2,boundary);
|
len+=snprintf(&buffer[len],8192-len,template2,boundary);
|
||||||
memcpy(&buffer[len],m->manifestdata,m->manifest_all_bytes);
|
memcpy(&buffer[len],m->manifestdata,m->manifest_all_bytes);
|
||||||
|
@ -657,6 +657,8 @@ setup_DirectPush() {
|
|||||||
setup_common
|
setup_common
|
||||||
setup_direct
|
setup_direct
|
||||||
setup_direct_peer
|
setup_direct_peer
|
||||||
|
executeOk ls -l
|
||||||
|
tfw_cat --stdout
|
||||||
}
|
}
|
||||||
test_DirectPush() {
|
test_DirectPush() {
|
||||||
set_instance +B
|
set_instance +B
|
||||||
|
Loading…
x
Reference in New Issue
Block a user