diff --git a/README b/README index e5f0d25..ed94734 100644 --- a/README +++ b/README @@ -8,6 +8,22 @@ RES: github.com/tinyproxy/tinyproxy RES: github.com/nginx/nginx +TECHNICALS + + int initres(void); + void fretres(void); + int readlin(char **buff, char **buff_lim); + int parshfield(char **offset, int len, /* out */ struct point *hentries); + int parstitle(char *offset, int len, /* out */ struct httitle *titl); + int parsme(char **buff, /* out */ struct httpars *pars); + + Library is designed to follow source input unaltering. + Which means, that it does not directly alter the input + data or strings while storing the information of all + parsed results on the stack or as pointers to specific + parts of the source data. This allows to provide it + with input that resides both within the stack or heap. + LEAKS LEAKS file contains the most recent valgrind memory leaks @@ -18,7 +34,6 @@ LEAKS TODO - * headers table needs length fields * implement tests * integrations with tinyproxy..? diff --git a/tinyparser b/tinyparser deleted file mode 100755 index 38dc33e..0000000 Binary files a/tinyparser and /dev/null differ diff --git a/tinyparser.c b/tinyparser.c index 09a0379..4ca407b 100644 --- a/tinyparser.c +++ b/tinyparser.c @@ -4,38 +4,83 @@ #include "tinyparser.h" #include "streecmp/streecmp.h" -extern char *headers; extern char *methods; +extern char *headers; -int method = 0; -char *uri = NULL; -char *ver = NULL; -int uri_len = 0; -int ver_len = 0; +static struct nod *method_tree = NULL; +static struct nod *header_tree = NULL; -struct nod *header_tree = NULL; -struct nod *method_tree = NULL; -struct point *header_table = NULL; +static void debug_stats(struct httpars *pars) { + fprintf(stderr, "\tstats:\n" + "\t\tmethod\t: %d\n" + "\t\turi\t: %.*s\n" + "\t\tver\t: %.*s\n", + pars->titl.method, + pars->titl.uri.len, pars->titl.uri.er, + pars->titl.ver.len, pars->titl.ver.er + ); -int read_line(char **buffer, char **buffer_limit) { + fprintf(stdout, "\theaders:\n"); + for (int i = 0; i < header_count; i++) { + struct point *pnt = &pars->hentries[i]; + if (!pnt->er) { + continue; + } + + fprintf(stdout, "\t\t%d\t: %.*s\n", i, pnt->len, pnt->er); + } +} + +int initres(void) { + int ret = 0; + + header_tree = allocnod(); + if (!header_tree) { + return -1; + } + + method_tree = allocnod(); + if (!method_tree) { + return -1; + } + + ret = gentree(header_tree, headers, NULL); + if (ret < 0) { + return -1; + } + + ret = gentree(method_tree, methods, NULL); + if (ret < 0) { + return -1; + } + + return 0; +} + +void fretres(void) { + free(method_tree); + free(header_tree); +} + +int read_line(char **buff, char **buff_lim) { int diff = 0; - if ((*buffer) >= (*buffer_limit)) { + if ((*buff) >= (*buff_lim)) { return diff; } int ret = 0; - char *match = strstr(*buffer, "\r\n"); + char *match = strstr(*buff, "\r\n"); if (match) { - ret = match-(*buffer); - *buffer += 2; + ret = match-(*buff); + *buff += 2; } else { - ret = (*buffer_limit)-(*buffer); + ret = (*buff_lim)-(*buff); } - *buffer += ret; + *buff += ret; return ret; } -int parse_header(char *offset, int len) { +int parshfield(char *offset, int len, struct point *hentries) { int key = 0; int ret = 0; int diff = 0; @@ -78,13 +123,13 @@ _loop: // header value diff = cursor_lim-cursor; - header_table[key].er = cursor; - header_table[key].len = diff; + hentries[key].er = cursor; + hentries[key].len = diff; return 0; } -int parse_title(char *offset, int len) { +int parstitle(char *offset, int len, struct httitle *titl) { int ret = 0; int diff = 0; char *cursor = offset; @@ -105,7 +150,7 @@ int parse_title(char *offset, int len) { return -1; } - method = ret; + titl->method = ret; cursor += diff; // white space @@ -128,8 +173,8 @@ _loop1: } diff = uri_lim-cursor; - uri = cursor; - uri_len = diff; + titl->uri.er = cursor; + titl->uri.len = diff; cursor += diff; @@ -145,28 +190,28 @@ _loop2: // ver diff = cursor_lim-cursor; - ver = cursor; - ver_len = diff; + titl->ver.er = cursor; + titl->ver.len = diff; cursor += diff; return 0; } -int parse_request(char *buffer) { +int parsme(char *buff, struct httpars *pars) { int ret; - char *buffer_limit = buffer+strlen(buffer); + char *buff_lim = buff+strlen(buff); - char *title_offset = buffer; - int title_len = read_line(&buffer, &buffer_limit); - if ((ret = parse_title(title_offset, title_len)) < 0) { + char *title_offset = buff; + int title_len = read_line(&buff, &buff_lim); + if ((ret = parstitle(title_offset, title_len, &pars->titl)) < 0) { fprintf(stderr, "Failed parsing title\n"); return -1; } for (int bound = 0; bound < MAX_BOUND; bound++) { - char *header_offset = buffer; - int header_len = read_line(&buffer, &buffer_limit); + char *header_offset = buff; + int header_len = read_line(&buff, &buff_lim); char *header_limit = header_offset+header_len; // IF END OF MESSAGE @@ -174,7 +219,9 @@ int parse_request(char *buffer) { break; } - if ((ret = parse_header(header_offset, header_len)) < 0) { + if ((ret = parshfield(header_offset, + header_len, + pars->hentries)) < 0) { fprintf(stderr, "Failed parsing header\n"); return -1; } @@ -183,72 +230,3 @@ int parse_request(char *buffer) { return 0; } -void debug_stats(void) { - fprintf(stderr, "\tstats:\n" - "\t\tmethod\t: %d\n" - "\t\turi\t: %.*s\n" - "\t\tver\t: %.*s\n", - method, uri_len, uri, ver_len, ver - ); - - fprintf(stdout, "\theaders:\n"); - for (int i = 0; i < header_count; i++) { - struct point *pnt = &header_table[i]; - if (!pnt->er) { - continue; - } - - fprintf(stdout, "\t\t%d\t: %.*s\n", i, pnt->len, pnt->er); - } -} - -int main(void) { - int ret; - char *str = strdup(TEST_ONE); - - header_table = (struct point *) calloc(header_count, sizeof(struct point)); - if (!header_table) { - fprintf(stderr, "Not enough dynamic memory\n"); - return -1; - } - - header_tree = allocnod(); - if (!header_tree) { - fprintf(stderr, "Not enough dynamic memory\n"); - return -1; - } - - method_tree = allocnod(); - if (!method_tree) { - fprintf(stderr, "Not enough dynamic memory\n"); - return -1; - } - - ret = gentree(header_tree, headers, NULL); - if (ret < 0) { - fprintf(stderr, "Failed generating the header comparison tree\n"); - return -1; - } - - ret = gentree(method_tree, methods, NULL); - if (ret < 0) { - fprintf(stderr, "Failed generating the header comparison tree\n"); - return -1; - } - - ret = parse_request(str); - if (ret < 0) { - fprintf(stderr, "Failed parsing request\n"); - return -1; - } - - fprintf(stdout, "++Successfully parsed data++\n"); - debug_stats(); - - frenod(method_tree); - frenod(header_tree); - free(header_table); - free(str); - - return 0; -} diff --git a/tinyparser.h b/tinyparser.h index e8d157d..09e419a 100644 --- a/tinyparser.h +++ b/tinyparser.h @@ -11,8 +11,6 @@ "\r\n"\ "{\"key\": \"kefjoiawejfojgorgjbosejrgo\"}"\ -// ENUMS - // SRC:https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods enum methods { method_get = 1, @@ -145,4 +143,22 @@ struct point { int len; }; +struct httitle { + int method; + struct point uri; + struct point ver; +}; + +struct httpars { + struct httitle titl; + struct point hentries[header_count]; +}; + +int initres(void); +void fretres(void); +int readlin(char **buff, char **buff_lim); +int parshfield(char *offset, int len, /* out */ struct point *hentries); +int parstitle(char *offset, int len, /* out */ struct httitle *titl); +int parsme(char *buff, /* out */ struct httpars *pars); + #endif