headers module is done

This commit is contained in:
overflowerror 2019-03-04 21:53:57 +01:00
parent 8ededfc290
commit 3e1c9fff18
4 changed files with 153 additions and 5 deletions

View file

@ -7,22 +7,23 @@ BIN_NAME = cfloor
all: $(BIN_NAME) all: $(BIN_NAME)
$(BIN_NAME): obj/main.o obj/networking.o obj/linked.o obj/logging.o obj/signals.o $(BIN_NAME): obj/main.o obj/networking.o obj/linked.o obj/logging.o obj/signals.o obj/headers.o
$(LD) $(LDFLAGS) -o $@ $^ $(LD) $(LDFLAGS) -o $@ $^
test: obj/test.o obj/networking.o obj/linked.o obj/logging.o obj/signals.o test: obj/test.o obj/networking.o obj/linked.o obj/logging.o obj/signals.o obj/headers.o
$(LD) $(LDFLAGS) -o $@ $^ $(LD) $(LDFLAGS) -o $@ $^
valgrind: CFLAGS += -static -g valgrind: CFLAGS += -static -g
valgrind: clean test valgrind: clean test
valgrind --leak-check=yes ./test valgrind --leak-check=yes ./test
obj/main.o: src/networking.h src/linked.h src/logging.h src/signals.h src/misc.h obj/main.o: src/networking.h src/linked.h src/logging.h src/signals.h src/misc.h src/headers.h
obj/test.o: src/networking.h src/linked.h src/logging.h src/signals.h src/misc.h obj/test.o: src/networking.h src/linked.h src/logging.h src/signals.h src/misc.h src/headers.h
obj/networking.o: src/networking.h src/headers.h src/linked.h src/logging.h src/signals.h obj/networking.o: src/networking.h src/headers.h src/linked.h src/logging.h src/signals.h
obj/linked.o: src/linked.h obj/linked.o: src/linked.h
obj/logging.o: src/logging.h obj/logging.o: src/logging.h
obj/signals.o: src/signals.h obj/signals.o: src/signals.h
obj/headers.o: src/headers.h
obj/%.o: src/%.c obj obj/%.o: src/%.c obj
$(CC) $(CFLAGS) -c -o $@ $< $(CC) $(CFLAGS) -c -o $@ $<

View file

@ -0,0 +1,120 @@
#include <stdlib.h>
#include <string.h>
#include "headers.h"
int headers_find(struct headers* headers, const char* key) {
for (int i = 0; i < headers->number; i++) {
if (strcmp(headers->headers[i].key, key) == 0)
return i;
}
return -1;
}
const char* headers_get(struct headers* headers, const char* key) {
int tmp = headers_find(headers, key);
if (tmp < 0)
return NULL;
return headers->headers[tmp].value;
}
int headers_mod(struct headers* headers, char* key, char* value) {
int index = headers_find(headers, key);
if (index < 0) {
struct header* tmp = realloc(headers->headers, (headers->number + 1) * sizeof(struct header));
if (tmp == NULL) {
// we don't need to clean up this connection gets dropped anyway
return HEADERS_ALLOC_ERROR;
}
headers->headers = tmp;
index = headers->number++;
}
headers->headers[index] = (struct header) {
.key = key,
.value = value
};
return index;
}
int headers_parse(struct headers* headers, const char* _currentHeader, size_t length) {
char* key = NULL;
char* value = NULL;
char* currentHeader = malloc(length);
if (currentHeader == NULL)
return HEADERS_ALLOC_ERROR;
memcpy(currentHeader, _currentHeader, length);
// string terminator not needed
char* keyTmp = currentHeader;
char* valueTmp = NULL;
for(int i = 0; i < length; i++) {
if (currentHeader[i] == ':') {
keyTmp[i] = '\0';
valueTmp = currentHeader + i + 1;
length -= i + 1;
break;
}
}
if (length < 0) {
free(currentHeader);
return HEADERS_PARSE_ERROR;
}
if (valueTmp == NULL) {
free(currentHeader);
return HEADERS_PARSE_ERROR;
}
key = malloc(strlen(keyTmp) + 1);
if (key == NULL) {
free(currentHeader);
return HEADERS_ALLOC_ERROR;
}
value = malloc(length + 1);
if (value == NULL) {
free(currentHeader);
return HEADERS_ALLOC_ERROR;
}
strcpy(key, keyTmp);
memcpy(value, valueTmp, length);
value[length] = '\0';
free(currentHeader);
int shift = 0;
for(int i = 0; i < strlen(value); i++) {
if (value[i] != ' ') {
shift = i;
break;
}
}
if (shift > 0) {
memmove(value, value + shift, strlen(value) - shift + 1);
}
for(int i = strlen(value) - 1; i >= 0; i--) {
if (value[i] != ' ') {
value[i + 1] = '\0';
break;
}
}
return headers_mod(headers, key, value);
}
void headers_free(struct headers* headers) {
for (int i = 0; i < headers->number; i++) {
if (headers->headers[i].key != NULL)
free(headers->headers[i].key);
if (headers->headers[i].value != NULL)
free(headers->headers[i].value);
}
if (headers->headers != NULL)
free(headers->headers);
}

View file

@ -1,6 +1,9 @@
#ifndef HEADERS_H #ifndef HEADERS_H
#define HEADERS_H #define HEADERS_H
#define HEADERS_PARSE_ERROR (-1)
#define HEADERS_ALLOC_ERROR (-2)
struct header { struct header {
char* key; char* key;
char* value; char* value;
@ -11,4 +14,9 @@ struct headers {
struct header* headers; struct header* headers;
}; };
const char* headers_get(struct headers* headers, const char* key);
int headers_mod(struct headers* headers, char* key, char* value);
int headers_parse(struct headers* headers, const char* currentHeader, size_t length);
void headers_free(struct headers* headers);
#endif #endif

View file

@ -13,6 +13,7 @@
#include "linked.h" #include "linked.h"
#include "logging.h" #include "logging.h"
#include "signals.h" #include "signals.h"
#include "headers.h"
bool global = true; bool global = true;
bool overall = true; bool overall = true;
@ -173,7 +174,24 @@ void testTimers() {
checkInt(counter, 100, "interval count"); checkInt(counter, 100, "interval count");
} }
handler_t handlerGetter(struct metaData metaData, const char* host) { void testHeaders() {
struct headers headers = (struct headers) {
.number = 0
};
char* tmp = "test: Hello World ";
checkInt(headers_parse(&headers, tmp, strlen(tmp)), 0, "parse ok");
tmp = "blablabla";
checkInt(headers_parse(&headers, tmp, strlen(tmp)), HEADERS_PARSE_ERROR, "parse error");
tmp = "test2: Hello World2";
checkInt(headers_parse(&headers, tmp, strlen(tmp)), 1, "parse ok");
checkString(headers_get(&headers, "test"), "Hello World", "value check");
headers_free(&headers);
}
handler_t handlerGetter(struct metaData metaData, const char* host, struct bind* bind) {
return NULL; return NULL;
} }
@ -202,6 +220,7 @@ int main(int argc, char** argv) {
test("linked lists", &testLinkedList); test("linked lists", &testLinkedList);
test("logging", &testLogging); test("logging", &testLogging);
test("signals", &testTimers); test("signals", &testTimers);
test("headers", &testHeaders);
printf("\nOverall: %s\n", overall ? "OK" : "FAILED"); printf("\nOverall: %s\n", overall ? "OK" : "FAILED");