mirror of
https://github.com/sigmasternchen/CFloor
synced 2025-03-15 04:18:55 +00:00
headers module is done
This commit is contained in:
parent
8ededfc290
commit
3e1c9fff18
4 changed files with 153 additions and 5 deletions
9
Makefile
9
Makefile
|
@ -7,22 +7,23 @@ BIN_NAME = cfloor
|
|||
|
||||
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 $@ $^
|
||||
|
||||
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 $@ $^
|
||||
|
||||
valgrind: CFLAGS += -static -g
|
||||
valgrind: clean 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/test.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 src/headers.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/logging.o: src/logging.h
|
||||
obj/signals.o: src/signals.h
|
||||
obj/headers.o: src/headers.h
|
||||
|
||||
obj/%.o: src/%.c obj
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
|
120
src/headers.c
120
src/headers.c
|
@ -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);
|
||||
}
|
|
@ -1,6 +1,9 @@
|
|||
#ifndef HEADERS_H
|
||||
#define HEADERS_H
|
||||
|
||||
#define HEADERS_PARSE_ERROR (-1)
|
||||
#define HEADERS_ALLOC_ERROR (-2)
|
||||
|
||||
struct header {
|
||||
char* key;
|
||||
char* value;
|
||||
|
@ -11,4 +14,9 @@ struct 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
|
||||
|
|
21
src/test.c
21
src/test.c
|
@ -13,6 +13,7 @@
|
|||
#include "linked.h"
|
||||
#include "logging.h"
|
||||
#include "signals.h"
|
||||
#include "headers.h"
|
||||
|
||||
bool global = true;
|
||||
bool overall = true;
|
||||
|
@ -173,7 +174,24 @@ void testTimers() {
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -202,6 +220,7 @@ int main(int argc, char** argv) {
|
|||
test("linked lists", &testLinkedList);
|
||||
test("logging", &testLogging);
|
||||
test("signals", &testTimers);
|
||||
test("headers", &testHeaders);
|
||||
|
||||
|
||||
printf("\nOverall: %s\n", overall ? "OK" : "FAILED");
|
||||
|
|
Loading…
Reference in a new issue