diff options
Diffstat (limited to 'http.c')
-rw-r--r-- | http.c | 103 |
1 files changed, 99 insertions, 4 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); } |