Last active
August 29, 2024 18:24
-
-
Save Akanoa/d85e9ca157becf74e61a48bdc32f2bf6 to your computer and use it in GitHub Desktop.
Mini serveur HHTP statique
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <errno.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/socket.h> | |
#include <netinet/in.h> | |
#include <unistd.h> | |
const unsigned short PORT = 8080; | |
int running = 1; | |
static void signal_int_handler() { | |
printf("Exiting\n"); | |
running = 0; | |
} | |
int response_to_client(const int socket_fd) { | |
// Wait for client message | |
char buf[1024] = {0}; | |
const int read_size = read(socket_fd,&buf, sizeof(buf)); | |
if (read_size == -1) { | |
printf("Unable to read socket\n"); | |
return -1; | |
} | |
// Write response | |
const char msg[] = "HTTP/1.1 200 OK\r\n" | |
"Content-Type: text/plain\r\n" | |
"Content-Length: 2\r\n\r\n" | |
"OK\r\n"; | |
while (1) { | |
const int write_response = write(socket_fd, msg, strlen(msg)); | |
if (write_response == -1) { | |
if (errno == EINTR) { | |
continue; | |
} | |
return -1; | |
} | |
break; | |
} | |
return 0; | |
} | |
int main(void) { | |
// Socket file descriptor creation | |
const int socket_fd = socket(AF_INET, SOCK_STREAM, 0); | |
if (socket_fd == -1) { | |
fprintf(stderr,"Unable to create socket file descriptor"); | |
exit(1); | |
} | |
const int reuse = 1; | |
const int reuse_addr_response = setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)); | |
if (reuse_addr_response == -1) { | |
fprintf(stderr, "Unable to set SO_REUSEADDR to socket"); | |
exit(1); | |
} | |
// Socket struct | |
struct sockaddr_in server_address, client_address; | |
// Fill with zeros the structure | |
bzero(&server_address, sizeof(server_address)); | |
// Define socket characteristics | |
server_address.sin_family = AF_INET; | |
server_address.sin_addr.s_addr = htonl(INADDR_ANY); | |
server_address.sin_port = htons(PORT); | |
// Bind socket to structure | |
const int bind_response = bind(socket_fd, (struct sockaddr *)&server_address, sizeof(server_address)); | |
if (bind_response == -1) { | |
// fprintf(stderr, "ERRNO : %d", errno); | |
// fprintf(stderr, "Unable to bind the socket to file descriptor"); | |
exit(1); | |
} | |
// Listen for connections | |
const int listen_response = listen(socket_fd, 5); | |
if (listen_response != 0) { | |
fprintf(stderr, "Unable to listen to port %d", PORT); | |
exit(1); | |
} | |
signal(SIGINT, signal_int_handler); | |
// Accept for connections | |
while (running) { | |
unsigned int client_socket_len = sizeof(client_address); | |
const int connection_fd = accept(socket_fd, (struct sockaddr*)&client_address, &client_socket_len); | |
if (connection_fd == -1) { | |
fprintf(stderr, "Unable to accept incoming connection"); | |
} | |
if(response_to_client(connection_fd) == -1) { | |
fprintf(stderr, "Unable to write response"); | |
} | |
close(connection_fd); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment