-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
{% ENDELDEF %}
diff --git a/building/main.cpp b/building/main.cpp
index 4e1cf94..fd1f100 100644
--- a/building/main.cpp
+++ b/building/main.cpp
@@ -29,7 +29,7 @@ struct CAWebChat {
std::vector
warning_flags = {"-Wall", "-Wno-unused-variable", "-Werror=return-type","-pedantic",
"-Wno-unused-but-set-variable", "-Wno-reorder"};
- std::vector version_flags = {"--std", "c++14", "-D", "_POSIX_C_SOURCE=200809L"};
+ std::vector version_flags = {"--std", "c++17", "-D", "_POSIX_C_SOURCE=200809L"};
std::vector debug_defines_release = {"_GLIBCXX_DEBUG"};
std::vector debug_defines_debug = {"_GLIBCXX_DEBUG", "DEBUG_ALLOW_LOUD"};
std::vector opt_flags_release = {"-g", "-O2"};
@@ -78,6 +78,7 @@ struct CAWebChat {
"connecting_assets/static_asset_manager.cpp",
"running_mainloop.cpp",
"form_data_structure/urlencoded_query.cpp",
+ "socket_address.cpp",
};
for (std::string& u: T.units)
u = "http_server/engine_engine_number_9/" + u;
@@ -93,6 +94,8 @@ struct CAWebChat {
"http_structures/response_gen.h",
"running_mainloop.h",
"form_data_structure/urlencoded_query.h",
+ "socket_address.h",
+ "admin_control.h",
};
for (std::string& u: T.exported_headers)
u = "engine_engine_number_9/" + u;
diff --git a/example/config.json b/example/config.json
index 712ed07..2ee8d70 100644
--- a/example/config.json
+++ b/example/config.json
@@ -31,6 +31,6 @@
"server": {
"workers": 8,
"http-listen": ["127.0.0.1:1025"],
- "command-listen": []
+ "admin-command-listen": ["127.0.0.1:1026"]
}
-}
\ No newline at end of file
+}
diff --git a/src/http_server/engine_engine_number_9/admin_control.cpp b/src/http_server/engine_engine_number_9/admin_control.cpp
new file mode 100644
index 0000000..1577fb8
--- /dev/null
+++ b/src/http_server/engine_engine_number_9/admin_control.cpp
@@ -0,0 +1,62 @@
+#include "admin_control.h"
+#include
+#include
+
+namespace een9 {
+ static const char* admin_to_server_ms = "a6m1n 2 server request ~~~";
+ static const char* server_to_admin_ms = "server to 4dm1n r3sponse ~~~";
+
+ AdminControlProtMsgRecvCtx::AdminControlProtMsgRecvCtx(const char *ms): magic_string(ms) {
+ ms_size = strlen(ms);
+ }
+
+ int AdminControlProtMsgRecvCtx::feedCharacter(char ch) {
+ assert(status == 0);
+ if (magic_string_progress < ms_size) {
+ if (magic_string[magic_string_progress] != ch) {
+ status = -1;
+ return status;
+ }
+ magic_string_progress++;
+ } else if (body_size_progress < 8) {
+ uint64_t bt = (uint64_t)(uint8_t)ch;
+ b_sz = ((b_sz << 8) | bt);
+ body_size_progress++;
+ if (body_size_progress == 8 && b_sz > 100000000) {
+ status = -1;
+ return status;
+ }
+ body.reserve(b_sz);
+ } else if (body.size() < b_sz) {
+ body += ch;
+ } else {
+ status = 1;
+ }
+ return status;
+ }
+
+ AdminControlRequestRCtx::AdminControlRequestRCtx(): AdminControlProtMsgRecvCtx(admin_to_server_ms) {
+ }
+
+ AdminControlResponseRCtx::AdminControlResponseRCtx(): AdminControlProtMsgRecvCtx(server_to_admin_ms) {
+ }
+
+ std::string generate_ac_msg_gen_case(const std::string& content, const char* ms) {
+ std::string result;
+ uint64_t N = content.size();
+ for (int i = 0; i < 8; i++) {
+ result += (char)(uint8_t)((N & 0xff00000000000000) >> 56);
+ N <<= 8;
+ }
+ result += content;
+ return result;
+ }
+
+ std::string generate_admin_control_request(const std::string &content) {
+ return generate_ac_msg_gen_case(content, admin_to_server_ms);
+ }
+
+ std::string generate_admin_control_response(const std::string &content) {
+ return generate_ac_msg_gen_case(content, server_to_admin_ms);
+ }
+}
diff --git a/src/http_server/engine_engine_number_9/admin_control.h b/src/http_server/engine_engine_number_9/admin_control.h
new file mode 100644
index 0000000..a354891
--- /dev/null
+++ b/src/http_server/engine_engine_number_9/admin_control.h
@@ -0,0 +1,37 @@
+#ifndef ENGINE_ENGINE_NUMBER_9_ADMIN_CONTROL_H
+#define ENGINE_ENGINE_NUMBER_9_ADMIN_CONTROL_H
+
+#include
+#include
+
+namespace een9 {
+ struct AdminControlProtMsgRecvCtx {
+ const char* magic_string;
+ size_t ms_size;
+ size_t magic_string_progress = 0;
+ size_t body_size_progress = 0;
+ uint64_t b_sz = 0;
+ std::string body;
+ int status = 0;
+
+ explicit AdminControlProtMsgRecvCtx(const char* ms);
+
+ int feedCharacter(char ch);
+ };
+
+ struct AdminControlRequestRCtx: public AdminControlProtMsgRecvCtx {
+ AdminControlRequestRCtx();
+ };
+
+ struct AdminControlResponseRCtx: public AdminControlProtMsgRecvCtx {
+ AdminControlResponseRCtx();
+ };
+
+ /* From ADMIN to server (will begin with admin_to_server_ms)*/
+ std::string generate_admin_control_request(const std::string& content);
+
+ /* From SERVER to admin (will begin with server_to_admin_ms).*/
+ std::string generate_admin_control_response(const std::string& content);
+}
+
+#endif
diff --git a/src/http_server/engine_engine_number_9/baza.cpp b/src/http_server/engine_engine_number_9/baza.cpp
index dec371c..0dcd06e 100644
--- a/src/http_server/engine_engine_number_9/baza.cpp
+++ b/src/http_server/engine_engine_number_9/baza.cpp
@@ -28,14 +28,30 @@ namespace een9 {
return false;
}
- bool endsIn(const std::string &a, const std::string &b) {
+ bool endsWith(const std::string &a, const std::string &b) {
if (b.size() > a.size())
return false;
return std::equal(a.end() - (ssize_t)b.size(), a.end(), b.begin());
}
+ bool beginsWith(const std::string &a, const std::string &b) {
+ if (b.size() > a.size())
+ return false;
+ return std::equal(a.begin(), a.begin() + (ssize_t)b.size(), b.begin());
+ }
+
std::string getSubstring(const std::string &str, size_t A, size_t B) {
ASSERT(A <= B && B <= str.size(), "Incorrect substring segment");
return str.substr(A, B - A);
}
+
+ std::string make_uppercase(const std::string &source) {
+ std::string result(source);
+ for (size_t i = 0; i < source.size(); i++) {
+ char ch = source[i];
+ if ('a' <= ch && ch <= 'z')
+ result[i] = (char)(ch - 'a' + 'A');
+ }
+ return result;
+ }
}
diff --git a/src/http_server/engine_engine_number_9/baza.h b/src/http_server/engine_engine_number_9/baza.h
index ef6b868..96378c7 100644
--- a/src/http_server/engine_engine_number_9/baza.h
+++ b/src/http_server/engine_engine_number_9/baza.h
@@ -18,11 +18,17 @@ namespace een9 {
bool strIn(const std::string& str, const char* arr[]);
- bool endsIn(const std::string& a, const std::string& b);
+ // b is postfix of a
+ bool endsWith(const std::string& a, const std::string& b);
+
+ // b is prefix of a
+ bool beginsWith(const std::string& a, const std::string& b);
/* In case of error, throws een9::ServerError */
std::string getSubstring(const std::string& str, size_t A, size_t B);
+ std::string make_uppercase(const std::string &source);
+
template
using uptr = std::unique_ptr;
}
diff --git a/src/http_server/engine_engine_number_9/connecting_assets/static_asset_manager.cpp b/src/http_server/engine_engine_number_9/connecting_assets/static_asset_manager.cpp
index 12bbea6..e4f4858 100644
--- a/src/http_server/engine_engine_number_9/connecting_assets/static_asset_manager.cpp
+++ b/src/http_server/engine_engine_number_9/connecting_assets/static_asset_manager.cpp
@@ -53,7 +53,7 @@ namespace een9 {
std::vector c_files = detour_over_regular_folder(dir_rule.directory);
for (const std::string& file: c_files) {
for (const StaticAssetManagerRulePostfixFilter& ext: dir_rule.postfix_rules_type_assign) {
- if (endsIn(file, ext.required_postfix)) {
+ if (endsWith(file, ext.required_postfix)) {
/* Found it! */
StaticAsset etot{ext.assigned_type, };
readFile(dir_rule.directory + "/" + file, etot.content);
diff --git a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp
index c9ec6b3..c02a744 100644
--- a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp
+++ b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.cpp
@@ -5,11 +5,12 @@
#include
// Used for debug
+#ifdef DEBUG_ALLOW_LOUD
#include "unistd.h"
#include
#include "sys/dir.h"
#include "../os_utils.h"
-
+#endif
namespace een9 {
ClientRequestParser_CommonPrograms::ClientRequestParser_CommonPrograms() {
@@ -106,8 +107,10 @@ namespace een9 {
if (p.first == "Content-Length") {
collecting_body = res.has_body = true;
body_size = std::stoull(p.second);
- if (body_size > 100000000)
- THROW("Message content is too big");
+ if (body_size > 100000000) {
+ status = -1;
+ return status;
+ }
res.body.reserve(body_size);
}
}
@@ -121,7 +124,6 @@ namespace een9 {
writeFile("log/req", header);
#endif
status = -1;
- THROW("bad request");
}
}
return status;
diff --git a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.h b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.h
index e4756e9..ea6e559 100644
--- a/src/http_server/engine_engine_number_9/http_structures/client_request_parse.h
+++ b/src/http_server/engine_engine_number_9/http_structures/client_request_parse.h
@@ -37,7 +37,6 @@ namespace een9 {
explicit ClientRequestParser_WorkerBuffers(const ClientRequestParser_CommonPrograms& common_comp_program);
};
- /* Ou yeah, baby, it's time for more OOP */
struct ClientHttpRequestParser_Ctx {
ClientRequest& res;
regexis024::VirtualMachine& vm;
diff --git a/src/http_server/engine_engine_number_9/os_utils.cpp b/src/http_server/engine_engine_number_9/os_utils.cpp
index 6ed7a2e..d487f4a 100644
--- a/src/http_server/engine_engine_number_9/os_utils.cpp
+++ b/src/http_server/engine_engine_number_9/os_utils.cpp
@@ -25,7 +25,6 @@ namespace een9 {
}
UniqueFdWrapper::~UniqueFdWrapper() {
- // printf("DEBUG!!! Closing fd = %d\n", fd);
if (fd >= 0)
close(fd);
}
@@ -55,7 +54,7 @@ namespace een9 {
while ((ret = (int)read(fd, buf, 2048)) > 0) {
size_t oldN = result.size();
result.resize(oldN + ret);
- memcpy((void*)&result.c_str()[oldN], buf, ret);
+ memcpy(result.data() + oldN, buf, ret);
}
ASSERT_on_iret(ret, "Reading from " + description);
}
diff --git a/src/http_server/engine_engine_number_9/running_mainloop.cpp b/src/http_server/engine_engine_number_9/running_mainloop.cpp
index 41560fc..1b5b626 100644
--- a/src/http_server/engine_engine_number_9/running_mainloop.cpp
+++ b/src/http_server/engine_engine_number_9/running_mainloop.cpp
@@ -13,6 +13,7 @@
#include "http_structures/client_request_parse.h"
#include "http_structures/response_gen.h"
#include "baza_inter.h"
+#include "admin_control.h"
namespace een9 {
struct QElementHttpConnections {
@@ -73,11 +74,13 @@ namespace een9 {
WorkersTaskQueue queue;
bool& termination;
guest_core_t guest_core;
+ guest_core_admin_control_t guest_core_admin_control;
/* Parser programs */
ClientRequestParser_CommonPrograms parser_programs;
- WorkersEnvCommon(bool& term, guest_core_t g_c): termination(term), guest_core(std::move(g_c)){}
+ WorkersEnvCommon(bool& term, const MainloopParameters& params): termination(term),
+ guest_core(params.guest_core), guest_core_admin_control(params.guest_core_admin_control){}
};
struct WorkersEnv {
@@ -89,25 +92,22 @@ namespace een9 {
};
// todo: add timeout for multiple bytes, add more settings
- ClientRequest process_connection_input(int fd, const EEN9_ServerTips& s_tips, WorkersEnv& wte) {
+ ClientRequest process_http_connection_input(int fd, const EEN9_ServerTips& s_tips, WorkersEnv& wte) {
ClientRequest res;
ClientHttpRequestParser_Ctx parser(res, wte.personal_parser_buffer, wte.wtec.parser_programs);
int ret;
char buf[2048];
- ASSERT_pl(parser.status == 0);
+ assert(parser.status == 0);
while ((ret = (int)recv(fd, buf, 2048, 0)) > 0) {
for (size_t i = 0; i < ret; i++) {
- /* Throws ServerError on bad input */
- if (parser.feedCharacter(buf[i]) > 0) {
+ if (parser.feedCharacter(buf[i]) > 0)
break;
- }
}
if (parser.status > 0)
break;
}
ASSERT_on_iret(ret, "recv");
- ASSERT_pl(parser.status == 1);
- // printf("Log: worker received clients request\n%s\n", client_request.toString().c_str());
+ assert(parser.status == 1);
return res;
}
@@ -123,10 +123,35 @@ namespace een9 {
printf("Log: worker: succesfully asnwered with response\n");
}
+ std::string process_admin_control_connection_input(int fd, const EEN9_ServerTips& s_tips, WorkersEnv& wte) {
+ AdminControlRequestRCtx pctx;
+ int ret;
+ char buf[2048];
+ assert(pctx.status == 0);
+ while ((ret = (int)recv(fd, buf, 2048, 0)) > 0) {
+ for (size_t i = 0; i < ret; i++) {
+ if (pctx.feedCharacter(buf[i]) > 0)
+ break;
+ }
+ if (pctx.status > 0)
+ break;
+ }
+ ASSERT_on_iret(ret, "recv");
+ assert(pctx.status == 1);
+ return pctx.body;
+ }
+
void process_connection(const SlaveTask& task, WorkersEnv& wte) {
- ClientRequest client_request = process_connection_input(task.fd(), task.s_tips, wte);
- std::string server_response = wte.wtec.guest_core(task, client_request, wte.id);
- process_connection_output(task.fd(), server_response);
+ if (task.conn_info.type == 0) {
+ ClientRequest client_request = process_http_connection_input(task.fd(), task.s_tips, wte);
+ std::string server_response = wte.wtec.guest_core(task, client_request, wte.id);
+ process_connection_output(task.fd(), server_response);
+ } else if (task.conn_info.type == 1) {
+ std::string admin_request = process_admin_control_connection_input(task.fd(), task.s_tips, wte);
+ std::string server_response_content = wte.wtec.guest_core_admin_control(task, admin_request, wte.id);
+ std::string server_response = generate_admin_control_response(server_response_content);
+ process_connection_output(task.fd(), server_response);
+ }
}
void* worker_func(void* wte_ptr) {
@@ -156,13 +181,13 @@ namespace een9 {
return NULL;
}
- // todo: retrieve address of connected client
-
void electric_boogaloo(const MainloopParameters& params, bool& termination_trigger) {
- WorkersEnvCommon wtec(termination_trigger, params.guest_core);
+ WorkersEnvCommon wtec(termination_trigger, params);
ASSERT(params.slave_number > 0, "No workers spawned");
- size_t Nip = params.ports_to_listen.size();
- ASSERT(Nip > 0, "No open listeting addresses");
+ size_t CRL_Nip = params.client_regular_listened.size();
+ ASSERT(CRL_Nip > 0, "No open listeting addresses (http)");
+ size_t ACL_Nip = params.admin_control_listened.size();
+ size_t Nip = CRL_Nip + ACL_Nip;
std::vector workers(params.slave_number);
std::vector> wtes(params.slave_number);
@@ -173,44 +198,49 @@ namespace een9 {
pthread_create(&workers[i], NULL, worker_func, wtes[i].get());
}
+ // todo: move this try block inside the loop
try {
int ret;
- std::vector listening_socks(Nip);
+ struct Ear {
+ /* A copy from params */
+ SocketAddress my_addr;
+ UniqueFdWrapper listening_sock;
+ /* type 0 is for http protocol
+ * type 1 is for admin-cmd protocol */
+ int type;
+ };
+ std::vector ears(Nip);
+ for (size_t i = 0; i < CRL_Nip; i++) {
+ ears[i].my_addr = params.client_regular_listened[i];
+ ears[i].type = 0;
+ }
+ for (size_t i = 0; i < ACL_Nip; i++) {
+ ears[i + CRL_Nip].my_addr = params.admin_control_listened[i];
+ ears[i + CRL_Nip].type = 1;
+ }
for (size_t i = 0; i < Nip; i++) {
- printf("Creating listening socket\n");
- uint16_t port = params.ports_to_listen[i];
int listening_socket_fd = socket(AF_INET, SOCK_STREAM, 0);
- ASSERT_on_iret(listening_socket_fd, "Listening socket creation");
+ ASSERT_on_iret(listening_socket_fd, "'Listening socket' creation");
UniqueFdWrapper listening_socket(listening_socket_fd);
- printf("Listening socket created\n");
- sockaddr_in listening_address;
- listening_address.sin_family = AF_INET;
- listening_address.sin_port = htons(port);
- uint32_t lca = (127u << 24) | 1;
- listening_address.sin_addr.s_addr = htonl(lca);
int reuseaddr_nozero_option_value = 1;
ret = setsockopt(listening_socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuseaddr_nozero_option_value, sizeof(int));
- ASSERT_on_iret(ret, "setting SO_REUSEADDR befire binding to address");
- ret = bind(listening_socket(), (const sockaddr*)&listening_address, sizeof(listening_address));
- ASSERT_on_iret(ret, "binding to INADDR_ANY:" + std::to_string(port));
- printf("Binded socket to address\n");
+ ASSERT_on_iret(ret, "Can't set SO_REUSEADDR");
+ bind_to_socket_address(listening_socket_fd, ears[i].my_addr);
ret = listen(listening_socket(), 128);
- ASSERT_on_iret(ret, "listening for connections");
- printf("Listening socket succesfully started listening\n");
- listening_socks[i] = std::move(listening_socket);
+ ASSERT_on_iret(ret, "listen() listening for connections");
+ ears[i].listening_sock = std::move(listening_socket);
}
std::vector pollfds(Nip);
for (size_t i = 0; i < Nip; i++) {
- pollfds[i].fd = listening_socks[i]();
+ pollfds[i].fd = ears[i].listening_sock();
pollfds[i].events = POLLRDNORM;
}
- printf("Entering mainloop\n");
ASSERT(params.mainloop_recheck_interval_us > 0, "Incorrect poll timeout");
while (true) {
- MutexLockGuard lg1(wtec.corvee_bed, "poller termination check");
+ // MutexLockGuard lg1(wtec.corvee_bed, "poller termination check");
if (wtec.termination)
break;
- lg1.unlock();
+ // lg1.unlock();
for (size_t i = 0; i < Nip; i++) {
pollfds[i].revents = 0;
}
@@ -218,21 +248,24 @@ namespace een9 {
ret = poll(pollfds.data(), Nip, params.mainloop_recheck_interval_us);
if (errno == EINTR)
break;
- ASSERT_on_iret(ret, "polling");
+ // todo: do not end program here (in the loop. Nothing in the loop should be able to end program)
+ ASSERT_on_iret(ret, "poll()");
for (size_t i = 0; i < Nip; i++) {
if ((pollfds[i].revents & POLLRDNORM)) {
try {
- sockaddr client_address;
- socklen_t client_addr_len = sizeof(client_address);
- int session_sock = accept(pollfds[i].fd, &client_address, &client_addr_len);
+ int session_sock = accept(pollfds[i].fd, NULL, NULL);
ASSERT_on_iret(session_sock, "Failed to accept incoming connection");
- printf("Log: successful connection\n");
UniqueFdWrapper session_sock_fdw(session_sock);
configure_socket_rcvsndtimeo(session_sock_fdw(), params.s_conf.request_timeout);
+ SocketAddress peer_addr;
+ get_peer_name_as_socket_address(session_sock, peer_addr);
{ MutexLockGuard lg2(wtec.corvee_bed, "poller adds connection");
- SlaveTask task{ConnectionInfo{}, std::move(session_sock_fdw),
+ SlaveTask task{
+ ConnectionInfo{ears[i].my_addr, peer_addr, ears[i].type},
+ std::move(session_sock_fdw),
EEN9_ServerTips{wtec.queue.size(),
- params.s_conf.critical_load_1, params.s_conf.request_timeout}};
+ params.s_conf.critical_load_1, params.s_conf.request_timeout}
+ };
if (wtec.queue.size() < params.s_conf.critical_load_2)
wtec.queue.push_back(std::move(task));
}
diff --git a/src/http_server/engine_engine_number_9/running_mainloop.h b/src/http_server/engine_engine_number_9/running_mainloop.h
index 65bcd4e..4595dc2 100644
--- a/src/http_server/engine_engine_number_9/running_mainloop.h
+++ b/src/http_server/engine_engine_number_9/running_mainloop.h
@@ -7,12 +7,14 @@
#include "os_utils.h"
#include "http_structures/client_request.h"
#include
+#include "socket_address.h"
namespace een9 {
struct ConnectionInfo {
- // todo: add server address field
- // todo: add client address field
- int type; // O_o why??
+ SocketAddress server_name;
+ SocketAddress client_name;
+ /* 0 - http, 1 - 'een9::admin-control' protocol */
+ int type;
};
/* This structure is passed to guest function. It contains server info that might be or might be not used
@@ -33,6 +35,8 @@ namespace een9 {
/* guest_core function must not throw anything that is not derived from std::exception */
typedef std::function guest_core_t;
+ /* same as gurst_core_t, but it used not for http, but for een9 specific "admin-cmd" protocol */
+ typedef std::function guest_core_admin_control_t;
struct ServersConfiguration {
size_t critical_load_1 = 90;
@@ -42,15 +46,19 @@ namespace een9 {
};
struct MainloopParameters {
+ /* On which addresses should I listed for incoming HTTP connections */
+ std::vector client_regular_listened;
+ /* On which addresses should I listen for incoming administrative commands */
+ std::vector admin_control_listened;
bool do_logging = true;
- bool open_admin_listener = true;
- // todo: add support for unix socket address
- uint16_t admin_listener_port = 12345;
- guest_core_t guest_core;
size_t slave_number = 2;
- std::vector ports_to_listen;
int mainloop_recheck_interval_us = 100;
+ /* Takes parsed http request object. Should return fully-prepared http response */
+ guest_core_t guest_core;
+ /* Takes admin input. Returns only desired output message (without protocol header) */
+ guest_core_admin_control_t guest_core_admin_control;
+
ServersConfiguration s_conf;
};
diff --git a/src/http_server/engine_engine_number_9/socket_address.cpp b/src/http_server/engine_engine_number_9/socket_address.cpp
new file mode 100644
index 0000000..eb65dfd
--- /dev/null
+++ b/src/http_server/engine_engine_number_9/socket_address.cpp
@@ -0,0 +1,276 @@
+#include "socket_address.h"
+#include
+#include "baza.h"
+#include "baza_inter.h"
+#include
+#include
+#include
+#include
+#include
+#include
+
+namespace een9 {
+ struct regexp_cmp_out{
+ std::vector prg;
+ regexis024::track_var_list vars;
+ };
+ regexp_cmp_out compile_regexp(const char* expr) {
+ regexp_cmp_out res;
+ std::string problem;
+ int ret = regexis024::compile(expr, res.vars, res.prg, problem);
+ ASSERT(ret == 0, "Can't compile regexp");
+ return res;
+ }
+
+ struct SocketAddressParser_Inner {
+ regexp_cmp_out prg;
+ regexis024::VirtualMachine vm;
+ regexis024::tai_t tdiff_k;
+ std::pair i4_k;
+ std::pair i6_k;
+ std::pair ip_k;
+ regexis024::tai_t skip_k;
+
+#define reg_int4 "#4(0|[1-9][0-9]!r{0;2})"
+#define reg_int6 "#6(0|[1-9a-fA-F][0-9a-fA-F]!r{0;3})"
+#define reg_6RHT_rep(mt) "(:|(:" reg_int6 ")!r{1;" #mt "})"
+#define reg_6LFT_rep(ea) "(" reg_int6 ":)!r{" #ea "}"
+#define reg_6zs "#s:0;"
+#define reg_intp "#p(0|[1-9][0-9]!r{0;4})"
+#define reg_addr_in4 "(#t:1;" reg_int4 "." reg_int4 "." reg_int4 "." reg_int4 ":" reg_intp ")"
+#define reg_addr_in6_core "(" reg_6LFT_rep(7) reg_int6 "|" ":" reg_6zs reg_6RHT_rep(6) "|" \
+ reg_6LFT_rep(1) reg_6zs reg_6RHT_rep(5) "|" \
+ reg_6LFT_rep(2) reg_6zs reg_6RHT_rep(4) "|" \
+ reg_6LFT_rep(3) reg_6zs reg_6RHT_rep(3) "|" \
+ reg_6LFT_rep(4) reg_6zs reg_6RHT_rep(2) "|" \
+ reg_6LFT_rep(5) reg_6zs reg_6RHT_rep(1) "|" \
+ reg_6LFT_rep(6) reg_6zs ":" ")"
+#define reg_addr_in6 "(#t:2;\\[" reg_addr_in6_core "\\]:" reg_intp ")"
+ SocketAddressParser_Inner(): prg(compile_regexp(
+ reg_addr_in4 "|" reg_addr_in6
+ )), vm(prg.prg.size(), prg.prg.data(), UINT64_MAX, UINT16_MAX, UINT32_MAX, UINT32_MAX, UINT64_MAX)
+ {
+ ASSERT_pl(vm.initialize() == 0);
+ tdiff_k = prg.vars.at("t").colarr_first;
+ skip_k = prg.vars.at("s").colarr_first;
+ auto obtain_range = [&](const std::string& name) -> std::pair {
+ const regexis024::TrackingVariableInfo& vi = prg.vars.at(name);
+ assert(vi.colarr_first > 0 && vi.colarr_second > 0);
+ return {(regexis024::tai_t)vi.colarr_first, (regexis024::tai_t)vi.colarr_second};
+ };
+ i4_k = obtain_range("4");
+ i6_k = obtain_range("6");
+ ip_k = obtain_range("p");
+ }
+ };
+
+ SocketAddressParser::SocketAddressParser() {
+ opaque = new SocketAddressParser_Inner();
+ }
+
+ SocketAddressParser::~SocketAddressParser() {
+ delete (SocketAddressParser_Inner*)opaque;
+ }
+
+ int parse_socket_address(const std::string& addr, SocketAddress& res, SocketAddressParser& pdata) {
+#define reveal (*(SocketAddressParser_Inner*)pdata.opaque)
+ reveal.vm.wipeToInit();
+ ASSERT_pl(reveal.vm.addNewMatchingThread() == 0);
+ int ret;
+ for (size_t i = 0; i < addr.size(); i++) {
+ ret = reveal.vm.feedCharacter((uint64_t)addr[i], 1);
+ // if (!reveal.vm.haveSurvivors()) {
+ // printf("DEBUG: died on %s\n", addr.substr(0, i + 1).c_str());
+ // break;
+ // }
+ }
+ if (reveal.vm.isMatched()) {
+ std::vector ca = reveal.vm.getMatchedThreadCABranchReverse();
+ std::reverse(ca.begin(), ca.end());
+ size_t ci = 0;
+#define curKey() ca[ci].key
+#define curValue() ca[ci].value
+ auto extractRange = [&](std::pair rk) -> std::string {
+ assert(ca[ci].key == rk.first && ca[ci + 1].key == rk.second);
+ size_t oci = ci;
+ ci += 2;
+ return getSubstring(addr, ca[oci].value, ca[oci + 1].value);
+ };
+ assert(curKey() == reveal.tdiff_k);
+ if (curValue() == 1) {
+ ci++;
+ uint32_t res_addr = 0;
+ for (int i = 0; i < 4; i++) {
+ std::string h = extractRange(reveal.i4_k);
+ uint32_t p = std::stoul(h);
+ if (p > 255)
+ return -1;
+ res_addr = ((res_addr << 8) | p);
+ }
+ uint32_t res_port = std::stoul(extractRange(reveal.ip_k));
+ if (res_port > 65535)
+ return -1;
+ res.v.gen.sa_family = AF_INET;
+ res.v.sin.sin_port = htons(res_port); // host to network short
+ res.v.sin.sin_addr.s_addr = htonl(res_addr); // host to network long
+ res.addrLen = sizeof(sockaddr_in);
+ } else if (curValue() == 2){
+ ci++;
+ int skipped = 8;
+ for (const regexis024::CAEvent& ev: ca) {
+ if (ev.key == reveal.i6_k.first)
+ skipped--;
+ }
+ assert(skipped == 0 || skipped >= 2);
+ uint16_t res_u6_addr16[8];
+ size_t bi = 0;
+ std::string h;
+ while (bi < 8) {
+ if (curKey() == reveal.i6_k.first) {
+ h = extractRange(reveal.i6_k);
+ assert(h.size() <= 4);
+ uint32_t v = 0;
+ for (char ch: h) {
+ v <<= 4;
+ if ('0' <= ch && ch <= '9') {
+ v |= (uint32_t)(ch - '0');
+ } else if ('a' <= ch && ch <= 'z') {
+ v |= (uint32_t)(ch - 'a' + 10);
+ } else if ('A' <= ch && ch <= 'Z') {
+ v |= (uint32_t)(ch - 'A' + 10);
+ } else
+ assert(false);
+ }
+ assert(v <= UINT16_MAX);
+ res_u6_addr16[bi++] = (uint16_t)v;
+ } else if (curKey() == reveal.skip_k) {
+ ci++;
+ for (int j = 0; j < skipped; j++)
+ res_u6_addr16[bi++] = 0;
+ } else
+ assert(false);
+ }
+ assert(bi == 8);
+ uint32_t res_port = std::stoul(extractRange(reveal.ip_k));
+ if (res_port > 65535)
+ return -1;
+ res.v.gen.sa_family = AF_INET6;
+ res.v.sin6.sin6_port = htons(res_port);
+ for (int i = 0; i < 8; i++)
+ res.v.sin6.sin6_addr.__in6_u.__u6_addr16[i] = htons(res_u6_addr16[i]);
+ res.addrLen = sizeof(sockaddr_in6);
+ } else
+ assert(false);
+ assert(ci == ca.size());
+ return 0;
+ }
+ const std::string& up = "unix:";
+ if (beginsWith(addr, up)) {
+ std::string path = addr.substr(up.size());
+ if (path.empty())
+ return -1;
+ if (path.back() == '/')
+ return -1;
+ for (char ch: path)
+ if (ch == 0)
+ return -1;
+ res.v.gen.sa_family = AF_UNIX;
+ if (sizeof(res.v.sun.sun_path) > path.size())
+ THROW("path is too big");
+ memcpy(res.v.sun.sun_path, path.c_str(), path.size());
+ res.addrLen = offsetof(sockaddr_un, sun_path) + path.size();
+ return 0;
+ }
+ return -1;
+ }
+
+ std::string short2hex(uint16_t v) {
+ if (v == 0)
+ return "0";
+ std::string result;
+ while (v) {
+ result += (char)((v & 0xf) > 9 ? (v & 0xf) - 10 + 'a' : (v & 0xf) + '0');
+ v >>= 4;
+ }
+ std::reverse(result.begin(), result.end());
+ return result;
+ }
+
+ std::string stringify_socket_address(const SocketAddress &addr) {
+ if (addr.v.gen.sa_family == AF_INET) {
+ char buf[22];
+ uint32_t IP = ntohl(addr.v.sin.sin_addr.s_addr);
+ uint16_t port = ntohs(addr.v.sin.sin_port);
+ snprintf(buf, 22, "%u.%u.%u.%u:%hu", (IP >> 24) & 0xff, (IP >> 16) & 0xff, (IP >> 8) & 0xff,
+ (IP >> 0) & 0xff, port);
+ return buf;
+ } else if (addr.v.gen.sa_family == AF_INET6) {
+ uint16_t IP[8];
+ for (int i = 0; i < 8; i++)
+ IP[i] = ntohs(addr.v.sin6.sin6_addr.__in6_u.__u6_addr16[i]);
+ uint16_t port = ntohs(addr.v.sin6.sin6_port);
+ int largest_sz = 0;
+ int largest_start = 0;
+ int cur_sz = 0;
+ for (int i = 0; i < 8; i++) {
+ if (IP[i] == 0) {
+ cur_sz++;
+ if (largest_sz < cur_sz) {
+ largest_sz = cur_sz;
+ largest_start = i + 1 - cur_sz;
+ }
+ } else {
+ cur_sz = 0;
+ }
+ }
+ std::string core;
+ for (int i = 0; i < 8;) {
+ if (largest_sz >= 2 && largest_start == i) {
+ i += largest_sz;
+ if (i == 8)
+ core += "::";
+ else
+ core += ":";
+ } else {
+ if (i > 0)
+ core += ":";
+ core += short2hex(IP[i]);
+ i++;
+ }
+ }
+ assert(core.size() <= 39);
+ char buf[48];
+ snprintf(buf, 48, "[%s]:%hu", core.c_str(), port);
+ return buf;
+ } else if (addr.v.gen.sa_family == AF_UNIX) {
+ assert(addr.addrLen > offsetof(sockaddr_un, sun_path));
+ size_t path_len = addr.addrLen - offsetof(sockaddr_un, sun_path);
+ assert(path_len <= sizeof(addr.v.sun.sun_path));
+ std::string path(path_len, ')');
+ memcpy(path.data(), addr.v.sun.sun_path, path_len);
+ return "unix:" + path;
+ } else
+ return "Socket address of unknown domain";
+ }
+
+ void bind_to_socket_address(int sockfd, const SocketAddress &addr) {
+ int ret;
+ if (addr.v.gen.sa_family == AF_INET) {
+ ret = bind(sockfd, (const sockaddr*)&addr.v.sin, addr.addrLen);
+ } else if (addr.v.gen.sa_family == AF_INET6) {
+ ret = bind(sockfd, (const sockaddr*)&addr.v.sin6, addr.addrLen);
+ } else if (addr.v.gen.sa_family == AF_INET) {
+ ret = bind(sockfd, (const sockaddr*)&addr.v.sun, addr.addrLen);
+ } else
+ THROW("binding socket to address of unsupported domain");
+ ASSERT_on_iret(ret, "binding socket");
+ }
+
+ void get_peer_name_as_socket_address(int sockfd, SocketAddress &res) {
+ socklen_t willbecome = sizeof(res.v);
+ int ret = getpeername(sockfd, &res.v.gen, &willbecome);
+ ASSERT_on_iret(ret, "getpeername");
+ assert(willbecome <= sizeof(res.v));
+ res.addrLen = willbecome;
+ }
+}
diff --git a/src/http_server/engine_engine_number_9/socket_address.h b/src/http_server/engine_engine_number_9/socket_address.h
new file mode 100644
index 0000000..50511df
--- /dev/null
+++ b/src/http_server/engine_engine_number_9/socket_address.h
@@ -0,0 +1,51 @@
+#ifndef ENGINE_ENGINE_NUMBER_9_SOCKET_ADDRESS_H
+#define ENGINE_ENGINE_NUMBER_9_SOCKET_ADDRESS_H
+
+#if defined(SOLARIS)
+#include
+#endif
+#include
+#include
+#if defined(BSD)
+#include
+#include
+#endif
+#include
+#include
+
+namespace een9 {
+ /* Right now een9 supports only IP4, IP6, unix domain. System service querying is not implemented yet *
+ * */
+
+ struct SocketAddress {
+ union {
+ sockaddr gen;
+ sockaddr_in sin;
+ sockaddr_in6 sin6;
+ sockaddr_un sun;
+ } v;
+ size_t addrLen = sizeof(sockaddr_in);
+ };
+
+ /* Not thread-safe. Use only from one thread (at a time) */
+ struct SocketAddressParser {
+ void* opaque = NULL;
+
+ SocketAddressParser();
+ SocketAddressParser(const SocketAddressParser&) = default;
+ SocketAddressParser& operator=(const SocketAddressParser&) = default;
+ ~SocketAddressParser();
+ };
+
+ int parse_socket_address(const std::string& addr, SocketAddress& res, SocketAddressParser& pdata);
+
+ std::string stringify_socket_address(const SocketAddress& addr);
+
+ /* Throws ServerError on error */
+ void bind_to_socket_address(int sockfd, const SocketAddress& addr);
+
+ /* Throws ServerError on error */
+ void get_peer_name_as_socket_address(int sockfd, SocketAddress& res);
+}
+
+#endif
diff --git a/src/http_server/nytl_tests/HypertextPages/test.nytl.html b/src/http_server/misc_tests/HypertextPages/test.nytl.html
similarity index 100%
rename from src/http_server/nytl_tests/HypertextPages/test.nytl.html
rename to src/http_server/misc_tests/HypertextPages/test.nytl.html
diff --git a/src/http_server/misc_tests/sockaddr_parse_test.cpp b/src/http_server/misc_tests/sockaddr_parse_test.cpp
new file mode 100644
index 0000000..39a44a2
--- /dev/null
+++ b/src/http_server/misc_tests/sockaddr_parse_test.cpp
@@ -0,0 +1,72 @@
+#include
+#include
+
+using namespace een9;
+
+void test(const std::string& test, bool is_correct, SocketAddressParser& parser) {
+#define fup printf("Test failed\n"); fflush(stdout); abort(); return;
+ SocketAddress addr;
+ int ret = parse_socket_address(test, addr, parser);
+ if ((ret == 0) != is_correct) {
+ fup
+ }
+ if (is_correct) {
+ std::string back = stringify_socket_address(addr);
+ if (make_uppercase(test) != make_uppercase(back)){
+ fup
+ }
+ }
+ printf("Test passed\n");
+}
+
+void test_dcs(const std::string& test, const std::string& need, SocketAddressParser& parser) {
+ SocketAddress addr;
+ int ret = parse_socket_address(test, addr, parser);
+ if (ret != 0) {
+ fup
+ }
+ std::string right = stringify_socket_address(addr);
+ if (right != need) {
+ fup
+ }
+ printf("Test passed\n");
+}
+
+int main() {
+ SocketAddressParser parser;
+ test("[12::12:0:0:0]:600", true, parser);
+ test("[12::12:0:FFFF:0]:600", true, parser);
+ test("[12::11:1]:600", true, parser);
+ test("[::a::]:600", false, parser);
+ test("[FFd:1:1:1:1:FFd:1:f]:65535", true, parser);
+ test("[f:f:f:f:f:0:1:f]:65535", true, parser);
+ test("[1:1:1:1:1:0:1:0]:11212", true, parser);
+ test("[1:1:1:1:1:1:1:1]:1", true, parser);
+ test("[1:1:1:1:1:0:1:0]:65536", false, parser);
+ test("[1:1:1:1:1:0:1:0]:65535", true, parser);
+ test("[1:H:1:1:1:FFd:1:f]:65535", false, parser);
+
+ test("[::]:1", true, parser);
+ test("12.11.11.123:312", true, parser);
+ test("0.1.111.123:31212", true, parser);
+ test("0.1.111.123:65536", false, parser);
+ test("0.1.111.123:65535", true, parser);
+ test("0.1.111.255:65535", true, parser);
+ test("255.0.255.255:65535", true, parser);
+ test("255.0.256.0:65535", false, parser);
+ test("255.0.1000.0:65535", false, parser);
+ test("255.0.01.0:65535", false, parser);
+ test("255.0.1.0:605535", false, parser);
+ test("2.0.1.0:05535", false, parser);
+ test("255.0.1.0::65535", false, parser);
+ test(".255.0.1.0::65535", false, parser);
+ test("..0.1.0::65535", false, parser);
+ test("[FFFF0::]:0", false, parser);
+ test("[0::01:]:0", false, parser);
+ test("[0:fa:ffff::]:0", true, parser);
+ test("[::a:a:a:a:a:a:b]:10", false, parser);
+ test_dcs("[0:0:0:0:0:0:0:0]:413", "[::]:413", parser);
+ test_dcs("[::0:0:0:0]:413", "[::]:413", parser);
+ test_dcs("[::0:0:0:0:0:0]:413", "[::]:413", parser);
+ test_dcs("[::a:a:0:0:0:0]:413", "[0:0:a:a::]:413", parser);
+}
\ No newline at end of file
diff --git a/src/http_server/nytl_tests/test0.cpp b/src/http_server/misc_tests/test0.cpp
similarity index 100%
rename from src/http_server/nytl_tests/test0.cpp
rename to src/http_server/misc_tests/test0.cpp
diff --git a/src/http_server/new_york_transit_line/templater.cpp b/src/http_server/new_york_transit_line/templater.cpp
index e139811..fa613af 100644
--- a/src/http_server/new_york_transit_line/templater.cpp
+++ b/src/http_server/new_york_transit_line/templater.cpp
@@ -100,7 +100,7 @@ namespace nytl {
while ((ret = (int)read(fd, buf, 2048)) > 0) {
size_t oldN = result.size();
result.resize(oldN + ret);
- memcpy((void*)&result.c_str()[oldN], buf, ret);
+ memcpy(result.data() + oldN, buf, ret);
}
if (ret < 0) {
close(fd);
diff --git a/src/http_server/nytl_tests/HypertextPages/c.txt b/src/http_server/nytl_tests/HypertextPages/c.txt
deleted file mode 100644
index 69fdca1..0000000
--- a/src/http_server/nytl_tests/HypertextPages/c.txt
+++ /dev/null
@@ -1,4 +0,0 @@
- AAA
- {% FOR _:val IN cba %}
- TUTUTUTUTUTUTUTUN {% PUT jesccomp val %}
- {% ENDFOR %}
\ No newline at end of file
diff --git a/src/web_chat/initialize.cpp b/src/web_chat/initialize.cpp
index f0a613f..80e90ba 100644
--- a/src/web_chat/initialize.cpp
+++ b/src/web_chat/initialize.cpp
@@ -57,7 +57,7 @@ void sqlite_single_statement(sqlite3* db_hand, const std::string& req_statement)
printf("NULL | ");
} else {
const unsigned char* text = sqlite3_column_text(stmt_obj, i);
- een9_ASSERT(sqlite3_errcode(db_hand) != SQLITE_NOMEM, "oom in sqlite3_column_text");
+ een9_ASSERT(text, "oom in sqlite3_column_text");
printf("%s | ", (const char*)text);
// todo: THIS F. B.S. IS NOT SAFE
}
diff --git a/src/web_chat/main.cpp b/src/web_chat/main.cpp
index afaed49..ad794a1 100644
--- a/src/web_chat/main.cpp
+++ b/src/web_chat/main.cpp
@@ -16,7 +16,7 @@ int main(int argc, char** argv){
if (argc != 1 + 2)
usage(argv);
std::string config_file = argv[1];
- if (!een9::isRegularFile(config_file) || !een9::endsIn(config_file, ".json")) {
+ if (!een9::isRegularFile(config_file) || !een9::endsWith(config_file, ".json")) {
printf("\"%s\" is not a json file\n", argv[1]);
usage(argv);
}
diff --git a/src/web_chat/run.cpp b/src/web_chat/run.cpp
index eb1a3a0..87a558a 100644
--- a/src/web_chat/run.cpp
+++ b/src/web_chat/run.cpp
@@ -9,7 +9,7 @@
#include
#include
#include
-
+#include
bool termination = false;
@@ -17,87 +17,93 @@ void sigterm_action(int) {
termination = true;
}
-std::string unsafe_client_request_stringification(const een9::ClientRequest& req) {
- std::string text = "\n\nGot some cool stuff\n";
- text += (req.method + " " + req.uri_path + " " + req.http_version + "\n");
- for (auto& p: req.headers) {
- text += p.first; text += ": "; text += p.second; text += "\n";
- }
- text += "Body\n"; text += req.body; text += "\n";
- return text;
-}
-
-
void run_website(const json::JSON& config) {
- een9_ASSERT(config["assets"].g().isString(), "config[\"\assets\"] is not string");
+ een9_ASSERT(config["assets"].g().isString(), "config[\"assets\"] is not string");
std::string assets_dir = config["assets"].g().asString();
een9_ASSERT(een9::isDirectory(assets_dir), "\"" + assets_dir + "\" is not a directory");
een9::StaticAssetManagerSlaveModule samI;
- samI.update({
- een9::StaticAssetManagerRule{assets_dir + "/css", "/assets/css", {{".css", "text/css"}} },
- een9::StaticAssetManagerRule{assets_dir + "/js", "/assets/js", {{".js", "text/js"}} },
- een9::StaticAssetManagerRule{assets_dir + "/img", "/assets/img", {
- {".jpg", "image/jpg"}, {".png", "image/png"}, {".svg", "image/svg+xml"}
- } },
- });
+ samI.update({
+ een9::StaticAssetManagerRule{assets_dir + "/css", "/assets/css", {{".css", "text/css"}} },
+ een9::StaticAssetManagerRule{assets_dir + "/js", "/assets/js", {{".js", "text/js"}} },
+ een9::StaticAssetManagerRule{assets_dir + "/img", "/assets/img", {
+ {".jpg", "image/jpg"}, {".png", "image/png"}, {".svg", "image/svg+xml"}
+ } },
+ });
- const json::JSON& config_presentation = config["presentation"].g();
+ const json::JSON& config_presentation = config["presentation"].g();
+ int64_t slave_number = config["server"]["workers"].g().asInteger().get_int();
+ een9_ASSERT(slave_number > 0 && slave_number <= 200, "E");
+ struct WorkerGuestData {
/* Because templaters use libjsonincpp, they can't be READ by two thread simultaneously */
- std::vector> templaters_copies(8);
- for (int i = 0; i < 8; i++) {
- templaters_copies[i] = std::make_unique(
- nytl::TemplaterSettings{nytl::TemplaterDetourRules{assets_dir + "/HypertextPages"}});
- templaters_copies[i]->update();
- }
+ een9::uptr templater;
+ };
+ std::vector worker_guest_data;
+ for (int i = 0; i < slave_number; i++) {
+ worker_guest_data[i].templater = std::make_unique(
+ nytl::TemplaterSettings{nytl::TemplaterDetourRules{assets_dir + "/HypertextPages"}});
+ worker_guest_data[i].templater->update();
+ }
- // printf("%s\n", templaters_copies[0]->render("list-rooms", {&config_presentation}).c_str());
- // return 0;
-
- een9::MainloopParameters params;
- params.guest_core = [&samI, &templaters_copies, config_presentation]
- (const een9::SlaveTask& task, const een9::ClientRequest& req, een9::worker_id_t worker_id) -> std::string {
- een9_ASSERT_pl(0 <= worker_id && worker_id < templaters_copies.size());
- nytl::Templater& templater = *templaters_copies[worker_id];
- een9::StaticAsset sa;
- int ret;
- // printf("%s", unsafe_client_request_stringification(req).c_str());
- // if (req.uri_path == "/output") {
- // std::string text = unsafe_client_request_stringification(req);
- // return een9::form_http_server_response_200("text/plain", text);
- // }
- auto rteee = [&](const std::string& el_name, bool pass_phr) -> std::string {
- std::string page = templater.render(el_name,
- pass_phr ? std::vector{&config_presentation} : std::vector{});
- return een9::form_http_server_response_200("text/html", page);
- };
- if (req.uri_path == "/" || req.uri_path == "/list-rooms") {
- return rteee("list-rooms", true);
- }
- if (req.uri_path == "/chat") {
- return rteee("chat", false);
- }
- if (req.uri_path == "/profile") {
- return rteee("profile", false);
- }
- if (req.uri_path == "/registration") {
- return rteee("registration", false);
- }
- /* Trying to interpret request as asset lookup */
- ret = samI.get_asset(req.uri_path, sa);
- if (ret >= 0) {
- return een9::form_http_server_response_200(sa.type, sa.content);
- }
- return een9::form_http_server_response_404("text/html", " Not found!
");
+ een9::MainloopParameters params;
+ params.guest_core = [&samI, &worker_guest_data, config_presentation]
+ (const een9::SlaveTask& task, const een9::ClientRequest& req, een9::worker_id_t worker_id) -> std::string {
+ een9_ASSERT_pl(0 <= worker_id && worker_id < worker_guest_data.size());
+ nytl::Templater& templater = *worker_guest_data[worker_id].templater;
+ een9::StaticAsset sa;
+ int ret;
+ auto rteee = [&](const std::string& el_name, bool pass_phr) -> std::string {
+ std::string page = templater.render(el_name,
+ pass_phr ? std::vector{&config_presentation} : std::vector{});
+ return een9::form_http_server_response_200("text/html", page);
};
+ if (req.uri_path == "/" || req.uri_path == "/list-rooms") {
+ return rteee("list-rooms", true);
+ }
+ if (req.uri_path == "/chat") {
+ return rteee("chat", false);
+ }
+ if (req.uri_path == "/profile") {
+ return rteee("profile", false);
+ }
+ if (req.uri_path == "/registration") {
+ return rteee("registration", false);
+ }
+ /* Trying to interpret request as asset lookup */
+ ret = samI.get_asset(req.uri_path, sa);
+ if (ret >= 0) {
+ return een9::form_http_server_response_200(sa.type, sa.content);
+ }
+ return een9::form_http_server_response_404("text/html", " Not found!
");
+ };
- params.ports_to_listen = {1025};
- params.slave_number = 8;
- params.open_admin_listener = false;
+ params.guest_core_admin_control = []
+ (const een9::SlaveTask& task, const std::string& req, een9::worker_id_t) -> std::string {
+ if (req == "hello") {
+ return ":0 omg! hiii!! Hewwou :3 !!!!";
+ } if (req == "8") {
+ termination = true;
+ return "Bye";
+ } else {
+ return "Incorrect command";
+ }
+ };
- signal(SIGINT, sigterm_action);
- signal(SIGTERM, sigterm_action);
+ params.slave_number = slave_number;
- een9::electric_boogaloo(params, termination);
+ een9::SocketAddressParser sap;
+ auto translate_addr_list_conf = [&sap](std::vector& dest, const std::vector& source) {
+ size_t N = source.size();
+ dest.resize(N);
+ for (size_t i = 0; i < N; i++)
+ een9::parse_socket_address(source[i].asString(), dest[i], sap);
+ };
+ translate_addr_list_conf(params.client_regular_listened, config["server"]["http-listen"].g().asArray());
+ translate_addr_list_conf(params.admin_control_listened, config["server"]["admin-command-listen"].g().asArray());
+
+ signal(SIGINT, sigterm_action);
+ signal(SIGTERM, sigterm_action);
+
+ een9::electric_boogaloo(params, termination);
}
\ No newline at end of file