Mime parsing
FossilOrigin-Name: e6a37f930fb748cdf6828053bc6df089e4ea426602863ae77aefb62c8ff773f2
This commit is contained in:
parent
4114bac685
commit
8d4b8f77d4
4 changed files with 105 additions and 23 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -4,4 +4,5 @@ filec
|
|||
**/*.chtml
|
||||
mastodont-c
|
||||
config.h
|
||||
treebird
|
||||
treebird
|
||||
test/tests
|
|
@ -1,3 +1,5 @@
|
|||
# NOTE: This software is not finished. Any bugs are likely noted
|
||||
|
||||
# Treebird
|
||||
|
||||
![Treebird logo](./meta/treebird.png)
|
||||
|
|
112
src/mime.c
112
src/mime.c
|
@ -20,6 +20,7 @@
|
|||
#include <fcgi_stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include "mime.h"
|
||||
|
||||
char* get_mime_boundary(char* content_type_str, char** bound)
|
||||
|
@ -64,49 +65,118 @@ error:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
char* strnws(char* str)
|
||||
static char* strnws(char* str)
|
||||
{
|
||||
for (; isblank(*str); ++str);
|
||||
return str;
|
||||
}
|
||||
|
||||
#define STRSCMP(begin, str) strncmp((begin), (str), sizeof(str))
|
||||
// Function assumes character is at ';' char
|
||||
static char* read_key(char** r, char* key)
|
||||
{
|
||||
char* val, *read_val;
|
||||
size_t key_len = strlen(key);
|
||||
*r = strnws(*r+1);
|
||||
if (strncmp(*r, key, key_len) != 0)
|
||||
return NULL;
|
||||
*r = strnws(*r + key_len);
|
||||
if (**r != '=')
|
||||
return NULL;
|
||||
*r = strnws(*r + 1);
|
||||
if (**r == '\"') ++(*r);
|
||||
val = *r;
|
||||
// Chop off string
|
||||
if ((read_val = strchr(*r, '\"')) ||
|
||||
(read_val = strchr(*r, ';')) ||
|
||||
(read_val = strchr(*r, '\r')))
|
||||
*read_val = '\0';
|
||||
// Jump to end
|
||||
*r += strlen(val)+1;
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
#define STRSCMP(begin, str) strncmp((begin), (str), sizeof(str)-1)
|
||||
|
||||
char* read_form_data(char* boundary, char* begin, struct http_form_info* info)
|
||||
{
|
||||
char* r, *name;
|
||||
ptrdiff_t data_size;
|
||||
// Step 1: Parse name
|
||||
// Parser variables
|
||||
char* r, *read_val;
|
||||
size_t bound_len = strlen(boundary);
|
||||
if (strncmp(begin, "--", 2) != 0 ||
|
||||
strncmp(begin+2, boundary, bound_len) != 0)
|
||||
return NULL;
|
||||
|
||||
// Check if this is the end
|
||||
if (strncmp(begin + 2 + bound_len, "--", 2) == 0)
|
||||
return NULL;
|
||||
|
||||
r = begin + 2 + bound_len + 2; /* Skip over LRSF */
|
||||
|
||||
if (STRSCMP(r, "Content-Disposition") != 0)
|
||||
return NULL;
|
||||
|
||||
r = strnws(r + sizeof("Content-Disposition")+1);
|
||||
if (*r != ':' ||
|
||||
STRSCMP(r, "form-data") != 0) // Fucked up
|
||||
r = strnws(r + sizeof("Content-Disposition")-1);
|
||||
if (*r != ':') // Fucked up
|
||||
return NULL;
|
||||
|
||||
r = strnws(r + sizeof("form-data")+1);
|
||||
r = strnws(r + 1);
|
||||
if (STRSCMP(r, "form-data") != 0)
|
||||
return NULL;
|
||||
r = strnws(r + sizeof("form-data")-1);
|
||||
if (*r != ';')
|
||||
return NULL;
|
||||
r = strnws(r+1);
|
||||
if (STRSCMP(r, "name") != 0)
|
||||
return NULL;
|
||||
r = strnws(r + sizeof("name")+1);
|
||||
if (*r != '=')
|
||||
return NULL;
|
||||
r = strnws(r + 1);
|
||||
if (*r == '\"')
|
||||
|
||||
info->name = read_key(&r, "name");
|
||||
// Step 2: Parse filename (if there)
|
||||
if (*r == ';')
|
||||
{
|
||||
info->filename = read_key(&r, "filename");
|
||||
}
|
||||
else
|
||||
info->filename = NULL;
|
||||
|
||||
if (*r == '\r')
|
||||
r += 2;
|
||||
if (*r == '\"') ++r;
|
||||
name = r;
|
||||
if ((r = strchr(r, '\"')))
|
||||
*r = '\0';
|
||||
|
||||
printf("nameparsed: %s\r\n", name);
|
||||
// Step 3: Parse Content-type (if there)
|
||||
if (STRSCMP(r, "Content-Type") == 0)
|
||||
{
|
||||
r = strnws(r + sizeof("Content-type")-1);
|
||||
if (*r != ':')
|
||||
return NULL;
|
||||
|
||||
return name;
|
||||
r = strnws(r + 1);
|
||||
info->content_type = r;
|
||||
if ((r = strchr(r, '\r')))
|
||||
*r = '\0';
|
||||
else
|
||||
return NULL;
|
||||
r += 4;
|
||||
}
|
||||
else if (*r == '\r') {
|
||||
info->content_type = NULL;
|
||||
r += 2;
|
||||
}
|
||||
|
||||
// Last step: Find data
|
||||
info->value = r;
|
||||
|
||||
// Look for end
|
||||
if ((r = strstr(r, boundary)) &&
|
||||
r && strstr(r-4, "\r\n--"))
|
||||
{
|
||||
r[-4] = '\0';
|
||||
data_size = (r-4) - info->value;
|
||||
info->value_size = data_size;
|
||||
}
|
||||
else
|
||||
return NULL;
|
||||
|
||||
// Go back for next read
|
||||
r -= 2;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
11
src/mime.h
11
src/mime.h
|
@ -19,7 +19,16 @@
|
|||
#ifndef MIME_H
|
||||
#define MIME_H
|
||||
|
||||
struct http_form_info
|
||||
{
|
||||
char* name;
|
||||
char* filename;
|
||||
char* content_type;
|
||||
char* value;
|
||||
size_t value_size;
|
||||
};
|
||||
|
||||
char* get_mime_boundary(char* content_type, char** res);
|
||||
char* read_mime_data(char* boundary, char* begin, struct http_form_info* info);
|
||||
char* read_form_data(char* boundary, char* begin, struct http_form_info* info);
|
||||
|
||||
#endif /* MIME_H */
|
||||
|
|
Loading…
Reference in a new issue