Created
January 19, 2022 14:35
-
-
Save vinikira/179c421f8db743e05dbc1dae2c0c1a38 to your computer and use it in GitHub Desktop.
HTTP server using only system sockets in C
This file contains 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
#!/bin/sh | |
set -xe | |
cc -Wall -Werror -std=c11 -pedantic -c common.c | |
cc -Wall -Werror -std=c11 -pedantic -o main main.c common.o |
This file contains 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 "common.h" | |
void err_n_die(const char *fmt, ...) { | |
int errno_save = errno; | |
va_list ap; | |
va_start(ap, fmt); | |
vfprintf(stderr, fmt, ap); | |
fprintf(stderr, "\n"); | |
fflush(stderr); | |
if (errno_save != 0) { | |
fprintf(stderr, "(errno = %d): %s\n", errno_save, strerror(errno_save)); | |
fprintf(stderr, "\n"); | |
fflush(stderr); | |
} | |
va_end(ap); | |
exit(1); | |
} | |
char *bin2hex(const unsigned char *input, size_t len) { | |
char *result; | |
char *hexits = "0123456789ABCDEF"; | |
if (input == NULL || len <= 0) { | |
return NULL; | |
} | |
int resultlength = (len * 3) + 1; | |
result = malloc(resultlength); | |
bzero(result, resultlength); | |
for (size_t i = 0; i < len; i++) { | |
int idx = i * 3; | |
result[idx] = hexits[input[i] >> 4]; | |
result[idx + 1] = hexits[input[i] & 0x0F]; | |
result[idx + 2] = ' '; | |
} | |
return result; | |
} |
This file contains 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
#ifndef _COMMON_H_ | |
#define _COMMON_H_ | |
#include <sys/socket.h> | |
#include <sys/types.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <strings.h> | |
#include <unistd.h> | |
#include <arpa/inet.h> | |
#include <stdarg.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <sys/time.h> | |
#include <sys/ioctl.h> | |
#include <netdb.h> | |
#define SERVER_PORT 18000 | |
#define MAXLINE 4096 | |
void err_n_die(const char *fmt, ...); | |
char *bin2hex(const unsigned char *input, size_t len); | |
#endif /* _COMMON_H_ */ |
This file contains 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 "common.h" | |
#define USE_TCP 0 | |
#define CONNECTIONS_QUEUE_SIZE 10 | |
int main(void) { | |
int listenfd; | |
int connfd; | |
int n; | |
struct sockaddr_in servaddr; | |
uint8_t buff[MAXLINE + 1]; | |
uint8_t recvline[MAXLINE + 1]; | |
if ((listenfd = socket(AF_INET, SOCK_STREAM, USE_TCP)) < 0) { | |
err_n_die("socket error"); | |
} | |
bzero(&servaddr, sizeof(servaddr)); | |
servaddr.sin_family = AF_INET; | |
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); | |
servaddr.sin_port = htons(SERVER_PORT); | |
if ((bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr))) < 0) { | |
err_n_die("bind error."); | |
} | |
if ((listen(listenfd, CONNECTIONS_QUEUE_SIZE)) < 0 ) { | |
err_n_die("listen error."); | |
} | |
while (1) { | |
printf("Waiting for a connection on port %d", SERVER_PORT); | |
fflush(stdout); | |
connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); | |
memset(recvline, 0, MAXLINE); | |
while ((n = read(connfd, recvline, MAXLINE - 1)) > 0) { | |
fprintf(stdout, "\n%s\n\n%s", bin2hex(recvline, n), recvline); | |
if (recvline[n - 1] == '\n') { | |
break; | |
} | |
memset(recvline, 0, MAXLINE); | |
} | |
if (n < 0) { | |
err_n_die("read error."); | |
} | |
snprintf((char *) buff, sizeof(buff), "HTTP/1.0 200 OK\r\n\r\nHello"); | |
write(connfd, (char *) buff, strlen((char *) buff)); | |
close(connfd); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment