fixed some bugs, made an utility to send admin commands to server, added both http listeners and admin-cmd listeners. Command "8" to shutdown the server. And the most important: IU9 CA Web Chat can now talk like a mentally ill teenager (command "hello" (gonna delete this later))
This commit is contained in:
parent
4d18d13a93
commit
6be78c1510
@ -79,6 +79,7 @@ struct CAWebChat {
|
||||
"running_mainloop.cpp",
|
||||
"form_data_structure/urlencoded_query.cpp",
|
||||
"socket_address.cpp",
|
||||
"admin_control.cpp",
|
||||
};
|
||||
for (std::string& u: T.units)
|
||||
u = "http_server/engine_engine_number_9/" + u;
|
||||
@ -143,11 +144,24 @@ struct CAWebChat {
|
||||
"find_db.cpp",
|
||||
};
|
||||
for (std::string& u: T.units)
|
||||
u = "web_chat/" + u;
|
||||
u = "web_chat/iu9_ca_web_chat_service/" + u;
|
||||
T.include_pr = "web_chat";
|
||||
T.installation_dir = "";
|
||||
my_targets.push_back(T);
|
||||
}
|
||||
{ CTarget T{"iu9-ca-web-chat-admin-cli", "executable"};
|
||||
T.additional_compilation_flags = getSomeRadFlags();
|
||||
T.proj_deps = {
|
||||
CTargetDependenceOnProjectsLibrary{"engine_engine_number_9"},
|
||||
};
|
||||
T.units = {
|
||||
"cli.cpp", // Main file
|
||||
};
|
||||
for (std::string& u: T.units)
|
||||
u = "web_chat/iu9_ca_web_chat_admin_cli/" + u;
|
||||
T.include_pr = "web_chat";
|
||||
my_targets.push_back(T);
|
||||
}
|
||||
regular_ctargets_to_2bus_conversion(ext_targets, my_targets, runlevel_1, runlevel_2,
|
||||
cmd.project_root, cmd.installation_root);
|
||||
}
|
||||
|
@ -27,10 +27,10 @@ namespace een9 {
|
||||
return status;
|
||||
}
|
||||
body.reserve(b_sz);
|
||||
} else if (body.size() < b_sz) {
|
||||
body += ch;
|
||||
} else {
|
||||
status = 1;
|
||||
body += ch;
|
||||
if (body.size() >= b_sz)
|
||||
status = 1;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
@ -42,7 +42,7 @@ namespace een9 {
|
||||
}
|
||||
|
||||
std::string generate_ac_msg_gen_case(const std::string& content, const char* ms) {
|
||||
std::string result;
|
||||
std::string result = ms;
|
||||
uint64_t N = content.size();
|
||||
for (int i = 0; i < 8; i++) {
|
||||
result += (char)(uint8_t)((N & 0xff00000000000000) >> 56);
|
||||
|
@ -100,14 +100,14 @@ namespace een9 {
|
||||
assert(parser.status == 0);
|
||||
while ((ret = (int)recv(fd, buf, 2048, 0)) > 0) {
|
||||
for (size_t i = 0; i < ret; i++) {
|
||||
if (parser.feedCharacter(buf[i]) > 0)
|
||||
if (parser.feedCharacter(buf[i]) != 0)
|
||||
break;
|
||||
}
|
||||
if (parser.status > 0)
|
||||
if (parser.status != 0)
|
||||
break;
|
||||
}
|
||||
ASSERT(parser.status == 1, "Incorrect request"); // todo: do the same thing everywhere else
|
||||
ASSERT_on_iret(ret, "recv");
|
||||
assert(parser.status == 1);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -130,27 +130,33 @@ namespace een9 {
|
||||
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)
|
||||
if (pctx.feedCharacter(buf[i]) != 0)
|
||||
break;
|
||||
}
|
||||
if (pctx.status > 0)
|
||||
if (pctx.status != 0)
|
||||
break;
|
||||
}
|
||||
ASSERT(pctx.status == 1, "Incorrect request");
|
||||
ASSERT_on_iret(ret, "recv");
|
||||
assert(pctx.status == 1);
|
||||
return pctx.body;
|
||||
}
|
||||
|
||||
void process_connection(const SlaveTask& task, WorkersEnv& wte) {
|
||||
if (task.conn_info.type == 0) {
|
||||
printf("%d::Got http reuest\n", wte.id);
|
||||
ClientRequest client_request = process_http_connection_input(task.fd(), task.s_tips, wte);
|
||||
printf("%d::Http request has been read\n", wte.id);
|
||||
std::string server_response = wte.wtec.guest_core(task, client_request, wte.id);
|
||||
process_connection_output(task.fd(), server_response);
|
||||
printf("%d::Http response has been sent\n", wte.id);
|
||||
} else if (task.conn_info.type == 1) {
|
||||
printf("%d::Got admin-cmd request\n", wte.id);
|
||||
std::string admin_request = process_admin_control_connection_input(task.fd(), task.s_tips, wte);
|
||||
printf("%d::Admin-cmd request has been read\n", wte.id);
|
||||
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);
|
||||
printf("%d::Admin-cmd response has been sent\n", wte.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -254,16 +254,12 @@ namespace een9 {
|
||||
}
|
||||
|
||||
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);
|
||||
sa_family_t f = addr.v.gen.sa_family;
|
||||
if (f == AF_INET || f == AF_INET6 || f == AF_UNIX) {
|
||||
int ret = bind(sockfd, &addr.v.gen, addr.addrLen);
|
||||
ASSERT_on_iret(ret, "binding socket");
|
||||
} 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) {
|
||||
@ -273,4 +269,9 @@ namespace een9 {
|
||||
assert(willbecome <= sizeof(res.v));
|
||||
res.addrLen = willbecome;
|
||||
}
|
||||
|
||||
void connect_to_socket_address(int sockfd, const SocketAddress& targ) {
|
||||
int ret = connect(sockfd, &targ.v.gen, targ.addrLen);
|
||||
ASSERT_on_iret(ret, "connect socket to addr");
|
||||
}
|
||||
}
|
||||
|
@ -32,8 +32,8 @@ namespace een9 {
|
||||
void* opaque = NULL;
|
||||
|
||||
SocketAddressParser();
|
||||
SocketAddressParser(const SocketAddressParser&) = default;
|
||||
SocketAddressParser& operator=(const SocketAddressParser&) = default;
|
||||
SocketAddressParser(const SocketAddressParser&) = delete;
|
||||
SocketAddressParser& operator=(const SocketAddressParser&) = delete;
|
||||
~SocketAddressParser();
|
||||
};
|
||||
|
||||
@ -46,6 +46,8 @@ namespace een9 {
|
||||
|
||||
/* Throws ServerError on error */
|
||||
void get_peer_name_as_socket_address(int sockfd, SocketAddress& res);
|
||||
|
||||
void connect_to_socket_address(int sockfd, const SocketAddress& targ);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -34,6 +34,7 @@ void test_dcs(const std::string& test, const std::string& need, SocketAddressPar
|
||||
|
||||
int main() {
|
||||
SocketAddressParser parser;
|
||||
test("127:0:0:1:1026", false, 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);
|
||||
|
81
src/web_chat/iu9_ca_web_chat_admin_cli/cli.cpp
Normal file
81
src/web_chat/iu9_ca_web_chat_admin_cli/cli.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <engine_engine_number_9/admin_control.h>
|
||||
#include <engine_engine_number_9/socket_address.h>
|
||||
#include <engine_engine_number_9/baza_throw.h>
|
||||
#include <assert.h>
|
||||
#include <engine_engine_number_9/os_utils.h>
|
||||
|
||||
/* This so called 'een9::admin-control' protocol is very simple:
|
||||
* Admin sends request to server:
|
||||
* <Magic constant string> <8 byte field: size of body> <body (string of any characters)>
|
||||
* Server reads it to the end and sents response to admin:
|
||||
* <Magic constant string> <8 byte field: size of body> <body (string of any characters)>
|
||||
* More can be found in src/http_server/engine_engine_number_9/admin_control.cpp
|
||||
*/
|
||||
|
||||
void send_request_msg(int fd, const std::string& request_msg) {
|
||||
std::string str = een9::generate_admin_control_request(request_msg);
|
||||
size_t N = str.size(), i = 0;
|
||||
while (i < N) {
|
||||
int written = (int)send(fd, &str[i], std::min(2048lu, N - i), MSG_NOSIGNAL);
|
||||
een9_ASSERT_on_iret(written, "sending");
|
||||
een9_ASSERT_pl(written > 0);
|
||||
i += written;
|
||||
}
|
||||
}
|
||||
|
||||
std::string receive_response_msg(int fd) {
|
||||
een9::AdminControlResponseRCtx 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;
|
||||
}
|
||||
een9_ASSERT(pctx.status == 1, "Received incorrect response");
|
||||
een9_ASSERT_on_iret(ret, "recv");
|
||||
return pctx.body;
|
||||
}
|
||||
|
||||
void usage(char* za) {
|
||||
printf("%s <address of servers admin cmd listener> <message> [<other parts of message> ...]\n", za);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc < 1)
|
||||
return 134;
|
||||
if (argc < 3) {
|
||||
usage(argv[0]);
|
||||
}
|
||||
try {
|
||||
std::string conn_addr_targ = argv[1];
|
||||
std::string msg;
|
||||
for (int i = 2; i < argc; i++) {
|
||||
if (!msg.empty())
|
||||
msg += '\n';
|
||||
msg += argv[i];
|
||||
}
|
||||
int ret;
|
||||
een9::SocketAddressParser sap;
|
||||
een9::SocketAddress addr;
|
||||
ret = een9::parse_socket_address(conn_addr_targ, addr, sap);
|
||||
een9_ASSERT(ret == 0, "Incorrect address");
|
||||
int sock = socket(addr.v.gen.sa_family, SOCK_STREAM, 0);
|
||||
een9_ASSERT_on_iret(sock, "creating socket to target server");
|
||||
een9::UniqueFdWrapper sockGuard(sock);
|
||||
een9::connect_to_socket_address(sock, addr);
|
||||
printf("Ready to send request\n");
|
||||
send_request_msg(sock, msg);
|
||||
printf("Admin-cmd request has been sent\n");
|
||||
std::string answer = receive_response_msg(sock);
|
||||
printf("Admin-cmd response has been read\n");
|
||||
printf("Successfull command\n%s", answer.c_str());
|
||||
} catch (const std::exception& e) {
|
||||
printf("%s\n", e.what());
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
#include "str_fields_check.h"
|
||||
#include <sqlite3.h>
|
||||
#include <engine_engine_number_9/os_utils.h>
|
||||
#include <find_db.h>
|
||||
#include "find_db.h"
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -45,14 +45,14 @@ void sqlite_single_statement(sqlite3* db_hand, const std::string& req_statement)
|
||||
printf("Values: | ");
|
||||
for (int i = 0; i < cc; i++) {
|
||||
if (types[i] == SQLITE_INTEGER) {
|
||||
printf("%ld | ", sqlite3_column_int64(stmt_obj, i));
|
||||
printf("%lld | ", sqlite3_column_int64(stmt_obj, i));
|
||||
} else if (types[i] == SQLITE_FLOAT) {
|
||||
printf("%lf | ", sqlite3_column_double(stmt_obj, i));
|
||||
} else if (types[i] == SQLITE_BLOB) {
|
||||
const void* blob = sqlite3_column_blob(stmt_obj, i);
|
||||
een9_ASSERT(sqlite3_errcode(db_hand) == SQLITE_OK, "oom in sqlite3_column_blob");
|
||||
size_t sz = sqlite3_column_bytes(stmt_obj, i);
|
||||
printf("Blob of size %s | ", sz);
|
||||
printf("Blob of size %lu | ", sz);
|
||||
} else if (types[i] == SQLITE_NULL) {
|
||||
printf("NULL | ");
|
||||
} else {
|
@ -5,20 +5,21 @@
|
||||
#include "actions.h"
|
||||
#include <stdexcept>
|
||||
|
||||
void usage(char** argv) {
|
||||
printf("Usage: %s <file with settings> <run|initialize>\n", argv[0]);
|
||||
void usage(char* argv0) {
|
||||
printf("Usage: %s <file with settings> <run|initialize>\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv){
|
||||
try {
|
||||
een9_ASSERT_pl(argc > 0);
|
||||
if (argc < 1)
|
||||
return 111;
|
||||
if (argc != 1 + 2)
|
||||
usage(argv);
|
||||
usage(argv[0]);
|
||||
std::string config_file = argv[1];
|
||||
if (!een9::isRegularFile(config_file) || !een9::endsWith(config_file, ".json")) {
|
||||
printf("\"%s\" is not a json file\n", argv[1]);
|
||||
usage(argv);
|
||||
usage(argv[0]);
|
||||
}
|
||||
std::string cmd = argv[2];
|
||||
std::string config_text;
|
@ -39,7 +39,7 @@ void run_website(const json::JSON& config) {
|
||||
/* Because templaters use libjsonincpp, they can't be READ by two thread simultaneously */
|
||||
een9::uptr<nytl::Templater> templater;
|
||||
};
|
||||
std::vector<WorkerGuestData> worker_guest_data;
|
||||
std::vector<WorkerGuestData> worker_guest_data(slave_number);
|
||||
for (int i = 0; i < slave_number; i++) {
|
||||
worker_guest_data[i].templater = std::make_unique<nytl::Templater>(
|
||||
nytl::TemplaterSettings{nytl::TemplaterDetourRules{assets_dir + "/HypertextPages"}});
|
Loading…
Reference in New Issue
Block a user