aboutsummaryrefslogtreecommitdiffstats
path: root/server.c
blob: 7bc991a392964f04a11ca4d5ac20a4b4deac110e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <asm-generic/socket.h>
#include <errno.h>
#include <netdb.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#include <unistd.h>

int shsd_sendfile(int in_fd, FILE *ou_fd, struct stat *s)
{
	int stat_result = fstat(fileno(ou_fd), s);
	if (stat_result != 0) {
		perror("fstat");
		return -1;
	}
	sendfile(in_fd, fileno(ou_fd), NULL, s->st_size);

	return 0;
}

int main(int argc, char **argv)
{
	struct addrinfo hints, *res, *servinfo;
	struct sockaddr_storage their_addr;
	socklen_t addr_size;
	int sockfd, new_fd;
	int yes = 1;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET; // use IPv4 or IPv6, whichever
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = AI_PASSIVE; // fill in my IP for me
	getaddrinfo(NULL, argv[1], &hints, &res);

	sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) ==
	    -1) {
		perror("setsockopt");
		exit(1);
	}

	if (bind(sockfd, res->ai_addr, res->ai_addrlen) == -1) {
		perror("bind");
		close(sockfd);
		exit(1);
	}

	if (listen(sockfd, 10) == -1) {
		perror("listen");
		close(sockfd);
		exit(1);
	}

	addr_size = sizeof(their_addr);

	char buf[1024];
	memset(buf, 0, 1024);
	int recv_result;

	while (1) {
		new_fd = accept(sockfd, (struct sockaddr *)&their_addr,
				&addr_size);
		recv_result = recv(new_fd, (void *)buf, 1024, 0);
		if (recv_result == -1) {
			perror("recv");
			return -1;
		}

		if (strncmp(buf, "GET", 3) == 0) {
			char *http_status = "HTTP/1.1 200 OK\r\n";
			char *http_content_type = "text/html\r\n\r\n";

			printf("Received GET request.\n");
			send(new_fd, http_status, strlen(http_status), 0);

			send(new_fd, http_content_type,
			     strlen(http_content_type), 0);

			FILE *index_fd = fopen("./index.html", "r");

			struct stat stat_buf;
			shsd_sendfile(new_fd, index_fd, &stat_buf);
		}

		memset(buf, 0, 1024);
		close(new_fd);
	}

	close(sockfd);
	close(new_fd);

	return 0;
}