This commit is contained in:
biglyderv 2024-11-20 00:31:34 -05:00
commit 0a3dc4a56a
3 changed files with 156 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
/serv
/vgcore.*

2
Makefile Normal file
View file

@ -0,0 +1,2 @@
make:
gcc ./src/*.c -O3 -o ./serv

152
src/http.c Normal file
View file

@ -0,0 +1,152 @@
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <pthread.h>
#include <stddef.h>
#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);
}