#include #include #include #include "tinyparser.h" #include "streecmp/streecmp.h" extern char *headers; extern char *methods; int method = 0; char *uri = NULL; char *ver = NULL; int uri_len = 0; int ver_len = 0; struct nod *header_tree = NULL; struct nod *method_tree = NULL; struct point *header_table = NULL; int read_line(char **buffer, char **buffer_limit) { int diff = 0; if ((*buffer) >= (*buffer_limit)) { return diff; } int ret = 0; char *match = strstr(*buffer, "\r\n"); if (match) { ret = match-(*buffer); *buffer += 2; } else { ret = (*buffer_limit)-(*buffer); } *buffer += ret; return ret; } int parse_header(char *offset, int len) { int key = 0; int ret = 0; int diff = 0; char *cursor = offset; char *cursor_lim = offset+len; // header title char *htitle_lim = strchr(cursor, ':'); if (!htitle_lim) { return -1; } if (htitle_lim > cursor_lim) { return -1; } diff = htitle_lim-cursor; ret = streencmp(header_tree, cursor, diff); if (!ret) { return -1; } key = ret; cursor += diff; // white space and seperators _loop: if (cursor > cursor_lim) { return -1; } if (*cursor == ':') { cursor++; goto _loop; } if (*cursor == ' ') { cursor++; goto _loop; } // header value diff = cursor_lim-cursor; header_table[key].er = cursor; header_table[key].len = diff; return 0; } int parse_title(char *offset, int len) { int ret = 0; int diff = 0; char *cursor = offset; char *cursor_lim = cursor+len; // method char *method_lim = strchr(offset, ' '); if (!method_lim) { return -1; } if (method_lim > cursor_lim) { return -1; } diff = method_lim-cursor; ret = streencmp(method_tree, cursor, diff); if (ret == 0) { return -1; } method = ret; cursor += diff; // white space _loop1: if (cursor > cursor_lim) { return -1; } if (*cursor == ' ') { cursor++; goto _loop1; } // uri char *uri_lim = strchr(cursor, ' '); if (!uri_lim) { return -1; } if (uri_lim > cursor_lim) { return -1; } diff = uri_lim-cursor; uri = cursor; uri_len = diff; cursor += diff; // white space _loop2: if (cursor > cursor_lim) { return -1; } if (*cursor == ' ') { cursor++; goto _loop2; } // ver diff = cursor_lim-cursor; ver = cursor; ver_len = diff; cursor += diff; return 0; } int parse_request(char *buffer) { int ret; char *buffer_limit = buffer+strlen(buffer); char *title_offset = buffer; int title_len = read_line(&buffer, &buffer_limit); if ((ret = parse_title(title_offset, title_len)) < 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_limit = header_offset+header_len; // IF END OF MESSAGE if (!header_len) { break; } if ((ret = parse_header(header_offset, header_len)) < 0) { fprintf(stderr, "Failed parsing header\n"); return -1; } } 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; }