From 0a3dc4a56a3583f1696d8b2b425fa23bbeb71793 Mon Sep 17 00:00:00 2001 From: 08draven Date: Wed, 20 Nov 2024 00:31:34 -0500 Subject: [PATCH] init --- .gitignore | 2 + Makefile | 2 + src/http.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 src/http.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..41783a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/serv +/vgcore.* \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f6b8c90 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +make: + gcc ./src/*.c -O3 -o ./serv \ No newline at end of file diff --git a/src/http.c b/src/http.c new file mode 100644 index 0000000..b1f34d0 --- /dev/null +++ b/src/http.c @@ -0,0 +1,152 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_MSG 1024*1024*16 +#define LISTEN_BACKLOG 50 +#define THREADS 8 +#define MAX_HEADERS 1024 + +struct header { + char *key; + char *value; +}; + +struct header_list { + size_t header_count; + struct header *header_data; + size_t storage_count; + char *storage_data; +}; + +void handle_error(char *msg) { + perror(msg); + exit(EXIT_FAILURE); +} + +struct header_list push_header(struct header_list headers, char *key, char *value) { + if (headers.header_count >= MAX_HEADERS - 1) return headers; + + int len = headers.storage_count + 1; + snprintf(&headers.storage_data[len],MAX_MSG - len,"%s",key); + len += strlen(key) + 1; + snprintf(&headers.storage_data[len],MAX_MSG - len,"%s",value); + len += strlen(value) + 1; + headers.storage_count = len; + + struct header new_header; + new_header.value = &headers.storage_data[len - strlen(value) - 1]; + new_header.key = &headers.storage_data[len - strlen(value) - strlen(key) - 2]; + headers.header_data[headers.header_count] = new_header; + headers.header_count++; + + return headers; +} + +char *parse_header(char *tmp, char *msg, struct header_list headers) { + for (int i = 0; i < headers.header_count; i++) { + struct header dat = headers.header_data[i]; + snprintf(tmp,MAX_MSG,"%s\n%s: %s",msg,dat.key,dat.value); + memcpy(msg,tmp,MAX_MSG); + } + return tmp; +} + +void* use_sock(void* cfd2) { + printf("%s\n","Request is being sent"); + int cfd = (int) cfd2; + + char *msg = malloc(MAX_MSG); + char *tmp = malloc(MAX_MSG); + char *num = malloc(MAX_MSG); + char *html = "Balls man is cool"; + + struct header_list headers; + headers.header_count = 0; + headers.storage_count = 0; + + headers.header_data = calloc(MAX_HEADERS, sizeof(struct header)); + headers.storage_data = malloc(MAX_MSG); + + memset(headers.storage_data,0,MAX_MSG); + + tmp[0] = '\0'; + + headers = push_header(headers,"Content-Type","text/html"); + snprintf(num,MAX_MSG,"%d",strlen(html)); + headers = push_header(headers,"Content-Length",num); + + parse_header(tmp, msg, headers); + + snprintf(msg, MAX_MSG, "HTTP/1.1 200 OK%s\n\n%s", tmp, html); + + printf("%s\n",msg); + + send(cfd,msg,strlen(msg),0); + close(cfd); + + free(msg); + free(tmp); + free(num); + + return (void*) 1; +} + +// credit to the man docs +int main(int argc, char *argv[]) { + int sfd, cfd, thread_num; + struct sockaddr_in my_addr, peer_addr; + socklen_t peer_addr_size; + pthread_t* thread_list; + + sfd = socket(AF_INET, SOCK_STREAM, 0); + if (sfd == -1) + handle_error("socket"); + + memset(&my_addr, 0, sizeof(struct sockaddr_in)); + + my_addr.sin_family = AF_INET; + my_addr.sin_port = htons(8000); + my_addr.sin_addr.s_addr = htonl(0x7F000001); + + if (bind(sfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_in)) == -1) + handle_error("bind"); + + if (listen(sfd, LISTEN_BACKLOG) == -1) + handle_error("listen"); + + peer_addr_size = sizeof(struct sockaddr_in); + + thread_list = calloc(THREADS,sizeof(pthread_t)); + + for (size_t i = 0; i < THREADS; i++) { + thread_list[i] = -1; + } + + thread_num = 0; + + for (;;) { + cfd = accept(sfd, (struct sockaddr *)&peer_addr, &peer_addr_size); + + if (cfd == -1) + handle_error("accept"); + + if (thread_list[thread_num] != -1) { + pthread_join(thread_list[thread_num],NULL); + + thread_list[thread_num] = -1; + } + + pthread_create(&thread_list[thread_num],NULL,use_sock,(void*)cfd); + + thread_num = (thread_num + 1) % THREADS; + + } + + free(thread_list); +}