diff options
-rw-r--r-- | http.c | 103 | ||||
-rw-r--r-- | http.h | 5 | ||||
-rw-r--r-- | plop.c | 10 |
3 files changed, 113 insertions, 5 deletions
@@ -8,6 +8,7 @@ #include <unistd.h> static const int REQUEST_DATA_SIZE = 4096; +static const int MAX_HEADERS = 30; const char * status_str[] = { [STATUS_OK] = "200 OK", @@ -55,9 +56,9 @@ void free_request(struct request * request) free(request->data); } - if (NULL != request->headers) + if (NULL != request->headerv) { - free(request->headers); + free(request->headerv); } free(request); @@ -261,7 +262,101 @@ int parse_step_version(struct request * request) } request->version.length = request->position - request->version.start; - request->step = NULL; // TODO: Parse headers + request->step = parse_step_header_name; - return request->position; + return parse_step_header_name(request); +} + +/// Parses and verifies name of a single header from the request. +/// \param request Request to process +/// \return -1 if an error has occured, 0 if too little data available or total number of bytes processed +int parse_step_header_name(struct request * request) +{ + if (NULL == request->headerv) + { + request->headerv = malloc(sizeof(struct header) * MAX_HEADERS); + request->headerc = 0; + memset(request->headerv, 0, sizeof(struct header) * MAX_HEADERS); + + if (NULL == request->headerv) + { + return -1; + } + } + + // TODO: Check for the header section end without backtracking. + const int position = request->position; + int result = read_rest_of_line(request); + + if (0 == result) + { + return 0; + } + + if (2 == result - position) + { + // Header section ended, nothing left to parse. + return request->position + 2; + } + + request->position = position; + + if (0 >= request->headerv[request->headerc].name.start) + { + request->headerv[request->headerc].name.start = read_until_word(request); + + if (0 == request->headerv[request->headerc].name.start) + { + return 0; + } + } + + result = read_until_char(request, ':'); + + if (0 == result) + { + return 0; + } + + request->headerv[request->headerc].name.length = request->position - request->headerv[request->headerc].name.start; + request->step = parse_step_header_value; + + // Skip ':' + request->position++; + + return parse_step_header_value(request); +} + +/// Parses and verifies value of a single header from the request. +/// \param request Request to process +/// \return -1 if an error has occured, 0 if too little data available or total number of bytes processed +int parse_step_header_value(struct request * request) +{ + if (0 >= request->headerv[request->headerc].value.start) + { + request->headerv[request->headerc].value.start = read_until_word(request); + + if (0 == request->headerv[request->headerc].value.start) + { + return 0; + } + } + + const int result = read_rest_of_line(request); + + if (0 == result) + { + return 0; + } + + request->headerv[request->headerc].value.length = request->position - request->headerv[request->headerc].value.start; + request->step = parse_step_header_name; + request->headerc++; + + if (MAX_HEADERS == request->headerc) + { + return -1; + } + + return parse_step_header_name(request); } @@ -22,7 +22,8 @@ struct request struct span method; struct span path; struct span version; - struct header * headers; + struct header * headerv; + int headerc; struct span body; }; @@ -50,5 +51,7 @@ int parse_request(int, struct request **); int parse_step_method(struct request *); int parse_step_path(struct request *); int parse_step_version(struct request *); +int parse_step_header_name(struct request *); +int parse_step_header_value(struct request *); #endif // HTTP_H @@ -112,6 +112,16 @@ int handle_client(lua_State * L, struct pollfd * pfd, struct request ** request, (*request)->method.length, (*request)->data + (*request)->method.start, (*request)->path.length, (*request)->data + (*request)->path.start); + for (int h = 0; h < (*request)->headerc; ++h) + { + printf( + "\t'%.*s' = '%.*s'\n", + (*request)->headerv[h].name.length, + (*request)->data + (*request)->headerv[h].name.start, + (*request)->headerv[h].value.length, + (*request)->data + (*request)->headerv[h].value.start); + } + // TODO: Use results from parsing instead of raw data lua_getglobal(L, "Handler"); lua_pushlstring(L, (*request)->data, (*request)->length); |