diff --git a/zet.dpi.c b/zet.dpi.c index 9db8db6..f92f738 100644 --- a/zet.dpi.c +++ b/zet.dpi.c @@ -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'; + } + + // 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; } - 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; } 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);