Refactor multipart parsing

main
cel 5 years ago
parent 00dafd5ea9
commit fa9b692948

@ -961,6 +961,15 @@ static char *next_line(char *str) {
return nextline;
}
static char *parse_header(char *line) {
char *value = strchr(line, ':');
if (value != NULL) {
*value++ = '\0';
while (*value == ' ') value++;
}
return value;
}
static int http_serve_index(struct http_request *req) {
write_buf(req->fd, "HTTP/1.0 200 OK\r\nConnection: close\r\n\r\n");
close(req->fd);
@ -990,42 +999,48 @@ static int parse_multipart(struct http_request *req) {
req->len = len;
}
req->data[req->len] = '\0';
char *boundary_start = NULL;
while (req->len > 0) {
boundary_start = strstr(req->data, req->multipart_boundary);
if (boundary_start == NULL) return -1;
boundary_start += boundary_len;
char *line = boundary_start;
// iterate through parts
char *part, *next;
const char *boundary = req->multipart_boundary;
for (part = strstr(req->data, boundary); part != NULL; part = next) {
part += boundary_len;
if (part[0] == '-' && part[1] == '-') break; // end of parts
if (*part == '\r') part++;
if (*part == '\n') part++;
next = strstr(part, req->multipart_boundary);
char *end = next;
if (end != NULL) {
if (end[-1] == '\n') end--;
if (end[-1] == '\r') end--;
*end = '\0';
}
// iterate through headers in part
char *line, *nextline;
char *cdisp = NULL;
bool is_text = false;
if (*line == '\r') line++;
if (*line == '\n') line++;
char *nextline;
while (line != NULL) {
for (line = part; line != NULL; line = nextline) {
nextline = next_line(line);
if (!line[0]) break;
if (!*line) break; // end of headers
char *name = line;
char *value = strchr(line, ':');
if (value != NULL) {
*value++ = '\0';
while (*value == ' ') value++;
}
char *value = parse_header(line);
if (!strncmp(name, "Content-Disposition", 3)) cdisp = value;
line = nextline;
}
if (cdisp != NULL && !strcmp(cdisp, "form-data; name=\"text\"")) {
is_text = true;
char *name = NULL;
if (cdisp != NULL && !strncmp(cdisp, "form-data; name=\"", 17)) {
name = cdisp + 17;
char *end = strchr(name, '"');
if (end != NULL) *end = '\0';
}
req->len -= nextline - req->data;
req->data = nextline;
char *end = strstr(nextline, req->multipart_boundary);
if (end == NULL || strncmp(end + boundary_len, "--", 2)) return -1;
if (end[-1] == '\n') end--;
if (end[-1] == '\r') end--;
*end = '\0';
req->len = end - nextline;
if (is_text) break;
// handle part body
char *body = nextline;
if (body == NULL) continue;
if (!strcmp(name, "text")) {
req->data = body;
req->len = end == NULL ? strlen(body) : end - body;
}
}
return 0;
}
@ -1181,11 +1196,7 @@ static int handle_http_client(int fd, int firstchar) {
nextline = next_line(line);
if (!line[0]) break;
char *name = line;
char *value = strchr(line, ':');
if (value != NULL) {
*value++ = '\0';
while (*value == ' ') value++;
}
char *value = parse_header(line);
if (!strncmp(name, "Host", 3)) req.host = value;
else if (!strncmp(name, "Referer", 7)) req.referer = value;
else if (!strncmp(name, "Content-Length", 14)) req.content_length = atoi(value);

Loading…
Cancel
Save