2024-08-15 23:12:06 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "tinyparser.h"
|
2024-09-02 22:03:32 +00:00
|
|
|
#include "streecmp/streecmp.h"
|
|
|
|
|
|
|
|
extern char *headers;
|
2024-09-03 19:07:52 +00:00
|
|
|
extern char *methods;
|
2024-08-15 23:12:06 +00:00
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
int method = 0;
|
2024-08-15 23:12:06 +00:00
|
|
|
char *uri = NULL;
|
|
|
|
char *ver = NULL;
|
|
|
|
int uri_len = 0;
|
|
|
|
int ver_len = 0;
|
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
struct nod *header_tree = NULL;
|
|
|
|
struct nod *method_tree = NULL;
|
2024-09-03 19:51:27 +00:00
|
|
|
struct point *header_table = NULL;
|
2024-09-02 22:03:32 +00:00
|
|
|
|
|
|
|
int read_line(char **buffer, char **buffer_limit) {
|
2024-08-15 23:12:06 +00:00
|
|
|
int diff = 0;
|
2024-09-02 22:03:32 +00:00
|
|
|
if ((*buffer) >= (*buffer_limit)) {
|
|
|
|
return diff;
|
|
|
|
}
|
2024-08-15 23:12:06 +00:00
|
|
|
|
2024-09-02 22:03:32 +00:00
|
|
|
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;
|
2024-08-15 23:12:06 +00:00
|
|
|
}
|
|
|
|
|
2024-09-02 22:03:32 +00:00
|
|
|
int parse_header(char *offset, int len) {
|
2024-09-03 19:51:27 +00:00
|
|
|
int key = 0;
|
2024-09-02 22:03:32 +00:00
|
|
|
int ret = 0;
|
2024-09-03 19:51:27 +00:00
|
|
|
int diff = 0;
|
|
|
|
|
|
|
|
char *cursor = offset;
|
|
|
|
char *cursor_lim = offset+len;
|
|
|
|
|
|
|
|
// header title
|
2024-09-03 20:09:09 +00:00
|
|
|
char *htitle_lim = strchr(cursor, ':');
|
2024-09-03 19:51:27 +00:00
|
|
|
if (!htitle_lim) {
|
2024-09-02 22:03:32 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2024-09-03 19:51:27 +00:00
|
|
|
if (htitle_lim > cursor_lim) {
|
2024-09-02 22:03:32 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-09-03 19:51:27 +00:00
|
|
|
diff = htitle_lim-cursor;
|
|
|
|
ret = streencmp(header_tree, cursor, diff);
|
|
|
|
if (!ret) {
|
2024-09-02 22:03:32 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-09-03 19:51:27 +00:00
|
|
|
key = ret;
|
|
|
|
cursor += diff;
|
|
|
|
|
|
|
|
// white space and seperators
|
2024-09-03 20:09:09 +00:00
|
|
|
_loop:
|
|
|
|
if (cursor > cursor_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (*cursor == ':') {
|
|
|
|
cursor++;
|
|
|
|
goto _loop;
|
|
|
|
}
|
|
|
|
if (*cursor == ' ') {
|
2024-09-03 19:51:27 +00:00
|
|
|
cursor++;
|
2024-09-03 20:09:09 +00:00
|
|
|
goto _loop;
|
2024-09-03 19:51:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// header value
|
|
|
|
diff = cursor_lim-cursor;
|
|
|
|
|
|
|
|
header_table[key].er = cursor;
|
|
|
|
header_table[key].len = diff;
|
2024-09-02 22:03:32 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int parse_title(char *offset, int len) {
|
2024-09-03 19:07:52 +00:00
|
|
|
int ret = 0;
|
|
|
|
int diff = 0;
|
|
|
|
char *cursor = offset;
|
|
|
|
char *cursor_lim = cursor+len;
|
2024-08-15 23:12:06 +00:00
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
// method
|
|
|
|
char *method_lim = strchr(offset, ' ');
|
|
|
|
if (!method_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
2024-09-03 20:09:09 +00:00
|
|
|
if (method_lim > cursor_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
2024-08-15 23:12:06 +00:00
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
diff = method_lim-cursor;
|
|
|
|
ret = streencmp(method_tree, cursor, diff);
|
|
|
|
if (ret == 0) {
|
|
|
|
return -1;
|
|
|
|
}
|
2024-08-15 23:12:06 +00:00
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
method = ret;
|
|
|
|
cursor += diff;
|
|
|
|
|
|
|
|
// white space
|
2024-09-03 20:09:09 +00:00
|
|
|
_loop1:
|
|
|
|
if (cursor > cursor_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (*cursor == ' ') {
|
2024-09-03 19:07:52 +00:00
|
|
|
cursor++;
|
2024-09-03 20:09:09 +00:00
|
|
|
goto _loop1;
|
2024-09-03 19:07:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// uri
|
|
|
|
char *uri_lim = strchr(cursor, ' ');
|
|
|
|
if (!uri_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
2024-09-03 20:09:09 +00:00
|
|
|
if (uri_lim > cursor_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
2024-09-03 19:07:52 +00:00
|
|
|
|
|
|
|
diff = uri_lim-cursor;
|
|
|
|
uri = cursor;
|
|
|
|
uri_len = diff;
|
|
|
|
|
|
|
|
cursor += diff;
|
|
|
|
|
|
|
|
// white space
|
2024-09-03 20:09:09 +00:00
|
|
|
_loop2:
|
|
|
|
if (cursor > cursor_lim) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (*cursor == ' ') {
|
2024-09-03 19:07:52 +00:00
|
|
|
cursor++;
|
2024-09-03 20:09:09 +00:00
|
|
|
goto _loop2;
|
2024-08-15 23:12:06 +00:00
|
|
|
}
|
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
// ver
|
|
|
|
diff = cursor_lim-cursor;
|
|
|
|
ver = cursor;
|
|
|
|
ver_len = diff;
|
|
|
|
|
|
|
|
cursor += diff;
|
|
|
|
|
2024-08-15 23:12:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int parse_request(char *buffer) {
|
|
|
|
int ret;
|
2024-09-02 22:03:32 +00:00
|
|
|
char *buffer_limit = buffer+strlen(buffer);
|
2024-08-15 23:12:06 +00:00
|
|
|
|
|
|
|
char *title_offset = buffer;
|
2024-09-02 22:03:32 +00:00
|
|
|
int title_len = read_line(&buffer, &buffer_limit);
|
2024-08-15 23:12:06 +00:00
|
|
|
if ((ret = parse_title(title_offset, title_len)) < 0) {
|
|
|
|
fprintf(stderr, "Failed parsing title\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-09-02 22:03:32 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-15 23:12:06 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-03 19:51:27 +00:00
|
|
|
void debug_stats(void) {
|
|
|
|
fprintf(stderr, "\tstats:\n"
|
2024-09-03 20:09:09 +00:00
|
|
|
"\t\tmethod\t: %d\n"
|
|
|
|
"\t\turi\t: %.*s\n"
|
|
|
|
"\t\tver\t: %.*s\n",
|
2024-09-03 19:51:27 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-09-03 20:09:09 +00:00
|
|
|
fprintf(stdout, "\t\t%d\t: %.*s\n", i, pnt->len, pnt->er);
|
2024-09-03 19:51:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-15 23:12:06 +00:00
|
|
|
int main(void) {
|
|
|
|
int ret;
|
|
|
|
char *str = strdup(TEST_ONE);
|
|
|
|
|
2024-09-03 19:51:27 +00:00
|
|
|
header_table = (struct point *) calloc(header_count, sizeof(struct point));
|
2024-09-02 22:03:32 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
method_tree = allocnod();
|
|
|
|
if (!method_tree) {
|
|
|
|
fprintf(stderr, "Not enough dynamic memory\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-09-02 22:03:32 +00:00
|
|
|
ret = gentree(header_tree, headers, NULL);
|
2024-09-03 19:07:52 +00:00
|
|
|
if (ret < 0) {
|
|
|
|
fprintf(stderr, "Failed generating the header comparison tree\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
ret = gentree(method_tree, methods, NULL);
|
|
|
|
if (ret < 0) {
|
2024-09-02 22:03:32 +00:00
|
|
|
fprintf(stderr, "Failed generating the header comparison tree\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-08-15 23:12:06 +00:00
|
|
|
ret = parse_request(str);
|
|
|
|
if (ret < 0) {
|
|
|
|
fprintf(stderr, "Failed parsing request\n");
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-09-03 19:51:27 +00:00
|
|
|
fprintf(stdout, "++Successfully parsed data++\n");
|
|
|
|
debug_stats();
|
2024-08-15 23:12:06 +00:00
|
|
|
|
2024-09-03 19:07:52 +00:00
|
|
|
frenod(method_tree);
|
2024-09-02 22:03:32 +00:00
|
|
|
frenod(header_tree);
|
|
|
|
free(header_table);
|
2024-08-15 23:12:06 +00:00
|
|
|
free(str);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|