-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.c
153 lines (126 loc) · 4.12 KB
/
main.c
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include <stdio.h>
#include "request.h"
#include "response.h"
#include "error.h"
#include "server_defines.h"
#include "config_file.h"
#include "thread_wrapper.h"
#include <locale.h>
#include "base.h"
#include "cache.h"
#include "log.h"
shock_config_t conf;
void processRequest(SOCKET sock) {
char buffer[REQUEST_MAX];
recv(sock, &buffer, sizeof(buffer), 0);
shock_request_t request;
//Parse and validate request
int reqError = shock_parse_request(&request, &buffer, strlen(buffer));
if (reqError == -1) {
shock_error_badrequest(sock, &request);
return;
}
shock_log_access(&request);
//Now serve the file!
char* route = request.route;
char lastchar = route[strlen(route)-1];
if (lastchar == '/') {
strcat(route, "index.html");
}
char filename[FILENAME_MAX] = "";
sprintf(filename, "%s%s", conf.root, route);
if (conf.etagCache == 1 && request.etag[0] != 0) {
char *ptr;
time_t res = strtoll(request.etag, &ptr, 10);
if (shock_cache_compare(filename, res) == 1) {
shock_response_notmodified(sock);
} else {
shock_serve_file(sock, filename);
}
} else {
shock_serve_file(sock, filename);
}
closesocket(sock);
}
int initSockets() {
#ifdef _WIN32
WORD version_wanted = MAKEWORD(1,1);
WSADATA wsaData;
if ( WSAStartup(version_wanted, &wsaData) != 0 ) {;
return -1;
}
#endif // _WIN32
return 0;
}
int main(int argc, char* argv[]) {
printf("*** shockd server by MrOnlineCoder ***\n");
printf("Initializing...\n\n");
if (initSockets() == -1) {
printf("[Fatal Error] Cannot init Winsock!\n");
return 1;
}
//setlocale(LC_ALL, "");
//IPaddress ip;
printf("Applying configuration from shockd.conf file...\n\n");
shock_config_t config;
shock_default_config(&config);
if (shock_parse_config(&config, "shockd.conf") == -1) {
printf("[Fatal Error] cannot parse config!");
return 1;
}
conf = config;
printf("[Config] Port: %d\n", conf.port);
printf("[Config] Server Root: %s\n", conf.root);
printf("[Config] ClearLogs: %d\n", conf.clearLogs);
printf("[Config] ETag Cache: %d\n", conf.etagCache);
printf("[Config] Log File: %s\n", conf.logFile);
if (shock_log_init(&conf) == -1) {
printf("[Fatal Error] Cannot init logging system!\n");
return 1;
}
printf("\nResolving IP...\n\n");
SOCKET server;
struct sockaddr_in serverIP;
server = socket(AF_INET , SOCK_STREAM , 0);
if (server == -1)
{
shock_log(SHOCK_ERROR, "Cannot create server socket!");
printf("[Fatal Error] Cannot create server socket!");
return 1;
}
//Prepare the sockaddr_in structure
serverIP.sin_family = AF_INET;
serverIP.sin_addr.s_addr = INADDR_ANY;
serverIP.sin_port = htons( conf.port );
if( bind(server,(struct sockaddr *)&serverIP , sizeof(serverIP)) < 0)
{
shock_log(SHOCK_ERROR, "Cannot bind socket to port!!");
printf("[Fatal Error] Cannot bind socket to port! \n");
return 1;
}
printf("Starting server...\n\n");
if (listen(server, 5) == SOCKET_ERROR) {
printf("[Fatal Error] Cannot start listening on given port! \n");
return 1;
}
SOCKET client;
struct sockaddr_in clientIP;
size_t c = sizeof(struct sockaddr_in);
shock_log_raw("-----------------------------------------------\n\n");
shock_log_raw("NEW SERVER SESSION STARTED AT %s\n", shock_format_time());
shock_log_raw("-----------------------------------------------\n");
shock_log(SHOCK_INFO, "Server started!");
printf("[!] Done. Waiting for incoming connections...\n");
while (1) {
client=accept(server, (struct sockaddr *)&clientIP, (socklen_t*)&c);
if(client < 0)
{
shock_log(SHOCK_ERROR, "Couldn't accept incoming connection!");
printf("[Connection Error] Failed to accept incoming connection!");
continue;
}
shock_create_thread(processRequest, client);
}
printf("--- END, THAT SHOULDN'T BE REACHED ---");
return 0;
}