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
99
100
101
102
103
104
105
106
107
108
109
|
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <strings.h>
#define BUF_LEN 512
#define PATH_LEN 256
#define PORT "3456"
#define BACKLOG 10
int
main(void){
struct sockaddr_storage client_addr;
socklen_t addr_size = sizeof client_addr;
struct addrinfo hints, *serv_info;
int sockfd, acpt_fd, yes = 1, err, recv_len, file_len;
char buf[BUF_LEN], method[16], path[PATH_LEN], *file_buf;
FILE *file;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_flags = AI_PASSIVE;
hints.ai_socktype = SOCK_STREAM;
if ((err = getaddrinfo(NULL, PORT, &hints, &serv_info)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(err));
return 1;
}
if ((sockfd = socket(serv_info->ai_family, serv_info->ai_socktype,
serv_info->ai_protocol)) < 0) {
perror("socket");
exit(1);
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) < 0) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, serv_info->ai_addr, serv_info->ai_addrlen) < 0) {
perror("bind");
exit(1);
}
freeaddrinfo(serv_info);
if (listen(sockfd, BACKLOG) < 0) {
perror("listen");
exit(1);
}
if ((acpt_fd =
accept(sockfd, (struct sockaddr *)&client_addr, &addr_size)) < 0) {
perror("accept");
exit(1);
}
chdir("./resources"); // folder where all files to send are
while (1) {
if ((recv_len = recv(acpt_fd, buf, BUF_LEN, 0)) < 0) {
perror("accept");
exit(1);
}
buf[recv_len] = '\0';
printf("got request: %s\n", buf);
sscanf(buf, "%s %s", method, path+1); //+1 as first char needs to be .
printf("method: %s\n", method);
if (strcmp(method, "GET") == 0) {
printf("requested: %s\n\n", path+1);
if (path[1] == '\0') {
printf("got empty request\n");
continue;
}
path[0] = '.';
if ((file = fopen(path, "r")) == NULL) {
printf("opening \"%s\" didn't work (file nonexistent?)\n\n", path);
continue;
}
fseek(file, 0, SEEK_END);
file_len = ftell(file);
rewind(file);
file_buf = malloc(file_len);
fread(file_buf, file_len, 1, file);
fclose(file);
file_buf[file_len] = '\0';
if (send(acpt_fd, file_buf, file_len, 0) < 0) {
perror("send");
exit(1);
}
free(file_buf);
// prevent data leak by resetting path (a second, empty GET request will
// otherwise send previous file
path[0] = path[1] = '\0';
}
else
printf("invalid method\n");
}
close(acpt_fd);
close(sockfd);
return 0;
}
|