13static char *skip_crlf(
char *p)
15 if (p[0] ==
'\r' && p[1] ==
'\n')
23static char *extract_quoted_param(
char *src,
const char *key)
25 char *p = strstr(src, key);
32 char *end = strchr(p,
'"');
48 const char *bsearch = strstr(ct,
"boundary=");
57 while (*bsearch && *bsearch !=
'"' && *bsearch !=
';' && *bsearch !=
' '
59 bval[blen++] = *bsearch++;
69 memcpy(delim + 2, bval, blen + 1);
70 size_t dlen = blen + 2;
72 char *body = (
char *)req->
body;
75 char *pos = strstr(body, delim);
85 if (pos[0] ==
'-' && pos[1] ==
'-')
98 if (pos[0] ==
'\r' && pos[1] ==
'\n')
104 char *line_end = strstr(pos,
"\r\n");
110 if (strncasecmp(pos,
"Content-Disposition:", 20) == 0)
119 part->
filename = extract_quoted_param(v,
"filename=");
120 part->
name = extract_quoted_param(v,
"name=");
122 else if (strncasecmp(pos,
"Content-Type:", 13) == 0)
135 char *next = strstr(pos, delim);
139 char *data_end = next - 2;
140 part->
data_len = (size_t)(data_end - pos);
145 pos = next + (int)dlen;
146 pos = skip_crlf(pos);
#define MAX_BOUNDARY_LEN
Maximum MIME boundary length (RFC 2046 allows up to 70 characters).
#define MAX_MULTIPART_PARTS
Maximum simultaneously parsed multipart parts per request.
const char * http_get_header(const HttpReq *req, const char *key)
Look up a header value by name (case-insensitive).
const char * multipart_get_field(const Multipart *mp, const char *field)
Look up a field value across all parsed parts by name.
bool multipart_parse(HttpReq *req, Multipart *mp)
Parse the body of req as multipart/form-data.
In-place multipart/form-data parser (RFC 7578).
Fully-parsed HTTP/1.1 request.
uint8_t body[BODY_BUF_SIZE+1]
Stored body bytes, always null-terminated.
One parsed part from a multipart body.
const char * data
Part body (null-terminated in-place).
const char * type
Content-Type of this part, or nullptr.
size_t data_len
Part body length in bytes (not counting the null).
const char * name
Form field name from Content-Disposition, or nullptr.
const char * filename
Upload filename from Content-Disposition, or nullptr.
Container for all parsed parts of a multipart body.
MultipartPart parts[MAX_MULTIPART_PARTS]
Parsed parts.
int part_count
Number of valid entries in parts[].