-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
120 lines (102 loc) · 4.68 KB
/
main.cpp
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
#include <iostream>
#include <csignal>
#include "httplib.h"
#include "popl.hpp"
using namespace httplib;
using namespace popl;
Server *svr;
std::string dump_headers(const Headers &headers) {
std::string s;
char buf[BUFSIZ];
for (const auto & x : headers) {
snprintf(buf, sizeof(buf), "%s: %s\n", x.first.c_str(), x.second.c_str());
s += buf;
}
return s;
}
void stop_handler(sig_atomic_t s) {
std::cout <<"Stopping server..." << std::endl;
if (svr && svr->is_valid()) {
svr->stop();
}
std::cout << "done." << std::endl;
exit(0);
}
int main(int argc, char **argv) {
std::string host;
std::string mount_directory;
int port;
//============================================================================================
// setup signal handler (Ctrl+C)
//============================================================================================
signal(SIGINT, stop_handler);
//============================================================================================
// setup options
//============================================================================================
OptionParser op("Allowed options");
auto help_option = op.add<Switch>("", "help", "produce help message");
auto host_option = op.add<Value<std::string>>("h", "host", "the host to listen to", "localhost");
auto port_option = op.add<Value<int>>("p", "port", "the port number", 8080);
auto directory_option = op.add<Value<std::string>>("d", "directory", "base directory to host", "./");
port_option->assign_to(&port);
host_option->assign_to(&host);
directory_option->assign_to(&mount_directory);
//============================================================================================
// parse options
//============================================================================================
try {
op.parse(argc, argv);
if (help_option->count() == 1) std::cout << op << std::endl;
} catch (const popl::invalid_option& e) {
std::cerr << "Invalid Option Exception: " << e.what() << "\n";
std::cerr << "error: ";
return -1;
} catch (const std::exception& e) {
std::cerr << "Generic error: " << e.what() << "\n";
return -1;
}
//============================================================================================
// initialize the server
//============================================================================================
svr = new Server();
if (!svr->is_valid()) {
std::cout << "Cannot start WebServer" << std::endl;
return -1;
}
//============================================================================================
// set directory mountpoint
//============================================================================================
auto ret = svr->set_mount_point("/", mount_directory);
if (!ret) {
std::cerr << "Cannot mount the directory " << mount_directory;
return -1;
}
//============================================================================================
// set error handler
//============================================================================================
svr->set_error_handler([](const auto& req, auto& res) {
std::cout << "request " << req.method << " " << req.path << " error: " << res.status << std::endl;
const char* fmt = "<p>Error Status: <span style='color:red;'>%d</span></p>";
char buf[BUFSIZ];
snprintf(buf, sizeof(buf), fmt, res.status);
res.set_content(buf, "text/html");
});
//============================================================================================
// set post routing handler
//============================================================================================
svr->set_post_routing_handler([](const auto& req, auto& res) {
res.set_header("Access-Control-Allow-Origin", "*");
});
//============================================================================================
// redirect root to index.html
//============================================================================================
svr->Get("/", [=](const Request & /*req*/, Response &res) {
res.set_redirect("/index.html");
});
//============================================================================================
// start listening
//============================================================================================
std::cout << "WebServer listening at " << host << ":" << port << std::endl;
svr->listen(host.c_str(), port);
return 0;
}