forked from phelrine/stakk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.h
103 lines (86 loc) · 2.29 KB
/
server.h
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
#ifndef SERVER_H
#define SERVER_H
#include "common.h"
namespace stakk {
class Server {
protected:
int port;
// implement in sub class
virtual wstring get_result(vector<string> path) = 0;
public:
// set locale
Server(int port_) {
port = port_;
}
virtual ~Server() {}
//parse http request
vector<string> parse_request(string request) {
vector<string> splited = split(request, '\n');
vector<string> path;
for (size_t i = 0; i < splited.size(); i++) {
if (splited[i].find("GET") == 0) {
vector<string> parsed = split(splited[i], ' ');
if (parsed.size() < 1)
continue;
path = split(parsed[1], '/');
for (size_t j = 0; j < path.size(); j++) {
path[j] = urldecode(path[j]);
}
}
}
return path;
}
//generate http response
wstring generate_response(wstring result) {
wstring header = L"HTTP/1.1 200 OK\r\n";
header += L"Content-Type:text/plain; charset=UTF-8\r\n";
return header + L"\r\n" + result;
}
//socket communication
int communicate() {
int sock0;
struct sockaddr_in addr;
int yes = 1;
sock0 = socket(AF_INET, SOCK_STREAM, 0);
if (sock0 < 0) {
perror("socket");
return 1;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
setsockopt(sock0, SOL_SOCKET, SO_REUSEADDR, (const char *)&yes, sizeof(yes));
if (bind(sock0, (struct sockaddr *)&addr, sizeof(addr)) != 0) {
perror("bind");
return 1;
}
if (listen(sock0, 5) != 0) {
perror("listen");
return 1;
}
//main loop
while (true) {
struct sockaddr_in client;
socklen_t len = sizeof(client);
int sock = accept(sock0, (struct sockaddr *)&client, &len);
if (sock < 0) {
perror("accept");
break;
}
char inbuf[2048];
memset(inbuf, 0, sizeof(inbuf));
recv(sock, inbuf, sizeof(inbuf), 0);
vector<string> path = parse_request(inbuf);
//process query and get result
wstring result = get_result(path);
wstring response = generate_response(result);
string output = narrow(response);
send(sock, output.c_str(), (int)strlen(output.c_str()), 0);
close(sock);
}
close(sock0);
return 0;
}
};
}
#endif