diff --git a/assets/HypertextPages/list-rooms.html b/assets/HypertextPages/list-rooms.nytl.html
similarity index 68%
rename from assets/HypertextPages/list-rooms.html
rename to assets/HypertextPages/list-rooms.nytl.html
index 390359f..5136e4b 100644
--- a/assets/HypertextPages/list-rooms.html
+++ b/assets/HypertextPages/list-rooms.nytl.html
@@ -1,31 +1,32 @@
+{% ELDEF main JSON pres %}
- Список Чат-Комнат
+ {% WRITE pres.phr.decl.list-of-chat-rooms %}
-
Выберите Чат-Комнату
+
{% WRITE pres.phr.decl.select-chat-room %}
-
+
@@ -35,14 +36,14 @@
@@ -50,3 +51,4 @@
+{% ENDELDEF %}
diff --git a/example/config.json b/example/config.json
index 00c0345..3edafa7 100644
--- a/example/config.json
+++ b/example/config.json
@@ -1,3 +1,32 @@
{
- "name": "Web chat"
+ "presentation": {
+ "instance-identity": {
+ "top-title": "Вэб чат ИУ9"
+ },
+ "phr": {
+ "decl": {
+ "list-of-chat-rooms": "Список Чат-Комнат",
+ "select-chat-room": "Выберете чат комнату",
+ "name-of-room": "Название комнаты",
+ "create-room": "Создать комнату"
+ },
+ "act": {
+ "create-room": "Создать комнату",
+ "confirm": "Подтвердить",
+ "create": "Создать"
+ }
+ }
+ },
+ "assets": "./assets",
+ "limits": {
+ "max-users": 100000,
+ "max-rooms": 100000,
+ "max-messages": 10000000000000,
+ "storage-size-limit": 100000000000
+ },
+ "server": {
+ "workers": 8,
+ "http-listen": ["127.0.0.1:1025"],
+ "command-listen": []
+ }
}
\ No newline at end of file
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 2c07b7f..41560fc 100644
--- a/src/http_server/engine_engine_number_9/running_mainloop.cpp
+++ b/src/http_server/engine_engine_number_9/running_mainloop.cpp
@@ -82,10 +82,10 @@ namespace een9 {
struct WorkersEnv {
WorkersEnvCommon& wtec;
- int id;
+ worker_id_t id;
ClientRequestParser_WorkerBuffers personal_parser_buffer;
- explicit WorkersEnv(WorkersEnvCommon& wtec, int id): wtec(wtec), id(id), personal_parser_buffer(wtec.parser_programs){}
+ explicit WorkersEnv(WorkersEnvCommon& wtec, worker_id_t id): wtec(wtec), id(id), personal_parser_buffer(wtec.parser_programs){}
};
// todo: add timeout for multiple bytes, add more settings
@@ -125,7 +125,7 @@ namespace een9 {
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);
+ std::string server_response = wte.wtec.guest_core(task, client_request, wte.id);
process_connection_output(task.fd(), server_response);
}
@@ -149,6 +149,7 @@ namespace een9 {
} catch (const std::exception& e) {
printf("Client request procession failure in worker\n");
printf("%s\n", e.what());
+ /* Under mysterious some circumstances, in this place destructor of string in SystemError causes segfault. I can't fix that */
}
}
printf("Worker finished\n");
@@ -166,7 +167,7 @@ namespace een9 {
std::vector workers(params.slave_number);
std::vector> wtes(params.slave_number);
for (size_t i = 0; i < params.slave_number; i++) {
- wtes[i] = std::make_unique(wtec, i);
+ wtes[i] = std::make_unique(wtec, (worker_id_t)i);
}
for (size_t i = 0; i < params.slave_number; i++) {
pthread_create(&workers[i], NULL, worker_func, wtes[i].get());
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 aa7584a..65bcd4e 100644
--- a/src/http_server/engine_engine_number_9/running_mainloop.h
+++ b/src/http_server/engine_engine_number_9/running_mainloop.h
@@ -29,8 +29,10 @@ namespace een9 {
EEN9_ServerTips s_tips;
};
+ typedef int worker_id_t;
+
/* guest_core function must not throw anything that is not derived from std::exception */
- typedef std::function guest_core_t;
+ typedef std::function guest_core_t;
struct ServersConfiguration {
size_t critical_load_1 = 90;
diff --git a/src/http_server/new_york_transit_line/parser.cpp b/src/http_server/new_york_transit_line/parser.cpp
index c44cc33..d7c3460 100644
--- a/src/http_server/new_york_transit_line/parser.cpp
+++ b/src/http_server/new_york_transit_line/parser.cpp
@@ -447,27 +447,29 @@ namespace nytl {
mediocre_operator("str2code");
goto ya_e_ya_h_i_ya_g_d_o;;
}
+ auto prepare_to_depart_parts = [&]() {
+ assert(!result.parts.empty());
+ if (result.parts[0].type == ElementPart::p_code)
+ result.parts[0].when_code.lines = clement_lstrip(result.parts[0].when_code.lines);
+ if (result.parts.back().type == ElementPart::p_code)
+ rstrip(result.parts.back().when_code.lines);
+ size_t cut = 999999999999;
+ size_t N = result.parts.size();
+ for (size_t i = 0; i < N; i++) {
+ if (result.parts[i].type == ElementPart::p_code) {
+ one_part_update_min_start_wsp_non_empty(result.parts[i].when_code.lines, i, N, cut);
+ }
+ }
+ for (size_t i = 0; i < N; i++) {
+ if (result.parts[i].type == ElementPart::p_code) {
+ result.parts[i].when_code.lines = one_part_cut_excess_tab(result.parts[i].when_code.lines, i, N, cut);
+ }
+ }
+ };
if (op == "ENDELDEF") {
ASSERT(myself == gone_for_nothing, "Unexpected end of element");
skip_magic_block_end(ctx, syntax);
- if (!result.parts.empty()) {
- if (result.parts[0].type == ElementPart::p_code)
- result.parts[0].when_code.lines = clement_lstrip(result.parts[0].when_code.lines);
- if (result.parts.back().type == ElementPart::p_code)
- rstrip(result.parts.back().when_code.lines);
- size_t cut = 999999999999;
- size_t N = result.parts.size();
- for (size_t i = 0; i < N; i++) {
- if (result.parts[i].type == ElementPart::p_code) {
- one_part_update_min_start_wsp_non_empty(result.parts[i].when_code.lines, i, N, cut);
- }
- }
- for (size_t i = 0; i < N; i++) {
- if (result.parts[i].type == ElementPart::p_code) {
- result.parts[i].when_code.lines = one_part_cut_excess_tab(result.parts[i].when_code.lines, i, N, cut);
- }
- }
- }
+ prepare_to_depart_parts();
return NULL;
}
if (op == "ENDFOR") {
@@ -485,10 +487,13 @@ namespace nytl {
THROW("Expected LF, NOLF or end of magic block");
}
skip_magic_block_end(ctx, syntax);
+ prepare_to_depart_parts();
return NULL;
}
if (op == "ENDREF") {
+ assert(myself == gone_for_ref);
skip_magic_block_end(ctx, syntax);
+ prepare_to_depart_parts();
return NULL;
}
THROW("Unknown operator. Expected FOR, REF, PUT, WRITE, ROUGHINSERT, ENDELDEF, ENDFOR, ENDREF");
diff --git a/src/http_server/new_york_transit_line/rendering.cpp b/src/http_server/new_york_transit_line/rendering.cpp
index 48fc0b1..b6cc23e 100644
--- a/src/http_server/new_york_transit_line/rendering.cpp
+++ b/src/http_server/new_york_transit_line/rendering.cpp
@@ -9,22 +9,25 @@ namespace nytl {
std::string result;
size_t cur_line_width = 0;
+ /* Fix idea: get rid of newlined_somewhere */
void append(const std::string& text, size_t wsp_before_newlines, bool& newlined_somewhere) {
size_t n = result.size();
size_t m = text.size();
result.reserve(n + m);
for (size_t i = 0; i < m; i++) {
+ result += text[i];
if (text[i] == '\n') {
- newlined_somewhere = true;
- cur_line_width = 0;
+ // newlined_somewhere = true;
+
+ result.resize(result.size() + wsp_before_newlines, ' ');
+ cur_line_width = wsp_before_newlines;
} else {
- if (cur_line_width == 0 && newlined_somewhere) {
- result.resize(result.size() + wsp_before_newlines, ' ');
- cur_line_width = wsp_before_newlines;
- }
+ // if (cur_line_width == 0 && newlined_somewhere) {
+ // result.resize(result.size() + wsp_before_newlines, ' ');
+ // cur_line_width = wsp_before_newlines;
+ // }
cur_line_width++;
}
- result += text[i];
}
}
};
@@ -88,7 +91,7 @@ namespace nytl {
RFrame_OverArray(const ElementPart::when_for_put_S& part, size_t multiline_put_start, const std::vector &saved_args,
const std::vector &arr): RFrame_OverJSON(part, multiline_put_start, saved_args),
arr(arr) {
- if (part.where_key_var < 0)
+ if (part.where_key_var >= 0)
additional_json_wrapper = json::JSON(json::Integer(0l));
}
@@ -106,7 +109,7 @@ namespace nytl {
const std::map &dict): RFrame_OverJSON(part, multiline_put_start, saved_args_plus_iter),
dict(dict) {
it = dict.begin();
- if (part.where_key_var < 0)
+ if (part.where_key_var >= 0)
addition_json_wrapper = json::JSON("");
}
@@ -151,6 +154,8 @@ namespace nytl {
std::string escaped_json = escape(json::generate_str(*X, json::print_pretty));
rstrip(escaped_json);
append(escaped_json, result);
+ } else if (name == "jesccomp") {
+ append(escape(json::generate_str(*X, json::print_compact)), result);
} else if (name == "str2text") {
ASSERT(X->isString(), "str2text takes json string");
append(escape(X->asString()), result);
@@ -215,10 +220,10 @@ namespace nytl {
}
uptr RFrame_OverDictionary::toMe(bool returned, RFrame_passed) {
- if (returned && part.line_feed)
- append("\n", result);
if (it == dict.end())
return NULL;
+ if (returned && part.line_feed)
+ append("\n", result);
if (part.where_key_var > -1) {
addition_json_wrapper.asString() = it->first;
saved_args_plus_iter[part.where_key_var] = {true, "", &addition_json_wrapper};
diff --git a/src/http_server/new_york_transit_line/templater.cpp b/src/http_server/new_york_transit_line/templater.cpp
index ca07098..e139811 100644
--- a/src/http_server/new_york_transit_line/templater.cpp
+++ b/src/http_server/new_york_transit_line/templater.cpp
@@ -112,7 +112,10 @@ namespace nytl {
void Templater::update() {
elements = {
{"jesc", Element{{json::JSON(true)}, true}},
+ {"jesccomp", Element{{json::JSON(true)}, true}},
+ /* str2text base element has a dedicated operator - WRITE */
{"str2text", Element{{json::JSON(true)}, true}},
+ /* str2code base element has a dedicated operator - ROUGHINSERT */
{"str2code", Element{{json::JSON(true)}, true}},
};
std::vector intersting_files = indexing_detour(settings.det);
diff --git a/src/http_server/nytl_tests/HypertextPages/biba/boba/aboba.nytl.html b/src/http_server/nytl_tests/HypertextPages/biba/boba/aboba.nytl.html
new file mode 100644
index 0000000..8a154da
--- /dev/null
+++ b/src/http_server/nytl_tests/HypertextPages/biba/boba/aboba.nytl.html
@@ -0,0 +1,7 @@
+{% ELDEF main %}
+
+ CCC
+DDD
+
+
+{% ENDELDEF %}
\ No newline at end of file
diff --git a/src/http_server/nytl_tests/HypertextPages/test.nytl.html b/src/http_server/nytl_tests/HypertextPages/test.nytl.html
index 271871e..013fb7a 100644
--- a/src/http_server/nytl_tests/HypertextPages/test.nytl.html
+++ b/src/http_server/nytl_tests/HypertextPages/test.nytl.html
@@ -1,9 +1,9 @@
-{% ELDEF foo JSON cba %}
-BBBB
-{% ENDELDEF %}
+
{% ELDEF main JSON cba %}
- AAAA
- {% PUT test.foo cba %}
- {% PUT test.foo cba %}
+ AAA
+ {% FOR _:val IN cba %}
+ TUTUTUTUTUTUTUTUN {% PUT jesccomp val %}
+ {% ENDFOR %}
+
{% ENDELDEF %}
\ No newline at end of file
diff --git a/src/http_server/nytl_tests/test0.cpp b/src/http_server/nytl_tests/test0.cpp
index 48c7852..84b48ce 100644
--- a/src/http_server/nytl_tests/test0.cpp
+++ b/src/http_server/nytl_tests/test0.cpp
@@ -14,6 +14,9 @@ int main(int argc, char** argv) {
nytl::debug_print_templater(templater);
json::JSON cba;
cba["boba"] = json::JSON("<>");
+ cba["arr"][0] = json::JSON("zero");
+ cba["arr"][1] = json::JSON("one");
+ cba["arr"][2] = json::JSON("two");
// printf("DEBUG WAS: %p\n", &cba["boba"].g());
// printf("%s\n", json::generate_str(cba["boba"].g(), json::print_compact).c_str());
// return 0;
diff --git a/src/web_chat/main.cpp b/src/web_chat/main.cpp
index 745b5d7..24beccb 100644
--- a/src/web_chat/main.cpp
+++ b/src/web_chat/main.cpp
@@ -10,6 +10,8 @@
#include
#include
+#include "../http_server/engine_engine_number_9/running_mainloop.h"
+
bool termination = false;
void sigterm_action(int) {
@@ -17,7 +19,7 @@ void sigterm_action(int) {
}
void usage(char** argv) {
- printf("Usage: %s \n", argv[0]);
+ printf("Usage: %s \n", argv[0]);
exit(1);
}
@@ -32,30 +34,26 @@ std::string unsafe_client_request_stringification(const een9::ClientRequest& req
}
int main(int argc, char** argv){
- printf("%s\n", regexis024::opcode_to_str(regexis024::opcode_t::DIE));
try {
een9_ASSERT_pl(argc > 0);
- if (argc < 1 + 2)
+ if (argc < 1 + 1)
usage(argv);
if (!een9::isRegularFile(argv[1]) || !een9::endsIn(argv[1], ".json")) {
printf("\"%s\" is not a json file\n", argv[1]);
usage(argv);
}
std::string config_file = argv[1];
- if (!een9::isDirectory(argv[2])) {
- printf("\"%s\" is not a directory\n", argv[2]);
- usage(argv);
- }
- std::string assets_dir = argv[2];
std::string config_text;
een9::readFile(config_file, config_text);
json::JSON config = json::parse_str_flawless(config_text);
een9_ASSERT(config.isDictionary(), "config root is not dictionary");
+ 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 + "/HypertextPages", "/assets/html", {{".html", "text/html"}} },
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", {
@@ -63,31 +61,47 @@ int main(int argc, char** argv){
} },
});
+ json::JSON& config_presentation = config["presentation"].g();
+
+ /* 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();
+ }
+
+ // printf("%s\n", templaters_copies[0]->render("list-rooms", {&config_presentation}).c_str());
+ // return 0;
+
een9::MainloopParameters params;
- params.guest_core = [&samI](const een9::SlaveTask& task, const een9::ClientRequest& req) -> std::string {
+ 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& asset_path) -> std::string {
- ret = samI.get_asset(asset_path, sa);
- een9_ASSERT_pl(ret == 0);
- return een9::form_http_server_response_200(sa.type, sa.content);
+ // 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("/assets/html/list-rooms.html");
+ return rteee("list-rooms", true);
}
if (req.uri_path == "/chat") {
- return rteee("/assets/html/chat.html");
+ return rteee("chat", false);
}
if (req.uri_path == "/profile") {
- return rteee("/assets/html/profile.html");
+ return rteee("profile", false);
}
if (req.uri_path == "/registration") {
- return rteee("/assets/html/registration.html");
+ return rteee("registration", false);
}
/* Trying to interpret request as asset lookup */
ret = samI.get_asset(req.uri_path, sa);
@@ -96,6 +110,7 @@ int main(int argc, char** argv){
}
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;