2025-02-04 HTTP server from scratch in CΒΆ
After getting C sockets working yesterday I decided to create an HTTP server, here is the code:
/*
*
* serv_socket.c -- This file acts as a server for my socket connections.
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <unistd.h>
#include <fcntl.h>
#define PORT 9089
#define BUFFER_SIZE 1024
int main() {
int server_socket;
struct sockaddr_in serv_in;
server_socket = socket(AF_INET, SOCK_STREAM, 0);
if (server_socket == -1) {
perror("Error [-1] creating socket");
return 1;
}
serv_in.sin_family = AF_INET;
serv_in.sin_port = htons(PORT);
serv_in.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(server_socket, (struct sockaddr *)&serv_in, sizeof(serv_in)) < 0) {
perror("Error binding socket");
close(server_socket);
return 1;
}
printf("Server listening on port %d\n", PORT);
if (listen(server_socket, 1) < 0) {
perror("Error listening on socket");
close(server_socket);
return 1;
}
int client_socket;
char client_response[255];
while (1) {
client_socket = accept(server_socket, NULL, NULL);
if (client_socket < 0) {
perror("Accept failed");
continue;
}
ssize_t recv_size = recv(client_socket, client_response, sizeof(client_response) - 1, 0);
if (recv_size > 0) {
client_response[recv_size] = '\0';
}
printf("Received request:\n%s\n", client_response);
char *method = strtok(client_response, " ");
char *path = strtok(NULL, " ");
if (method && strcmp(method, "GET") == 0) {
char *file_path = path + 1;
if (strcmp(file_path, "") == 0) {
file_path = "index.html";
}
int file = open(file_path, O_RDONLY);
ssize_t bytes_read;
char file_buffer[BUFFER_SIZE] = {0};
char http_response[BUFFER_SIZE] = {0};
if (file < 0) {
perror("Error opening file");
char *not_found_response =
"HTTP/1.1 404 Not Found\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 15\r\n"
"Connection: close\r\n"
"\r\n"
"404 Not Found";
send(client_socket, not_found_response, strlen(not_found_response), 0);
} else {
snprintf(http_response, sizeof(http_response),
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/html\r\n"
"Connection: close\r\n"
"\r\n");
send(client_socket, http_response, strlen(http_response), 0);
}
while ((bytes_read = read(file, file_buffer, sizeof(file_buffer))) > 0) {
send(client_socket, file_buffer, bytes_read, 0);
}
if (bytes_read < 0) {
perror("Error reading file");
}
close(file);
}
close(client_socket);
}
close(server_socket);
return 0;
}