aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspl3g <spleefer6@yandex.ru>2025-03-18 11:36:25 +0300
committerspl3g <spleefer6@yandex.ru>2025-03-18 11:36:25 +0300
commitefabb034e09679660c6b1e82ec55c4f39d5cfb1d (patch)
treecf699fef6bc7c25b7c0813849096491562d3e01e
parent23b669976797eb5f0330462b0bb723adea31c88a (diff)
Add request context
-rw-r--r--lib/http.c33
-rw-r--r--lib/http.h31
2 files changed, 54 insertions, 10 deletions
diff --git a/lib/http.c b/lib/http.c
index 53eae81..bf75021 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -77,6 +77,27 @@ int get_in_port(struct sockaddr *sa) {
return (((struct sockaddr_in6*)sa)->sin6_port);
}
+void set_context_value(arena *arena, context *ctx, context_value kv) {
+ for (size_t i = 0; i < ctx->len; i++) {
+ context_value *ctx_val = (ctx->data + i);
+ if (cs_eq(kv.key, ctx_val->key)) {
+ ctx_val->val = kv.val;
+ return;
+ }
+ }
+ arena_da_append(arena, ctx, kv);
+}
+
+void *get_context_value(context *ctx, const_string key) {
+ for (size_t i = 0; i < ctx->len; i++) {
+ context_value *ctx_val = (ctx->data + i);
+ if (cs_eq(key, ctx_val->key)) {
+ return ctx_val->val;
+ }
+ }
+ return NULL;
+}
+
int init_server(arena *arena, struct server *serv, char *addr, char *port) {
// serv initialization
struct addrinfo hints, *res;
@@ -189,14 +210,14 @@ int chop_query(arena *arena, const_string *path, query_da *queries) {
}
do {
- query query = {0};
+ KV query = {0};
const_string key;
if (!cs_try_chop_delim(&query_str, '=', &key)) {
return -1;
}
query.key = key;
- query.val = query_str;
+ query.value = query_str;
arena_da_append(arena, queries, query);
query_count++;
} while (cs_try_chop_delim(&queries_str, '&', &query_str));
@@ -255,7 +276,7 @@ int parse_request(arena *arena, size_t inc_fd, struct request *req) {
const_string header_str = chop_request(&req_str, '\r', &parse_err);
req_str.data += 1;
- struct header header;
+ KV header;
header.key = chop_request(&header_str, ':', &parse_err);
header_str.data++;
header.value = header_str;
@@ -296,6 +317,12 @@ void process_request(struct server *serv, size_t inc_fd) {
resp.code = parse_res;
}
+ context req_context = {0};
+ set_context_value(&req_arena, &req_context, (context_value){CS("arena"), &req_arena});
+ for (size_t i = 0; i < serv->global_ctx.len; i++) {
+ set_context_value(&req_arena, &req_context, *(serv->global_ctx.data + i));
+ }
+
if (!resp.code) {
for (size_t i = 0; i < serv->handlers.len; i++) {
struct handler handler = serv->handlers.data[i];
diff --git a/lib/http.h b/lib/http.h
index b3c8e1b..883054b 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -19,14 +19,13 @@
#include "arena_strings.h"
#include "arena.h"
-struct header {
+typedef struct {
const_string key;
const_string value;
-};
-
+} KV;
typedef struct {
- struct header *data;
+ KV *data;
size_t len;
size_t cap;
} header_da;
@@ -37,7 +36,7 @@ typedef struct {
} query;
typedef struct {
- query *data;
+ KV *data;
size_t len;
size_t cap;
} query_da;
@@ -57,7 +56,18 @@ struct response {
const_string string;
};
-typedef void (*handler_func)(struct request, struct response *resp);
+typedef struct {
+ const_string key;
+ void *val;
+} context_value;
+
+typedef struct {
+ context_value *data;
+ size_t len;
+ size_t cap;
+} context;
+
+typedef void (*handler_func)(context*, struct request, struct response *resp);
struct handler {
const_string method;
@@ -72,10 +82,11 @@ typedef struct {
} handler_da;
struct server {
- arena *arena;
int sockfd;
struct sockaddr *addr;
+ arena *arena;
handler_da handlers;
+ context global_ctx;
};
typedef enum {
@@ -114,6 +125,12 @@ const_string get_response_string(response_code code);
void *get_in_addr(struct sockaddr *sa);
int get_in_port(struct sockaddr *sa);
+void set_context_value(arena *arena, context *ctx, context_value kv);
+void *get_context_value(context *ctx, const_string key);
+
+void resp_set_code(struct response* resp, response_code code);
+void resp_set_json(arena *arena, struct response* resp, const_string json);
+
int init_server(arena *arena, struct server *serv, char *addr, char *port);
int listen_and_serve(struct server *serv);