Work on request header parsing
This commit is contained in:
BIN
dist/Debug/GNU-Linux-x86/khttp
vendored
BIN
dist/Debug/GNU-Linux-x86/khttp
vendored
Binary file not shown.
@@ -13,6 +13,8 @@
|
|||||||
<gdb_interceptlist>
|
<gdb_interceptlist>
|
||||||
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
<gdbinterceptoptions gdb_all="false" gdb_unhandled="true" gdb_unexpected="true"/>
|
||||||
</gdb_interceptlist>
|
</gdb_interceptlist>
|
||||||
|
<gdb_signals>
|
||||||
|
</gdb_signals>
|
||||||
<gdb_options>
|
<gdb_options>
|
||||||
<DebugOptions>
|
<DebugOptions>
|
||||||
</DebugOptions>
|
</DebugOptions>
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
#include "../main.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* METHOD_GET, METHOD_POST, METHOD_HEAD, METHOD_PUT,
|
* METHOD_GET, METHOD_POST, METHOD_HEAD, METHOD_PUT,
|
||||||
@@ -32,7 +33,7 @@ http_method http_method_fromstring(const char* method) {
|
|||||||
METHOD_CONNECT};
|
METHOD_CONNECT};
|
||||||
|
|
||||||
size_t count = sizeof(methods) / sizeof(http_method);
|
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) {
|
if (strcmp(http_method_getstring(methods[i],NULL), method) == 0) {
|
||||||
return methods[i];
|
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 *http_request_line_new(http_method method, const char* other) {
|
||||||
http_request_line *req = calloc(1, sizeof(http_request_line));
|
http_request_line *req = calloc(1, sizeof(http_request_line));
|
||||||
|
if (req == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
req->method = method;
|
req->method = method;
|
||||||
if (req->method == METHOD_OTHER) {
|
if (req->method == METHOD_OTHER) {
|
||||||
req->method_other = calloc(strlen(other)+1, sizeof(char));
|
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 *http_response_line_new(uint16_t code) {
|
||||||
http_response_line *resp = calloc(1, sizeof(http_response_line));
|
http_response_line *resp = calloc(1, sizeof(http_response_line));
|
||||||
|
if (resp == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
resp->code = code;
|
resp->code = code;
|
||||||
resp->version = HTTP11;
|
resp->version = HTTP11;
|
||||||
return resp;
|
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 *http_header_new(const char* name) {
|
||||||
http_header *header = calloc(1, sizeof(http_header));
|
http_header *header = calloc(1, sizeof(http_header));
|
||||||
|
if (header == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
header->name = calloc(strlen(name)+1, sizeof(char));
|
header->name = calloc(strlen(name)+1, sizeof(char));
|
||||||
strcpy(header->name, name);
|
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) {
|
void http_header_append_content(http_header *header, const char* content) {
|
||||||
if (header->content == NULL) {
|
if (header->content == NULL) {
|
||||||
header->content = calloc(strlen(content)+1, sizeof(char));
|
header->content = calloc(strlen(content)+1, sizeof(char));
|
||||||
|
if (header->content == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
strcpy(header->content, content);
|
strcpy(header->content, content);
|
||||||
} else {
|
} else {
|
||||||
uint32_t newlen = strlen(header->content) + strlen(content) + 1;
|
uint32_t newlen = strlen(header->content) + strlen(content) + 1;
|
||||||
header->content = realloc(header->content, newlen);
|
header->content = realloc(header->content, newlen);
|
||||||
|
if (header->content == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
strcat(header->content, content);
|
strcat(header->content, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,13 +156,20 @@ void http_header_delete(http_header *header) {
|
|||||||
|
|
||||||
http_request *http_request_new() {
|
http_request *http_request_new() {
|
||||||
http_request *req = calloc(1, sizeof(http_request));
|
http_request *req = calloc(1, sizeof(http_request));
|
||||||
|
if (req == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
req->header_count = 0;
|
req->header_count = 0;
|
||||||
req->body = NULL;
|
req->body = NULL;
|
||||||
|
req->parsestatus = PARSE_REQUESTLINE;
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
void http_request_add_header(http_request *req, http_header *header) {
|
void http_request_add_header(http_request *req, http_header *header) {
|
||||||
req->header_count++;
|
req->header_count++;
|
||||||
req->headers = realloc(req->headers, req->header_count * sizeof(http_header*));
|
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;
|
req->headers[req->header_count-1] = header;
|
||||||
}
|
}
|
||||||
void http_request_apppend_body(http_request *req, const char* body) {
|
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;
|
bodylen += strlen(body) + 1;
|
||||||
req->body = realloc(req->body, bodylen * sizeof(char));
|
req->body = realloc(req->body, bodylen * sizeof(char));
|
||||||
|
if (req->body == NULL) {
|
||||||
|
fatal("calloc failed");
|
||||||
|
}
|
||||||
strcat(req->body, body);
|
strcat(req->body, body);
|
||||||
}
|
}
|
||||||
void http_request_delete(http_request *req) {
|
void http_request_delete(http_request *req) {
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "request.h"
|
|
||||||
|
|
||||||
typedef enum http_method {
|
typedef enum http_method {
|
||||||
METHOD_GET, METHOD_POST, METHOD_HEAD, METHOD_PUT,
|
METHOD_GET, METHOD_POST, METHOD_HEAD, METHOD_PUT,
|
||||||
@@ -43,13 +42,19 @@ extern "C" {
|
|||||||
char* content;
|
char* content;
|
||||||
} http_header;
|
} http_header;
|
||||||
|
|
||||||
|
typedef enum http_request_parsestatus {
|
||||||
|
PARSE_REQUESTLINE, PARSE_HEADERS, PARSE_BODY, PARSE_DONE, PARSE_FAIL
|
||||||
|
} http_request_parsestatus;
|
||||||
|
|
||||||
typedef struct http_request {
|
typedef struct http_request {
|
||||||
http_request_line *req;
|
http_request_line *req;
|
||||||
|
http_request_parsestatus parsestatus;
|
||||||
http_header **headers;
|
http_header **headers;
|
||||||
uint32_t header_count;
|
uint32_t header_count;
|
||||||
char *body;
|
char *body;
|
||||||
} http_request;
|
} http_request;
|
||||||
|
|
||||||
|
|
||||||
char* http_method_getstring(http_method method, char* method_other);
|
char* http_method_getstring(http_method method, char* method_other);
|
||||||
http_method http_method_fromstring(const char* method);
|
http_method http_method_fromstring(const char* method);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,66 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <strings.h>
|
||||||
|
#include "../main.h"
|
||||||
#include "http.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;
|
||||||
|
}
|
||||||
@@ -12,9 +12,10 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "../ut/utstring.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
|
||||||
|
char* parse_request(http_request *req, char *input);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
56
src/main.c
56
src/main.c
@@ -12,16 +12,26 @@
|
|||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
|
||||||
#include "ut/utlist.h"
|
#include "ut/utlist.h"
|
||||||
|
#include "ut/utarray.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "socket.h"
|
#include "socket.h"
|
||||||
|
#include "http/http.h"
|
||||||
|
#include "http/request.h"
|
||||||
|
|
||||||
int serverfd = 0;
|
int serverfd = 0;
|
||||||
|
char* teststr = "GET /testing/123 HTTP/1.1\r\n";
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
int main(int argc, char** argv) {
|
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;
|
skt_elem *connections = NULL;
|
||||||
|
|
||||||
serverfd = svr_create();
|
serverfd = svr_create();
|
||||||
@@ -38,6 +48,7 @@ int main(int argc, char** argv) {
|
|||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
skt_elem* newconn = calloc(1, sizeof(skt_elem));
|
skt_elem* newconn = calloc(1, sizeof(skt_elem));
|
||||||
newconn->info = info;
|
newconn->info = info;
|
||||||
|
newconn->current_request = http_request_new();
|
||||||
LL_APPEND(connections, newconn);
|
LL_APPEND(connections, newconn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -90,6 +101,9 @@ int main(int argc, char** argv) {
|
|||||||
if (elem->info->closed) {
|
if (elem->info->closed) {
|
||||||
LL_DELETE(connections, elem);
|
LL_DELETE(connections, elem);
|
||||||
skt_delete(elem->info);
|
skt_delete(elem->info);
|
||||||
|
if (elem->current_request != NULL) {
|
||||||
|
http_request_delete(elem->current_request);
|
||||||
|
}
|
||||||
free(elem);
|
free(elem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -125,3 +139,45 @@ void info(char* msg, ...) {
|
|||||||
fputc('\n', stdout);
|
fputc('\n', stdout);
|
||||||
va_end(va);
|
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;
|
||||||
|
}
|
||||||
@@ -20,6 +20,8 @@ void fatal(char* msg);
|
|||||||
void warning(char* msg, bool showPError);
|
void warning(char* msg, bool showPError);
|
||||||
void info(char* msg, ...);
|
void info(char* msg, ...);
|
||||||
|
|
||||||
|
char** str_splitlines(char *str, size_t *line_count);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ extern "C" {
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "http/http.h"
|
||||||
#include "ut/utstring.h"
|
#include "ut/utstring.h"
|
||||||
|
|
||||||
typedef struct skt_info skt_info;
|
typedef struct skt_info skt_info;
|
||||||
@@ -36,6 +37,7 @@ extern "C" {
|
|||||||
|
|
||||||
typedef struct skt_elem {
|
typedef struct skt_elem {
|
||||||
skt_info* info;
|
skt_info* info;
|
||||||
|
http_request *current_request;
|
||||||
struct skt_elem *next;
|
struct skt_elem *next;
|
||||||
} skt_elem;
|
} skt_elem;
|
||||||
|
|
||||||
|
|||||||
@@ -218,7 +218,12 @@ typedef struct {
|
|||||||
/* last we pre-define a few icd for common utarrays of ints and strings */
|
/* last we pre-define a few icd for common utarrays of ints and strings */
|
||||||
static void utarray_str_cpy(void *dst, const void *src) {
|
static void utarray_str_cpy(void *dst, const void *src) {
|
||||||
char **_src = (char**)src, **_dst = (char**)dst;
|
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) {
|
static void utarray_str_dtor(void *elt) {
|
||||||
char **eltc = (char**)elt;
|
char **eltc = (char**)elt;
|
||||||
|
|||||||
Reference in New Issue
Block a user