Add http server

This commit is contained in:
Rasmus Rasmussen 2025-03-10 21:23:34 +01:00
parent 3d63b6ef4b
commit 29bbb28f41
7 changed files with 216 additions and 4 deletions

BIN
WebServer

Binary file not shown.

16
include/ipaddress.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef IPADDRESS_H
#define IPADDRESS_H
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define MAX_LINE_LENGTH (1024)
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
int extract_ip_address_from_header(char *line, char *address);
char *get_ip_address(FILE *f);
#endif

13
include/server.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef SERVER_H
#define SERVER_H
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
#include <stdio.h>
void send_response(FILE *f, char *html);
int open_connection(int port);
void accept_client(int sock, char *key);
void send_only(int port, char *key);
#endif

View File

@ -1,7 +1,7 @@
# Makefile for hello.c
CC = gcc # C compiler
CFLAGS = -O2 # Compiler flags (optimization level)
CFLAGS = -O2 # Compiler flags (optimization level)
SRC_DIR = src
BUILD_DIR = build

60
src/ipaddress.c Normal file
View File

@ -0,0 +1,60 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "../include/ipaddress.h"
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
int extract_ip_address_from_header(char *line, char *address) {
int found = 0;
char *ptr;
char *name;
char *value;
name = strndup(line, MAX_LINE_LENGTH);
ptr = index(name, (int)':');
if (ptr == NULL) {
return 0;
}
// end the string at the colon
*ptr = '\0';
// get the value part of the header field
ptr = index(line, (int) ':');
value = strndup(ptr + 2, MAX_LINE_LENGTH);
// most ugly way to remove \r\n from the end of the string
value[strlen(value)-2] = '\0';
if (strncmp(name, "X-Forwarded-For", MAX_LINE_LENGTH) == 0) {
found = 1;
strncpy(address, value, MAX_LINE_LENGTH);
}
free(name);
free(value);
return found;
}
char *get_ip_address(FILE *f) {
int address_found = 0;
char *res;
char *ip_address = malloc (sizeof (char) * MAX_LINE_LENGTH);
char header_line[MAX_LINE_LENGTH];
do {
res = fgets(header_line, MAX_LINE_LENGTH, f);
if (res != NULL) {
printf("%s", res);
if (!address_found) {
address_found = extract_ip_address_from_header(res, ip_address);
}
}
} while (res != NULL && strcmp(header_line, "\r\n") != 0);
return ip_address;
}

View File

@ -1,7 +1,27 @@
#include <stdio.h>
#include <strings.h>
#include <stdlib.h>
#include "../include/fileReader.h"
#include "../include/server.h"
#include "../include/ipaddress.h"
int main() {
char *file = ReadHTML("/home/skingging/Documents/Projects/C/C-Webserver/HTML/index.html");
printf(file);
int main(int argc, char *argv[]) {
if(argc <= 1) {
printf("Please provide options. \n");
return 0;
}
char *file = NULL;
if(strcasecmp(argv[0], "cache")) {
file = ReadHTML("/home/skingging/Documents/Projects/C/C-Webserver/HTML/index.html");
}
int port = 3090;
send_only(port, "address");
exit(EXIT_SUCCESS);
return 0;
}

103
src/server.c Normal file
View File

@ -0,0 +1,103 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include "../include/ipaddress.h"
#include "../include/server.h"
// This code has been borrowed from this github repo https://github.com/wasmerio/c-http-server and modified by me.
void send_response(FILE *f, char *html)
{
fprintf(f, "HTTP/1.1 200 OK\r\n");
fprintf(f, "Content-Type: application/html\r\n");
fprintf(f, "\r\n");
fprintf(f, "%s", html);
}
int open_connection(int port)
{
int sock;
struct sockaddr_in addr_in;
printf("simpleserver::Creating socket: (%d, %d, 0)\n", AF_INET, SOCK_STREAM);
sock = socket(AF_INET, SOCK_STREAM, 0);
printf("simpleserver::Socket created (%d)\n", sock);
if (sock == -1)
{
printf("Failed to create socket (%d)\n", errno);
exit(EXIT_FAILURE);
}
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(port);
addr_in.sin_addr.s_addr = INADDR_ANY;
printf("simpleserver::bind (%d, (%d, %d, %d), %lu)\n", sock, addr_in.sin_family, addr_in.sin_port, addr_in.sin_addr.s_addr, sizeof(struct sockaddr_in));
int lol = bind(sock, (struct sockaddr *)&addr_in, sizeof(struct sockaddr_in));
printf("simpleserver::listen(%d, 8)\n", sock);
if (listen(sock, 8) == -1)
{
printf("Failed to get socket to listen (%d)\n", errno);
exit(EXIT_FAILURE);
}
return sock;
}
void accept_client(int sock, char *key)
{
struct sockaddr_in client_addr;
socklen_t clientaddr_len;
FILE *f;
printf("simpleserver::accept(%d)\n", sock);
int client_sock = accept(sock, (struct sockaddr *)&client_addr, &clientaddr_len);
printf("simpleserver::accepted (%d)\n", client_sock);
if (client_sock == -1)
{
printf("Failed to accept connection (%d)\n", errno);
exit(EXIT_FAILURE);
}
printf("simpleserver::fdopen(%d)\n", client_sock);
f = fdopen(client_sock, "w+");
if (f == NULL){
printf("simpleserver::Error during fdopen\n");
}
printf("simpleserver::send_response(%s)\n", key);
send_response(f, "<h1>Hello</h1>");
printf("simpleserver::fclose()\n");
fclose(f);
printf("simpleserver::fflush\n");
// stdout needs to be flushed in order for heroku to read the logs
fflush(stdout);
printf("simpleserver::endfflush\n");
}
void send_only(int port, char *key)
{
int sock = open_connection(port);
while (1)
{
accept_client(sock, key);
}
close(sock);
}