bunkum

an old and silly c99 web server with some fun features
Log | Files | Refs | README

commit 3f8a18907d21e9e1a91799243d0ec86d5f948bd0
parent 3576211e4e1822a07fca3d2342427229726287d3
Author: quantumish <freifeld.david@gmail.com>
Date:   Sat, 15 Apr 2023 23:01:17 -0700

Start trying to split listen() logic to a thread, attempt bugfixes

Diffstat:
Mhttp.c | 51++++++++++++++++++++++++++++++++++-----------------
Mhttp/request.c | 7++++---
Mutils/hashmap.c | 1+
Mutils/sync.c | 19+++++--------------
Autils/sync.h | 19+++++++++++++++++++
5 files changed, 63 insertions(+), 34 deletions(-)

diff --git a/http.c b/http.c @@ -21,10 +21,13 @@ #include "utils/log.h" #include "utils/time.h" #include "utils/shitvec.h" +#include "utils/sync.h" + #include "utils/compress.h" #include "http/response.h" #include "http/request.h" + response_t serve_error(enum StatusCode c) { response_t r = resp_new(c); resp_add_hdr(&r, "Content-Type", "text/html"); @@ -155,7 +158,8 @@ void* handle_conn(void* ctxt) { gettimeofday(&before, NULL); if (msgbuf[0] != 0) { request_t req = req_new(msgbuf, 1024); - + log_debug("after init %p %p", req.headers.keys, req.headers.vals); + response_t r = make_response(req); send(ns, r.content, r.sz, 0); free(r.content); @@ -188,23 +192,37 @@ int list_files_sv(shitvec_t* sv, char* base) { return 0; } +channel_t listen_chan; + +void* listen_for_conns(void* ctxt) { + int s = *(int*)ctxt; + int namelen; + struct sockaddr_in client; + log_info("Hi!"); + while (true) { + listen(s, 1); + int ns = accept(s, (struct sockaddr*)&client, (socklen_t*)&namelen); + log_info("Handling connection from %s", inet_ntoa(client.sin_addr)); + channel_push(&listen_chan, &ns); + } +} + // TODO some sort of DDOS protection idk int main() { int s = socket(AF_INET, SOCK_STREAM, 0); if (s == -1) die("socket"); + int portnum = 8080; struct sockaddr_in name; name.sin_family = AF_INET; - name.sin_port = htons(8082); + name.sin_port = htons(portnum); name.sin_addr.s_addr = htonl(INADDR_ANY); - if (bind(s, (struct sockaddr*)&name, sizeof(name)) < 0) { - name.sin_port = htons(0); - if (bind(s, (struct sockaddr*)&name, sizeof(name)) < 0) { - die("bind"); - } - } - + while(bind(s, (struct sockaddr*)&name, sizeof(name)) < 0) { + portnum += 1; + name.sin_port = htons(portnum); + } + paths = shitvec_new(MAX_PATH_LEN); path_redirs = hashmap_new(MAX_PATH_LEN, MAX_PATH_LEN); path_redirs.vark = true; @@ -216,15 +234,14 @@ int main() { getsockname(s, (struct sockaddr*)&name, (socklen_t*)&nlen); log_debug("Open on port %d.", htons(name.sin_port)); - int namelen; - char pathbuf[MAX_PATH_LEN]; - struct sockaddr_in client; - char msgbuf[512] = {0}; - while (true) { - listen(s, 1); - int ns = accept(s, (struct sockaddr*)&client, (socklen_t*)&namelen); + listen_chan = channel_new(sizeof(int)); - log_info("Handling connection from %s", inet_ntoa(client.sin_addr)); + pthread_t lthread; + pthread_create(&lthread, NULL, listen_for_conns, &s); + while (true) { + int ns = *(int*)channel_recv(&listen_chan); + log_debug("%d", ns); + pthread_t thread; pthread_create(&thread, NULL, handle_conn, &ns); } diff --git a/http/request.c b/http/request.c @@ -1,6 +1,7 @@ #include <stdio.h> #include <string.h> #include <stdint.h> +#include <stdlib.h> #include "../utils/log.h" #include "request.h" @@ -20,6 +21,8 @@ request_t req_new(char* reqbuf, size_t bufsize) { request_t req; req.buf = reqbuf; req.bufsize = bufsize; + req.headers = hashmap_new(MAX_HEADER_NAME, MAX_HEADER_VALUE); + req.headers.vark = true; return req; } @@ -61,9 +64,7 @@ int req_parse(request_t* req) { int matched = sscanf(req->buf, "%s %s HTTP/%f\r\n", (char*)method, (char*)req->path, &req->ver); if (matched < 3 || matched == EOF) return -1; req->method = method_enum((char*)method); - - req->headers = hashmap_new(MAX_HEADER_NAME, MAX_HEADER_VALUE); - req->headers.vark = true; + // FIXME if start is null this causes problems char* start = memchr(req->buf, '\n', MAX_HEADER_NAME+MAX_HEADER_VALUE)+1; while (start+MAX_HEADER_NAME+MAX_HEADER_VALUE < req->buf+req->bufsize) { diff --git a/utils/hashmap.c b/utils/hashmap.c @@ -41,6 +41,7 @@ hashmap_t hashmap_new(size_t ksize, size_t vsize) { // Keys and vals are in different arrays so unnecessary things aren't in cache h.keys = calloc(HASHMAP_INIT_SIZE, ksize); h.vals = malloc(vsize * HASHMAP_INIT_SIZE); + log_debug("in init %p %p", h.keys, h.vals); h.k_sz = ksize; h.v_sz = vsize; h.len = HASHMAP_INIT_SIZE; diff --git a/utils/sync.c b/utils/sync.c @@ -1,16 +1,6 @@ - -#include <pthread.h> -#include "shitvec.h" - - -typedef struct channel { - pthread_mutex_t mutex; - shitvec_t queue; - size_t msg_sz; - size_t sz; -} channel_t; - +#include "log.h" +#include "sync.h" channel_t channel_new(size_t msg_sz) { channel_t out; @@ -18,6 +8,7 @@ channel_t channel_new(size_t msg_sz) { pthread_mutex_init(&out.mutex, NULL); out.queue = shitvec_new(msg_sz); out.sz = 0; + return out; } void channel_push(channel_t* chan, void* msg) { @@ -38,6 +29,6 @@ void* channel_pop(channel_t* chan) { } void* channel_recv(channel_t * chan) { - while (__atomic_load_n(&chan->sz, __ATOMIC_RELAXED) == 0); - return channel_pop(chan); + while(__atomic_load_n(&chan->sz, __ATOMIC_RELAXED) == 0); + return channel_pop(chan); } diff --git a/utils/sync.h b/utils/sync.h @@ -0,0 +1,19 @@ +#ifndef UTIL_SYNC_H +#define UTIL_SYNC_H + +#include <pthread.h> +#include "shitvec.h" + +typedef struct channel { + pthread_mutex_t mutex; + shitvec_t queue; + size_t msg_sz; + size_t sz; +} channel_t; + +channel_t channel_new(size_t msg_sz); +void channel_push(channel_t* chan, void* msg); +void* channel_pop(channel_t* chan); +void* channel_recv(channel_t * chan); + +#endif