Work on request header parsing

This commit is contained in:
2014-07-18 23:40:15 +01:00
parent 6d3ca314d4
commit e56f8f3715
10 changed files with 165 additions and 7 deletions

Binary file not shown.

View File

@@ -13,6 +13,8 @@
<gdb_interceptlist>
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
</gdb_interceptlist>
<gdb_signals>
</gdb_signals>
<gdb_options>
<DebugOptions>
</DebugOptions>

View File

@@ -3,6 +3,7 @@
#include <stdint.h>
#include <string.h>
#include "http.h"
#include "../main.h"
/*
* METHOD_GET, METHOD_POST, METHOD_HEAD, METHOD_PUT,
@@ -32,7 +33,7 @@ http_method http_method_fromstring(const char* method) {
METHOD_CONNECT};
size_t count = sizeof(methods) / sizeof(http_method);
for(int i; i < count; i++) {
for(int i=0; i < count; i++) {
if (strcmp(http_method_getstring(methods[i],NULL), method) == 0) {
return methods[i];
}
@@ -42,6 +43,9 @@ http_method http_method_fromstring(const char* method) {
http_request_line *http_request_line_new(http_method method, const char* other) {
http_request_line *req = calloc(1, sizeof(http_request_line));
if (req == NULL) {
fatal("calloc failed");
}
req->method = method;
if (req->method == METHOD_OTHER) {
req->method_other = calloc(strlen(other)+1, sizeof(char));
@@ -59,6 +63,9 @@ void http_request_line_delete(http_request_line *req) {
http_response_line *http_response_line_new(uint16_t code) {
http_response_line *resp = calloc(1, sizeof(http_response_line));
if (resp == NULL) {
fatal("calloc failed");
}
resp->code = code;
resp->version = HTTP11;
return resp;
@@ -117,7 +124,9 @@ void http_reponse_line_delete(http_response_line *resp) {
http_header *http_header_new(const char* name) {
http_header *header = calloc(1, sizeof(http_header));
if (header == NULL) {
fatal("calloc failed");
}
header->name = calloc(strlen(name)+1, sizeof(char));
strcpy(header->name, name);
@@ -126,10 +135,16 @@ http_header *http_header_new(const char* name) {
void http_header_append_content(http_header *header, const char* content) {
if (header->content == NULL) {
header->content = calloc(strlen(content)+1, sizeof(char));
if (header->content == NULL) {
fatal("calloc failed");
}
strcpy(header->content, content);
} else {
uint32_t newlen = strlen(header->content) + strlen(content) + 1;
header->content = realloc(header->content, newlen);
if (header->content == NULL) {
fatal("calloc failed");
}
strcat(header->content, content);
}
}
@@ -141,13 +156,20 @@ void http_header_delete(http_header *header) {
http_request *http_request_new() {
http_request *req = calloc(1, sizeof(http_request));
if (req == NULL) {
fatal("calloc failed");
}
req->header_count = 0;
req->body = NULL;
req->parsestatus = PARSE_REQUESTLINE;
return req;
}
void http_request_add_header(http_request *req, http_header *header) {
req->header_count++;
req->headers = realloc(req->headers, req->header_count * sizeof(http_header*));
if (req->headers == NULL) {
fatal("calloc failed");
}
req->headers[req->header_count-1] = header;
}
void http_request_apppend_body(http_request *req, const char* body) {
@@ -157,6 +179,9 @@ void http_request_apppend_body(http_request *req, const char* body) {
}
bodylen += strlen(body) + 1;
req->body = realloc(req->body, bodylen * sizeof(char));
if (req->body == NULL) {
fatal("calloc failed");
}
strcat(req->body, body);
}
void http_request_delete(http_request *req) {

View File

@@ -13,7 +13,6 @@ extern "C" {
#endif
#include <stdint.h>
#include "request.h"
typedef enum http_method {
METHOD_GET, METHOD_POST, METHOD_HEAD, METHOD_PUT,
@@ -43,13 +42,19 @@ extern "C" {
char* content;
} http_header;
typedef enum http_request_parsestatus {
PARSE_REQUESTLINE, PARSE_HEADERS, PARSE_BODY, PARSE_DONE, PARSE_FAIL
} http_request_parsestatus;
typedef struct http_request {
http_request_line *req;
http_request_parsestatus parsestatus;
http_header **headers;
uint32_t header_count;
char *body;
} http_request;
char* http_method_getstring(http_method method, char* method_other);
http_method http_method_fromstring(const char* method);

View File

@@ -1,6 +1,66 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include "../main.h"
#include "http.h"
char* parse_request(http_request *req, char *input) {
size_t line_count;
char** lines = str_splitlines(input, &line_count);
switch(req->parsestatus) {
case PARSE_REQUESTLINE:
if (line_count == 0) {
break;
}
char* requestStr = lines[0];
char methodStr[20] = {0};
char uriStr[1024] = {0};
char versionStr[16] = {0};
int count = sscanf(requestStr, "%19s%*[ \t]%1023s%*[ \t]%15s", methodStr, uriStr, versionStr);
if (count < 3) {
req->parsestatus = PARSE_FAIL;
break;
}
http_method method = http_method_fromstring(methodStr);
if (method == METHOD_INVALID) {
req->parsestatus = PARSE_FAIL;
break;
}
http_version version;
if (strcasecmp(versionStr, "HTTP/1.0") == 0) { version = HTTP10; }
if (strcasecmp(versionStr, "HTTP/1.1") == 0) { version = HTTP11; }
http_request_line *request_line = http_request_line_new(method, NULL);
request_line->version = version;
request_line->uri = calloc(strlen(uriStr)+1, sizeof(char));
if (request_line->uri == NULL) {
fatal("calloc failed");
}
strcpy(request_line->uri, uriStr);
req->req = request_line;
req->parsestatus = PARSE_HEADERS;
break;
case PARSE_HEADERS:
break;
case PARSE_BODY:
break;
case PARSE_DONE:
case PARSE_FAIL:
break;
}
for(size_t i=0; i < line_count; i++) {
free(lines[i]);
free(lines);
}
return NULL;
}

View File

@@ -12,9 +12,10 @@
extern "C" {
#endif
#include "../ut/utstring.h"
#include "http.h"
char* parse_request(http_request *req, char *input);
#ifdef __cplusplus

View File

@@ -12,16 +12,26 @@
#include <strings.h>
#include "ut/utlist.h"
#include "ut/utarray.h"
#include "main.h"
#include "socket.h"
#include "http/http.h"
#include "http/request.h"
int serverfd = 0;
char* teststr = "GET /testing/123 HTTP/1.1\r\n";
/*
*
*/
int main(int argc, char** argv) {
/*char *test = calloc(strlen(teststr)+1, sizeof(char));
strcpy(test, teststr);
http_request *req = http_request_new();
parse_request(req, test);
return 0;*/
skt_elem *connections = NULL;
serverfd = svr_create();
@@ -38,6 +48,7 @@ int main(int argc, char** argv) {
if (info != NULL) {
skt_elem* newconn = calloc(1, sizeof(skt_elem));
newconn->info = info;
newconn->current_request = http_request_new();
LL_APPEND(connections, newconn);
}
}
@@ -90,6 +101,9 @@ int main(int argc, char** argv) {
if (elem->info->closed) {
LL_DELETE(connections, elem);
skt_delete(elem->info);
if (elem->current_request != NULL) {
http_request_delete(elem->current_request);
}
free(elem);
}
}
@@ -125,3 +139,45 @@ void info(char* msg, ...) {
fputc('\n', stdout);
va_end(va);
}
char** str_splitlines(char *str, size_t *line_count) {
char **result;
*line_count = 0;
char *tmp = str;
while(*tmp) {
if (*tmp == '\n') {
(*line_count)++;
}
tmp++;
}
if (*line_count == 0) {
result = calloc(1, sizeof(char*));
result[0] = calloc(strlen(str), sizeof(char));
strcpy(result[0], str);
return result;
}
result = calloc(*line_count, sizeof(char*));
if (result == NULL) {
fatal("calloc failed");
}
size_t i=0, linelen = 0;
char *line = strtok(str, "\n");
while(line) {
linelen = strlen(line);
result[i] = calloc(linelen+1, sizeof(char));
if (result[i] == NULL) {
fatal("calloc failed");
}
strcpy(result[i], line);
if (result[i][linelen-1] == '\r') {
result[i][linelen-1] = '\0';
result[i] = realloc(result[i], linelen);
}
line = strtok(NULL, "\n");
i++;
}
return result;
}

View File

@@ -20,6 +20,8 @@ void fatal(char* msg);
void warning(char* msg, bool showPError);
void info(char* msg, ...);
char** str_splitlines(char *str, size_t *line_count);
#ifdef __cplusplus
}

View File

@@ -17,6 +17,7 @@ extern "C" {
#include <sys/socket.h>
#include <netinet/in.h>
#include <time.h>
#include "http/http.h"
#include "ut/utstring.h"
typedef struct skt_info skt_info;
@@ -36,6 +37,7 @@ extern "C" {
typedef struct skt_elem {
skt_info* info;
http_request *current_request;
struct skt_elem *next;
} skt_elem;

View File

@@ -218,7 +218,12 @@ typedef struct {
/* last we pre-define a few icd for common utarrays of ints and strings */
static void utarray_str_cpy(void *dst, const void *src) {
char **_src = (char**)src, **_dst = (char**)dst;
*_dst = (*_src == NULL) ? NULL : strdup(*_src);
if (*_src != NULL) {
*_dst = calloc(strlen(*_src)+1, sizeof(char));
if (*_dst != NULL) {
strcpy(*_dst, *_src);
}
}
}
static void utarray_str_dtor(void *elt) {
char **eltc = (char**)elt;