1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

Embeddable: Create core dbs in proper subdirectory

This commit is contained in:
gnosygnu
2017-10-23 20:50:22 -04:00
parent dc22c15895
commit 1336d44f34
4537 changed files with 0 additions and 311750 deletions

View File

@@ -13,72 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*;
import gplx.core.primitives.*; import gplx.core.js.*;
import gplx.gfui.*; import gplx.gfui.kits.core.*; import gplx.gfui.controls.gxws.*;
import gplx.xowa.apps.servers.tcp.*;
import gplx.xowa.apps.servers.http.*; import gplx.xowa.guis.views.*;
public class Gxw_html_server implements Gxw_html {
private Xosrv_socket_wtr wtr; private Gfo_usr_dlg usr_dlg;
private final Js_wtr js_wtr = new Js_wtr();
public Gxw_html_server(Gfo_usr_dlg usr_dlg, Xosrv_socket_wtr wtr) {
this.usr_dlg = usr_dlg; this.wtr = wtr;
}
public void Html_doc_html_load_by_mem(String html) {Exec_as_str("location.reload(true);");} // HACK: force reload of page
public void Html_doc_html_load_by_url(Io_url path, String html) {Exec_as_str("location.reload(true);");} // HACK: force reload of page
public byte Html_doc_html_load_tid() {return html_doc_html_load_tid;} private byte html_doc_html_load_tid;
public void Html_doc_html_load_tid_(byte v) {html_doc_html_load_tid = v;}
public void Html_dispose() {}
public void Html_js_enabled_(boolean v) {}
public String Html_js_eval_proc_as_str(String name, Object... args) {return Exec_as_str(js_wtr.Write_statement_return_func(name, args).To_str_and_clear());} // TODO_OLD: add other params
public boolean Html_js_eval_proc_as_bool(String name, Object... args) {return Exec_as_bool(js_wtr.Write_statement_return_func(name, args).To_str_and_clear());}
public String Html_js_eval_script(String script) {return Exec_as_str(script);}
public Object Html_js_eval_script_as_obj(String script) {return Exec_as_str(script);}
public void Html_js_cbks_add(String js_func_name, Gfo_invk invk) {}
public String Html_js_send_json(String name, String data) {throw Err_.new_unimplemented();}
public void Html_invk_src_(Gfo_evt_itm v) {}
public GxwCore_base Core() {throw Err_.new_unimplemented();}
public GxwCbkHost Host() {throw Err_.new_unimplemented();} public void Host_set(GxwCbkHost host) {throw Err_.new_unimplemented();}
public Object UnderElem() {throw Err_.new_unimplemented();}
public String TextVal() {throw Err_.new_unimplemented();} public void TextVal_set(String v) {throw Err_.new_unimplemented();}
public void EnableDoubleBuffering() {throw Err_.new_unimplemented();}
private boolean Exec_as_bool(String s) {
Exec_as_str(s);
return true; // NOTE: js is async, so immediate return value is not possible; return true for now;
}
private String Exec_as_str(String s) {
if (wtr == null) return ""; // HACK: handles http_server
s = "(function () {" + s + "})();"; // NOTE: dependent on firefox_addon which does 'var result = Function("with(arguments[0]){return "+cmd_text+"}")(session.window);'; DATE:2014-01-28
gplx.core.threads.Thread_adp_.Sleep(50); // NOTE: need to sleep, else images won't actually show up on screen; PAGE:nethackwiki.com:Weapons; DATE:2015-08-23
Xosrv_msg msg = Xosrv_msg.new_(Xosrv_cmd_types.Browser_exec, Bry_.Empty, Bry_.Empty, Bry_.Empty, Bry_.Empty, Bry_.new_u8(s));
usr_dlg.Note_many("", "", "sending browser.js: msg=~{0}", s);
wtr.Write(msg);
return "";
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_set)) {}
else return Gfo_invk_.Rv_unhandled;
return this;
} private static final String Invk_set = "set";
public static void Init_gui_for_server(Xoae_app app, Xosrv_socket_wtr wtr) {
Mem_kit mem_kit = (Mem_kit)Gfui_kit_.Mem();
mem_kit.New_html_impl_prototype_(new Gxw_html_server(app.Usr_dlg(), wtr)); // NOTE: set prototype before calling Kit_
app.Gui_mgr().Kit_(mem_kit);
}
public static void Assert_tab(Xoae_app app, Xoae_page page) {
Xog_win_itm browser_win = app.Gui_mgr().Browser_win();
if (browser_win.Active_tab() == null) { // no active tab
Xowe_wiki wiki = page.Wikie(); // take wiki from current page; NOTE: do not take from browser_win.Active_tab().Wiki(); DATE:2015-02-23
browser_win.Tab_mgr().Tabs_new_init(wiki, page); // create at least one active tab; DATE:2014-07-30
}
}
public static Xog_tab_itm Assert_tab2(Xoae_app app, Xowe_wiki wiki) {
Xog_win_itm browser_win = app.Gui_mgr().Browser_win();
Xog_tab_itm rv = browser_win.Active_tab();
if (rv == null) { // no active tab
Xoae_page page = Xoae_page.New(wiki, wiki.Ttl_parse(Bry_.new_a7("Empty_tab")));
rv = browser_win.Tab_mgr().Tabs_new_init(wiki, page); // create at least one active tab; DATE:2014-07-30
}
return rv;
}
}

View File

@@ -13,22 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
class File_retrieve_mode {
public static String Xto_str(byte v) {
switch (v) {
case Mode_skip: return "skip";
case Mode_wait: return "wait";
case Mode_async_server: return "async_server";
default: throw Err_.new_unimplemented();
}
}
public static byte Xto_byte(String s) {
if (String_.Eq(s, "skip")) return Mode_skip;
else if (String_.Eq(s, "wait")) return Mode_wait;
else if (String_.Eq(s, "async_server")) return Mode_async_server;
else throw Err_.new_unimplemented();
}
public static final byte Mode_skip = 1, Mode_wait = 2, Mode_async_server = 3;
public static Keyval[] Options__list = Keyval_.Ary(Keyval_.new_("wait"), Keyval_.new_("skip"), Keyval_.new_("async_server", "async server"));
}

View File

@@ -13,13 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.langs.jsons.*;
public class Http_data__client {
public Http_data__client(byte[] server_host, String ip_address_str) {
this.server_host = server_host;
this.ip_address = Bry_.new_a7(ip_address_str);
}
public byte[] Server_host() {return server_host;} private final byte[] server_host;
public byte[] Ip_address() {return ip_address;} private final byte[] ip_address;
}

View File

@@ -13,36 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.xowa.files.*;
class Http_file_utl {
public static byte[] To_mime_type_by_path_as_bry(byte[] path_bry) {
int dot_pos = Bry_find_.Find_bwd(path_bry, Byte_ascii.Dot);
return dot_pos == Bry_find_.Not_found ? Mime_octet_stream : To_mime_type_by_ext_as_bry(path_bry, dot_pos, path_bry.length);
}
public static byte[] To_mime_type_by_ext_as_bry(byte[] ext_bry, int bgn, int end) {
Object o = mime_hash.Get_by_mid(ext_bry, bgn, end);
return o == null ? Mime_octet_stream : (byte[])o;
}
private static final byte[]
Mime_octet_stream = Xof_ext_.Mime_type__ary[Xof_ext_.Id_unknown]
, Mime_html = Bry_.new_a7("text/html")
, Mime_css = Bry_.new_a7("text/css")
, Mime_js = Bry_.new_a7("application/javascript")
;
private static final Hash_adp_bry mime_hash = Mime_hash__new();
private static Hash_adp_bry Mime_hash__new() {
Hash_adp_bry rv = Hash_adp_bry.ci_a7();
int len = Xof_ext_.Id__max;
for (int i = 0; i < len; ++i) {
rv.Add_bry_obj
( Bry_.Add(Byte_ascii.Dot, Xof_ext_.Bry__ary[i])
, Xof_ext_.Mime_type__ary[i]);
}
rv.Add_str_obj(".htm" , Mime_html);
rv.Add_str_obj(".html" , Mime_html);
rv.Add_str_obj(".css" , Mime_css);
rv.Add_str_obj(".js" , Mime_js);
return rv;
}
}

View File

@@ -13,144 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
/*
This file is part of XOWA: the XOWA Offline Wiki Application
Copyright (C) 2013 matthiasjasny@gmail.com; gnosygnu@gmail.com
XOWA is licensed under the terms of the General Public License (GPL) Version 3,
or alternatively under the terms of the Apache License Version 2.0.
You may use XOWA according to either of these licenses as is most appropriate
for your project on a case-by-case basis.
The terms of each license can be found in the following files:
GPLv3 License: LICENSE-GPLv3.txt
Apache License: LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.threads.*; import gplx.core.net.*; import gplx.core.primitives.*; import gplx.core.envs.*;
import gplx.langs.jsons.*; import gplx.langs.htmls.encoders.*;
import gplx.xowa.wikis.pages.*;
public class Http_server_mgr implements Gfo_invk {
private final Object thread_lock = new Object();
private final Gfo_usr_dlg usr_dlg;
private Http_server_socket wkr;
private byte retrieve_mode = File_retrieve_mode.Mode_wait;
private boolean running, init_gui_needed = true;
public Http_server_mgr(Xoae_app app) {
this.app = app;
this.usr_dlg = app.Usr_dlg();
this.request_parser = new Http_request_parser(server_wtr, false);
}
public Xoae_app App() {return app;} private final Xoae_app app;
public Http_server_wtr Server_wtr() {return server_wtr;} private final Http_server_wtr server_wtr = Http_server_wtr_.New__console();
public Http_request_parser Request_parser() {return request_parser;} private final Http_request_parser request_parser;
public Gfo_url_encoder Encoder() {return encoder;} private final Gfo_url_encoder encoder = Gfo_url_encoder_.New__http_url().Make();
public int Port() {return port;}
public Http_server_mgr Port_(int v, boolean caller_is_cfg) {
if ( caller_is_cfg
&& v == Port__default // new_val == 8080
&& port != Port__default) {// cur_val != 8080
return this; // exit; do not override command-line value with cfg_value
}
port = v;
return this;
} private int port = Port__default;
public Http_server_wkr_pool Wkr_pool() {return wkr_pool;} private final Http_server_wkr_pool wkr_pool = new Http_server_wkr_pool();
public Int_pool Uid_pool() {return uid_pool;} private final Int_pool uid_pool = new Int_pool();
public byte[] Home() {return home;} public void Home_(byte[] v) {home = Bry_.Add(Byte_ascii.Slash_bry, v);} private byte[] home = Bry_.new_a7("/home/wiki/Main_Page");
private void Running_(boolean val) {
if (val) {
if (running)
Note("HTTP Server already started");
else {
Run();
}
}
else {
if (running) {
wkr.Canceled_(true);
wkr = null;
Note("HTTP Server stopped");
}
else
Note("HTTP Server not started");
}
running = val;
}
public void Run() {
app.Cfg().Bind_many_app(this, Cfg__port, Cfg__file_retrieve_mode);
if (wkr == null) wkr = new Http_server_socket(this);
Thread_adp_.Start_by_key("thread:xowa.http_server.server", wkr, Http_server_socket.Invk_run);
Note("HTTP Server started: Navigate to http://localhost:" + Int_.To_str(port));
}
public void Run_xowa_cmd(Xoae_app app, String url_encoded_str) {
Gfo_url_encoder url_converter = Gfo_url_encoder_.New__http_url().Make(); // create instance for each call
String cmd = url_converter.Decode_str(url_encoded_str);
app.Gfs_mgr().Run_str(cmd);
}
public String Parse_page_to_html(Http_data__client data__client, byte[] wiki_domain, byte[] ttl_bry) {
synchronized (thread_lock) {
// create a shim gui to automatically handle default XOWA gui JS calls
if (init_gui_needed) {
init_gui_needed = false;
Gxw_html_server.Init_gui_for_server(app, null);
}
// get the wiki
Xowe_wiki wiki = (Xowe_wiki)app.Wiki_mgr().Get_by_or_make_init_y(wiki_domain); // assert init for Main_Page; EX:click zh.w on wiki sidebar; DATE:2015-07-19
if (Runtime_.Memory_total() > Io_mgr.Len_gb) Xowe_wiki_.Rls_mem(wiki, true); // release memory at 1 GB; DATE:2015-09-11
// get the url / ttl
if (Bry_.Len_eq_0(ttl_bry)) ttl_bry = wiki.Props().Main_page();
Xoa_url url = wiki.Utl__url_parser().Parse(ttl_bry);
Xoa_ttl ttl = Xoa_ttl.Parse(wiki, url.To_bry_page_w_anch()); // changed from ttl_bry to page_w_anch; DATE:2017-07-24
// get the page
gplx.xowa.guis.views.Xog_tab_itm tab = Gxw_html_server.Assert_tab2(app, wiki); // HACK: assert tab exists
Xoae_page page = wiki.Page_mgr().Load_page(url, ttl, tab);
app.Gui_mgr().Browser_win().Active_page_(page); // HACK: init gui_mgr's page for output (which server ordinarily doesn't need)
if (page.Db().Page().Exists_n()) { // if page does not exist, replace with message; else null_ref error; DATE:2014-03-08
page.Db().Text().Text_bry_(Bry_.new_a7("'''Page not found.'''"));
wiki.Parser_mgr().Parse(page, false);
}
page.Html_data().Head_mgr().Itm__server().Init_by_http(data__client).Enabled_y_();
// generate html
String rv = String_.new_u8(wiki.Html_mgr().Page_wtr_mgr().Gen(page, Xopg_page_.Tid_read)); // NOTE: must generate HTML now in order for "wait" and "async_server" to work with text_dbs; DATE:2016-07-10
boolean rebuild_html = false;
switch (retrieve_mode) {
case File_retrieve_mode.Mode_skip: // noop
break;
case File_retrieve_mode.Mode_async_server:
rebuild_html = true;
app.Gui_mgr().Browser_win().Page__async__bgn(tab);
break;
case File_retrieve_mode.Mode_wait:
rebuild_html = true;
gplx.xowa.guis.views.Xog_async_wkr.Async(page, tab.Html_itm());
page = wiki.Page_mgr().Load_page(url, ttl, tab); // HACK: fetch page again so that HTML will now include img data
break;
}
if (rebuild_html) rv = String_.new_u8(wiki.Html_mgr().Page_wtr_mgr().Gen(page, Xopg_page_.Tid_read));
return rv;
}
}
private void Note(String s) {
// usr_dlg.Prog_many("", "", s); // messages should write to progress bar for gui
usr_dlg.Note_many("", "", s);
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Cfg__port)) Port_(m.ReadInt("v"), true);
else if (ctx.Match(k, Cfg__file_retrieve_mode)) retrieve_mode = File_retrieve_mode.Xto_byte(m.ReadStr("v"));
else if (ctx.Match(k, Invk_running_)) Running_(m.ReadYn("v"));
else return Gfo_invk_.Rv_unhandled;
return this;
}
private static final String Invk_running_ = "running_";
private static final String
Cfg__port = "xowa.addon.http_server.port"
, Cfg__file_retrieve_mode = "xowa.addon.http_server.file_retrieve_mode";
private static final int Port__default = 8080;
}

View File

@@ -13,50 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.net.*; import gplx.core.threads.*; import gplx.core.primitives.*;
class Http_server_socket implements Gfo_invk {
private final Http_server_mgr server_mgr;
private Server_socket_adp server_socket;
public Http_server_socket(Http_server_mgr server_mgr) {this.server_mgr = server_mgr;}
public boolean Canceled() {return canceled;}
public Http_server_socket Canceled_(boolean v) {
canceled = v;
if (canceled) {
server_socket.Rls();
server_socket = null;
}
return this;
} private boolean canceled;
public void Run() {
if (server_socket == null) server_socket = new Server_socket_adp__base().Ctor(server_mgr.Port());
while (true) { // listen for incoming requests
Socket_adp client_socket = server_socket.Accept(); // NOTE: blocking call
int wkr_uid = -1; // NOTE: default to -1 to handle cases when http_server.max_clients is not set; DATE:2015-10-11
Http_server_wkr_pool wkr_pool = server_mgr.Wkr_pool();
if (wkr_pool.Enabled()) {
Http_server_wtr server_wtr = server_mgr.Server_wtr();
int timeout = wkr_pool.Timeout();
boolean print_msg = true;
while (wkr_pool.Full()) {
if (print_msg) {
print_msg = false;
server_wtr.Write_str_w_nl("maximum # of concurrent connections reached; max=" + wkr_pool.Max() + " timeout=" + timeout);
}
Thread_adp_.Sleep(timeout);
}
wkr_uid = server_mgr.Uid_pool().Get_next();
wkr_pool.Add(wkr_uid);
// server_wtr.Write_str_w_nl("added new worker; uid=" + wkr_uid);
}
Http_server_wkr wkr = new Http_server_wkr(server_mgr, wkr_uid);
wkr.Init_by_thread(client_socket);
Thread_adp_.Start_by_key("thread:xowa.http_server.client", wkr, Http_server_wkr.Invk_run);
}
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_run)) this.Run();
else return Gfo_invk_.Rv_unhandled;
return this;
} public static final String Invk_run = "run";
}

View File

@@ -13,171 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.ios.*; import gplx.core.ios.streams.*;
import gplx.core.primitives.*; import gplx.core.net.*; import gplx.langs.htmls.encoders.*;
import gplx.xowa.apps.*;
import gplx.xowa.htmls.js.*;
class Http_server_wkr implements Gfo_invk {
private final int uid;
private final Http_server_mgr server_mgr;
private final Http_server_wtr server_wtr;
private final Http_client_wtr client_wtr = Http_client_wtr_.new_stream();
private final Http_client_rdr client_rdr = Http_client_rdr_.new_stream();
private final Http_request_parser request_parser;
private final Gfo_url_encoder url_encoder;
private final Xoae_app app;
private final String root_dir_http;
private final byte[] root_dir_fsys;
private final Bry_bfr tmp_bfr = Bry_bfr_.New_w_size(64);
private Socket_adp socket;
private Http_data__client data__client;
public Http_server_wkr(Http_server_mgr server_mgr, int uid){
this.server_mgr = server_mgr; this.uid = uid;
this.app = server_mgr.App(); this.server_wtr = server_mgr.Server_wtr(); this.url_encoder = server_mgr.Encoder();
this.root_dir_http = app.Fsys_mgr().Root_dir().To_http_file_str();
this.root_dir_fsys = Bry_.new_u8(app.Fsys_mgr().Root_dir().Raw());
this.request_parser = server_mgr.Request_parser();
}
public void Init_by_thread(Socket_adp socket) {
this.socket = socket;
}
public void Run(){
Http_request_itm request = null;
try {
client_rdr.Stream_(socket.Get_input_stream());
client_wtr.Stream_(socket.Get_output_stream());
request = request_parser.Parse(client_rdr);
this.data__client = new Http_data__client(request.Host(), socket.Ip_address());
byte[] url_bry = request.Url();
if (Bry_.Eq(url_bry, Url__home)) url_bry = server_mgr.Home(); // "localhost:8080" comes thru as url of "/"; transform to custom home page; DATE:2015-10-11
switch (request.Type()) {
case Http_request_itm.Type_get: Process_get(request, url_bry); break;
case Http_request_itm.Type_post: Process_post(request); break;
}
client_wtr.Rls(); // client_rdr.Rls(); socket.Rls();
}
catch (Exception e) {
String request_str = request == null ? "<<NULL>>" : request.To_str(tmp_bfr, Bool_.N);
server_wtr.Write_str_w_nl(String_.Format("failed to process request;\nrequest={0}\nerr_msg={1}", request_str, Err_.Message_gplx_full(e)));
}
finally {
if (uid != -1) { // only release if uid was acquired; DATE:2015-10-11
server_mgr.Wkr_pool().Del(uid);
server_mgr.Uid_pool().Del(uid);
}
}
}
private void Process_get(Http_request_itm request, byte[] url) {
server_wtr.Write_str_w_nl(String_.new_u8(request.Host()) + "|GET|" + String_.new_u8(request.Url())); // use request url
if (Bry_.Has_at_bgn(url, Url__fsys)) Serve_file(url);
else if (Bry_.Has_at_bgn(url, Url__exec)) Exec_exec(url, Url__exec);
else if (Bry_.Has_at_bgn(url, Url__exec_2)) Exec_exec(url, Url__exec_2);
else Write_wiki(url);
}
private void Serve_file(byte[] url) {
tmp_bfr.Clear().Add(root_dir_fsys); // add "C:\xowa\"
int question_pos = Bry_find_.Find_fwd(url, Byte_ascii.Question);
int url_bgn = Bry_.Has_at_bgn(url, Url__fsys) ? Url__fsys_len : 0; // most files will have "/fsys/" at start, but Mathjax will not
int url_end = question_pos == Bry_find_.Not_found ? url.length : question_pos; // ignore files with query params; EX: /file/A.png?key=val
url_encoder.Decode(tmp_bfr, Bool_.N, url, url_bgn, url_end); // decode url to actual chars; note that XOWA stores on fsys in UTF-8 chars; "<22>" not "%C3"
byte[] path = tmp_bfr.To_bry_and_clear();
if (gplx.core.envs.Op_sys.Cur().Tid_is_wnt()) path = Bry_.Replace(path, Byte_ascii.Backslash, Byte_ascii.Slash);
client_wtr.Write_bry(Xosrv_http_wkr_.Rsp__http_ok);
// client_wtr.Write_str("Expires: Sun, 17-Jan-2038 19:14:07 GMT\n");
String mime_type = String_.new_u8(Http_file_utl.To_mime_type_by_path_as_bry(path));
client_wtr.Write_str("Content-Type: " + mime_type + "\n\n");
Io_stream_rdr file_stream = Io_stream_rdr_.New_by_url(Io_url_.new_fil_(String_.new_u8(path))).Open();
client_wtr.Write_stream(file_stream);
file_stream.Rls(); client_rdr.Rls(); socket.Rls();
}
private void Exec_exec(byte[] url, byte[] tkn_bgn) {
byte[] cmd = Bry_.Mid(url, tkn_bgn.length);
app.Http_server().Run_xowa_cmd(app, String_.new_u8(cmd));
}
private void Write_wiki(byte[] req) {
String wiki_domain = ""; String page_name = "";
String[] req_split = String_.Split(String_.new_u8(req), "/");
if(req_split.length >= 1){
wiki_domain = req_split[1];
}
if(req_split.length >= 4){
page_name = req_split[3];
for(int i = 4; i <= req_split.length-1; i++){
page_name += "/" + req_split[i];
}
page_name = url_encoder.Decode_str(page_name);
}
String page_html = app.Http_server().Parse_page_to_html(data__client, Bry_.new_u8(wiki_domain), Bry_.new_u8(page_name));
page_html = Convert_page(page_html, root_dir_http, wiki_domain);
Xosrv_http_wkr_.Write_response_as_html(client_wtr, Bool_.N, page_html);
}
private void Process_post(Http_request_itm request) {
byte[] msg = request.Post_data_hash().Get_by(Key__msg).Val();
byte[] app_mode = request.Post_data_hash().Get_by(Key__app_mode).Val();
Xoa_app_mode app_mode_itm = Xoa_app_mode.parse(String_.new_u8(app_mode));
server_wtr.Write_str_w_nl(String_.new_u8(request.Host()) + "|POST|" + String_.new_u8(msg));
Object url_tid_obj = post_url_hash.Get_by_bry(request.Url()); if (url_tid_obj == null) throw Err_.new_wo_type("unknown url", "url", request.Url(), "request", request.To_str(tmp_bfr, Bool_.N));
String rv = null;
switch (((Int_obj_val)url_tid_obj).Val()) {
case Tid_post_url_json:
rv = app.Html__bridge_mgr().Cmd_mgr().Exec(msg);
break;
case Tid_post_url_gfs:
rv = Object_.Xto_str_strict_or_null_mark(app.Gfs_mgr().Run_str(String_.new_u8(msg)));
break;
}
if (app_mode_itm.Tid_is_http())
rv = Convert_page(rv, root_dir_http , "<<MISSING_WIKI>>");
Xosrv_http_wkr_.Write_response_as_html(client_wtr, app_mode_itm.Tid() == Xoa_app_mode.Itm_file.Tid(), rv);
}
private static final byte[] Key__msg = Bry_.new_a7("msg"), Key__app_mode = Bry_.new_a7("app_mode");
private static final int Tid_post_url_json = 1, Tid_post_url_gfs = 2;
private static final Hash_adp_bry post_url_hash = Hash_adp_bry.ci_a7()
.Add_str_int("/exec/json" , Tid_post_url_json)
.Add_str_int("/exec/gfs" , Tid_post_url_gfs)
;
private static String Convert_page(String page_html, String root_dir_http, String wiki_domain) {
page_html = String_.Replace(page_html, root_dir_http , "/fsys/");
page_html = String_.Replace(page_html, "xowa-cmd:" , "/exec/");
page_html = String_.Replace(page_html, "<a href=\"/wiki/" , "<a href=\"/" + wiki_domain + "/wiki/");
page_html = String_.Replace(page_html, "<a href='/wiki/" , "<a href='/" + wiki_domain + "/wiki/");
page_html = String_.Replace(page_html, "action=\"/wiki/" , "action=\"/" + wiki_domain + "/wiki/");
page_html = String_.Replace(page_html, "/site" , "");
return page_html;
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_run)) {this.Run();}
else return Gfo_invk_.Rv_unhandled;
return this;
} public static final String Invk_run = "run";
private static final byte[]
Url__home = Bry_.new_a7("/"), Url__fsys = Bry_.new_a7("/fsys/")
, Url__exec = Bry_.new_a7("/exec/"), Url__exec_2 = Bry_.new_a7("/xowa-cmd:")
;
private static final int Url__fsys_len = Url__fsys.length;
}
class Xosrv_http_wkr_ {
public static void Write_response_as_html(Http_client_wtr client_wtr, boolean cross_domain, String html) {Write_response_as_html(client_wtr, cross_domain, Bry_.new_u8(html));}
public static void Write_response_as_html(Http_client_wtr client_wtr, boolean cross_domain, byte[] html) {
try{
// TODO_OLD: add command-line argument to allow testing from local file
// if (cross_domain)
// client_wtr.Write_str("Access-Control-Allow-Origin: *\n"); // No 'Access-Control-Allow-Origin' header is present on the requested resource.
client_wtr.Write_bry
( Bry_.Add
( Rsp__http_ok
, Rsp__content_type_html
, Byte_ascii.Nl_bry
, html
));
} catch (Exception err) {
client_wtr.Write_str("Site not found. Check address please, or see console log.\n" + Err_.Message_lang(err));
client_wtr.Rls();
}
}
public static final byte[]
Rsp__http_ok = Bry_.new_a7("HTTP/1.1 200 OK:\n")
, Rsp__content_type_html = Bry_.new_a7("Content-Type: text/html; charset=utf-8\n")
;
}

View File

@@ -13,25 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.xowa.wikis.domains.*; import gplx.xowa.langs.*;
class Http_server_wkr_ {
public static String Assert_main_page(Xoae_app app, String req) {
int mode = -1;
String[] req_array = String_.Split(req, "/");
if (String_.Has_at_end(req, "wiki/")) mode = 0;
else if (String_.Has_at_end(req, "wiki")) mode = 1;
else if (req_array.length == 3) mode = 2;
if (mode == -1) return req; // not a link to a Main Page; EX:localhost:8080/en.wikipedia.org/wiki/Earth
if (req_array.length < 3) return req; // shouldn't happen; EX: "localhost:8080wiki"
byte[] wiki_domain = Bry_.new_u8(req_array[1]);
Xow_domain_itm domain_itm = Xow_domain_itm_.parse(wiki_domain);
if (domain_itm.Domain_type_id() == Xow_domain_tid_.Tid__other && domain_itm.Lang_actl_itm().Id() == Xol_lang_stub_.Id__intl) return req;
Xowe_wiki wiki = app.Wiki_mgr().Get_by_or_make(wiki_domain);
wiki.Init_assert();
String main_page = String_.new_u8(wiki.Props().Main_page());
if (mode == 1) main_page = "/" + main_page;
else if (mode == 2) main_page = "wiki/" + main_page;
return req + main_page;
}
}

View File

@@ -13,28 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import org.junit.*;
public class Http_server_wkr__tst {
@Before public void init() {fxt.Clear();} private Http_server_wkr__fxt fxt = new Http_server_wkr__fxt();
@Test public void Assert_main_page() {
fxt.Init_wiki_main_page("fr.wikiversity.org", "Accueil");
fxt.Test_assert_main_page("/fr.wikiversity.org/" , "/fr.wikiversity.org/wiki/Accueil");
fxt.Test_assert_main_page("/fr.wikiversity.org/wiki" , "/fr.wikiversity.org/wiki/Accueil");
fxt.Test_assert_main_page("/fr.wikiversity.org/wiki/" , "/fr.wikiversity.org/wiki/Accueil");
fxt.Test_assert_main_page("/fr.wikiversity.org/wiki/A" , "/fr.wikiversity.org/wiki/A");
}
}
class Http_server_wkr__fxt {
private Xoae_app app;
public void Clear() {
this.app = Xoa_app_fxt.Make__app__edit();
}
public void Init_wiki_main_page(String domain, String main_page) {
Xowe_wiki wiki = app.Wiki_mgr().Get_by_or_make(Bry_.new_u8(domain));
wiki.Props().Main_page_(Bry_.new_u8(main_page));
}
public void Test_assert_main_page(String url, String expd) {
Tfds.Eq(expd, Http_server_wkr_.Assert_main_page(app, url));
}
}

View File

@@ -13,29 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.http; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.primitives.*;
public class Http_server_wkr_pool {
private final Ordered_hash hash = Ordered_hash_.New(); private final Int_obj_ref hash_key = Int_obj_ref.New_neg1();
public boolean Enabled() {return max != 0;}
public int Max() {return max;} private int max;
public int Timeout() {return timeout;} private int timeout;
public int Len() {return len;} private int len;
public boolean Full() {return len >= max;}
public void Init(int max, int timeout) {this.max = max; this.timeout = timeout;}
public void Add(int uid) {
if (max == 0) return; // disabled
synchronized (hash) {
Int_obj_ref wkr_key = Int_obj_ref.New(uid);
hash.Add(wkr_key, wkr_key);
++len;
}
}
public void Del(int uid) {
if (max == 0) return; // disabled
synchronized (hash) {
hash.Del(hash_key.Val_(uid));
--len;
}
}
}

View File

@@ -13,41 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.ios.*; import gplx.core.ios.streams.*;
public class Socket_rdr {
private java.net.ServerSocket server;
private java.net.Socket client;
private java.io.InputStream stream;
public IoStream Rdr_stream() {return rdr_stream;} private IoStream rdr_stream = null;
public int Port() {return port;} private int port;
public Socket_rdr Ctor(int port) {this.port = port; return this;}
public Socket_rdr Open() {
try {
// this.Rls();
if (server == null) {
server = new java.net.ServerSocket(port);
server.setReuseAddress(true);
}
client = server.accept();
client.setSoTimeout(10000);
stream = client.getInputStream();
rdr_stream = new IoStream_stream_rdr().UnderRdr_(stream);
return this;
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to open socket", "port", port);}
}
public void Close() {
try {
// if (server != null) server.close();
if (client != null) client.close();
if (stream != null) stream.close();
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to close socket", "port", port);}
}
public void Rls() {
try {
if (server != null) server.close();
if (client != null) client.close();
if (stream != null) stream.close();
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to rls socket", "port", port);}
}
}

View File

@@ -13,37 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
public class Socket_wtr {
private String host;
private int port;
private java.net.Socket socket;
private java.io.OutputStream stream;
public Socket_wtr Ctor(String host, int port) {this.host = host; this.port = port; return this;}
public Socket_wtr Open() {
try {
this.Rls();
socket = new java.net.Socket(host, port);
socket.setSoTimeout(10000);
stream = socket.getOutputStream();
return this;
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to open socket", "host", host, "port", port);}
}
public void Write(byte[] bry) {
try {
stream.write(bry, 0, bry.length);
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to write stream", "host", host, "port", port);}
}
public void Close() {
try {
if (stream != null) stream.close();
if (socket != null) socket.close();
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to close socket", "host", host, "port", port);}
}
public void Rls() {
try {
if (stream != null) stream.close();
if (socket != null) socket.close();
} catch (Exception e) {throw Err_.new_exc(e, "net", "failed to release socket", "host", host, "port", port);}
}
}

View File

@@ -13,11 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
public class Xosrv_cmd_types {
public static final byte[]
Cmd_exec = Bry_.new_a7("xowa.cmd.exec") , Cmd_pass = Bry_.new_a7("xowa.cmd.result") , Cmd_fail = Bry_.new_a7("xowa.cmd.error")
, Js_exec = Bry_.new_a7("xowa.js.exec") , Js_pass = Bry_.new_a7("xowa.js.result") , Js_fail = Bry_.new_a7("xowa.js.error")
, Browser_exec = Bry_.new_a7("browser.js.exec"), Browser_pass = Bry_.new_a7("browser.js.result") , Browser_fail = Bry_.new_a7("browser.js.error")
;
}

View File

@@ -13,107 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
public class Xosrv_msg {
public byte Version_tid() {return Version_tid_0;} static final byte Version_tid_0 = 0;
public byte[] Cmd_name() {return cmd_name;} private byte[] cmd_name;
public byte[] Msg_id() {return msg_id;} private byte[] msg_id;
public byte[] Sender() {return sender;} private byte[] sender;
public byte[] Recipient() {return recipient;} private byte[] recipient;
public byte[] Msg_date() {return msg_date;} private byte[] msg_date;
public byte[] Msg_text() {return msg_text;} private byte[] msg_text;
public void Print(Bry_bfr bfr) {
int body_len = cmd_name.length + msg_id.length + sender.length + recipient.length + msg_date.length + msg_text.length + 5; // 5=5 pipes for 6 fields
int cksum = (body_len * 2) + 1;
bfr.Add_int_fixed(this.Version_tid() , 1).Add_byte_pipe(); // 0|
bfr.Add_int_fixed(body_len , 10).Add_byte_pipe(); // 0123456789|
bfr.Add_int_fixed(cksum , 10).Add_byte_pipe(); // 0123456789|
bfr.Add(cmd_name ).Add_byte_pipe(); // cmd|
bfr.Add(msg_id ).Add_byte_pipe(); // id|
bfr.Add(sender ).Add_byte_pipe(); // sender|
bfr.Add(recipient ).Add_byte_pipe(); // recipient|
bfr.Add(msg_date ).Add_byte_pipe(); // msg_date|
bfr.Add(msg_text ); // msg_text
}
public static final Xosrv_msg Exit = new Xosrv_msg();
public static Xosrv_msg fail_(String fmt, Object... ary) {
Xosrv_msg rv = new Xosrv_msg();
rv.msg_text = Bry_.new_u8(String_.Format(fmt, ary));
return rv;
}
public static Xosrv_msg new_(byte[] cmd_name, byte[] msg_id, byte[] sender, byte[] recipient, byte[] msg_date, byte[] msg_text) {
Xosrv_msg rv = new Xosrv_msg();
rv.cmd_name = cmd_name;
rv.msg_id = msg_id;
rv.sender = sender;
rv.recipient = recipient;
rv.msg_date = msg_date;
rv.msg_text = msg_text;
return rv;
}
}
/*
Message definition
Id : 0
Purpose : Version number for message format
Data type : int
Notes : Always 0; will change to 1 if message format ever changes
Example : "0"
Id : 1
Description : Body length; specified total length of message field 3 (body)
Data type : int
Notes : always zero-padded to 10 bytes (not hexadecimal)
Example : "0000000123"
Id : 2
Description : Checksum; should equal (2 * body length) + 1
Data type : int
Notes : always zero-padded to 10 bytes (not hexadecimal)
Example : "0000000247"
Id : 3
Description : Body
Data type : String
Notes : length specified by field 1 (body length)
Example : see below
Body definition
* Pipes are not allowed in any field except for the last
* Only the first field is required
Id : 0
Purpose : Command name
Data type : String
Notes : unique name identifying the command
Example : "xowa.cmd.exec", "xowa.cmd.result", "xowa.cmd.error", "xowa.js.exec", "xowa.js.result", "xowa.js.error"
Id : 1
Purpose : Message id
Data type : String
Notes : Usage is defined by callers; can be empty
Example : "1", ""
Id : 2
Purpose : Sender id
Data type : String
Notes : Usage is defined by callers; can be empty
Example : "tab1", "xowa", ""
Id : 3
Purpose : Recipient id
Data type : String
Notes : Usage is defined by callers; can be empty
Example : "xowa", "tab1", ""
Id : 4
Purpose : Message date
Data type : String
Notes : ISO 8601 format; see http://www.w3.org/TR/NOTE-datetime; Usage is defined by callers; can be empty
Example : "1997-07-16T19:20:30.45+01:00", ""
Id : 5
Purpose : Message text
Data type : String
Notes : freeform; can contain any character
Example : "app.shell.fetch_page('simple.wikipedia.org/wiki/Earth', 'html');"*/

View File

@@ -13,50 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.primitives.*;
import gplx.core.ios.*; import gplx.core.ios.streams.*; import gplx.core.texts.*;
public class Xosrv_msg_rdr {
public Xosrv_msg_rdr(byte[] default_body_bry, IoStream rdr) {this.default_body_bry = default_body_bry; default_body_bry_len = default_body_bry.length; this.rdr = rdr;} private byte[] header_bry = new byte[24], default_body_bry; int default_body_bry_len;
public IoStream Rdr() {return rdr;} private IoStream rdr;
public Xosrv_msg Read() {
int bytes_read = rdr.Read(header_bry, 0, 24); // 24 = version(1) + pipe + msg_len (10) + pipe + cksum (10) + pipe
if (bytes_read < 24) {
if (bytes_read == -1) return Xosrv_msg.Exit; // stream closed; should only occur when shutting down
else return Xosrv_msg.fail_("header is invalid; hdr:{0}", String_.new_u8(header_bry, 0, bytes_read));
}
byte version = header_bry[0]; if (version != Byte_ascii.Num_0) return Xosrv_msg.fail_("version must be 0; version:{0}", Byte_.To_str(version));
int body_len = Bry_.To_int_or(header_bry, 2, 12, -1); if (body_len == -1) return Xosrv_msg.fail_("body_len is not number; body_len:{0}", String_.new_u8(header_bry, 2, 23));
int cksum = Bry_.To_int_or(header_bry, 13, 23, -1); if (cksum == -1) return Xosrv_msg.fail_("checksum is not number; cksum:{0}", String_.new_u8(header_bry, 13, 23));
if (!Chk_bytes(header_bry, Byte_ascii.Pipe, 1, 12, 23)) return Xosrv_msg.fail_("message should be delimited by pipes at 1, 12 and 23; message:{0}", String_.new_u8(header_bry, 0, 24));
if (cksum != (body_len * 2) + 1) return Xosrv_msg.fail_("checksum failed; body_len:{0} chksum:{1}", body_len, cksum);
byte[] body_bry = body_len > default_body_bry_len ? new byte[body_len] : default_body_bry;
rdr.Read(body_bry, 0, body_len);
Int_obj_ref fld_bgn = Int_obj_ref.New_zero(); Bool_obj_ref fail_ref = Bool_obj_ref.n_(); String_obj_ref fld_ref = String_obj_ref.null_();
byte[] cmd_name = Read_fld(body_bry, body_len, fld_bgn, fail_ref, fld_ref.Val_("cmd_name")); if (fail_ref.Val()) return Read_fld_fail(fld_ref, body_bry);
byte[] msg_id = Read_fld(body_bry, body_len, fld_bgn, fail_ref, fld_ref.Val_("msg_id")); if (fail_ref.Val()) return Read_fld_fail(fld_ref, body_bry);
byte[] sender = Read_fld(body_bry, body_len, fld_bgn, fail_ref, fld_ref.Val_("sender")); if (fail_ref.Val()) return Read_fld_fail(fld_ref, body_bry);
byte[] recipient = Read_fld(body_bry, body_len, fld_bgn, fail_ref, fld_ref.Val_("recipient")); if (fail_ref.Val()) return Read_fld_fail(fld_ref, body_bry);
byte[] msg_date = Read_fld(body_bry, body_len, fld_bgn, fail_ref, fld_ref.Val_("msg_date")); if (fail_ref.Val()) return Read_fld_fail(fld_ref, body_bry);
byte[] msg_text = Bry_.Mid(body_bry, fld_bgn.Val(), body_len);
return Xosrv_msg.new_(cmd_name, msg_id, sender, recipient, msg_date, msg_text);
}
private static byte[] Read_fld(byte[] bry, int bry_len, Int_obj_ref fld_bgn, Bool_obj_ref fail_ref, String_obj_ref fld_ref) {
int fld_end = Bry_find_.Find_fwd(bry, Byte_ascii.Pipe, fld_bgn.Val(), bry_len);
if (fld_end == Bry_find_.Not_found) {fail_ref.Val_y_(); return null;}
byte[] rv = Bry_.Mid(bry, fld_bgn.Val(), fld_end);
fld_bgn.Val_(fld_end + 1); // +1 to place after pipe
return rv;
}
private static Xosrv_msg Read_fld_fail(String_obj_ref fld_name, byte[] body_bry) {return Xosrv_msg.fail_("pipe not found for " + fld_name.Val() + "; body:{0}", String_.new_u8(body_bry));}
private static boolean Chk_bytes(byte[] bry, byte expd, int... pos_ary) {
int len = pos_ary.length;
int bry_len = bry.length;
for (int i = 0; i < len; i++) {
int pos = pos_ary[i];
if (pos >= bry_len) return false; // out of bounds; return false (don't fail)
if (bry[pos] != expd) return false;
}
return true;
}
}

View File

@@ -13,51 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import org.junit.*;
import gplx.core.ios.*; import gplx.core.ios.streams.*;
public class Xosrv_msg_rdr_tst {
@Before public void init() {fxt.Clear();} private Xosrv_msg_rdr_fxt fxt = new Xosrv_msg_rdr_fxt();
@Test public void Parse() {
String raw = "0|0000000045|0000000091|cmd_0|id_0|sender_0|recipient_0|date_0|text_0";
Xosrv_msg msg = fxt.Test_parse_msg(raw, "cmd_0", "id_0", "sender_0", "recipient_0", "date_0", "text_0");
fxt.Test_print(msg, raw);
}
@Test public void Err_header_is_invalid() {fxt.Test_parse_err("abcde", "header is invalid");}
@Test public void Err_checksum_failed() {fxt.Test_parse_err("0|0000000000|0000000000|", "checksum failed");}
@Test public void Err_cmd_missing() {fxt.Test_parse_err("0|0000000001|0000000003|a", "pipe not found for cmd_name");}
}
class Xosrv_msg_rdr_fxt {
public Xosrv_msg_rdr_fxt Clear() {
if (msg_rdr == null) {
msg_rdr_stream = new IoStream_mock();
msg_rdr = new Xosrv_msg_rdr(Bry_.Empty, msg_rdr_stream);
}
msg_rdr_stream.Reset();
return this;
} private Xosrv_msg_rdr msg_rdr; private IoStream_mock msg_rdr_stream;
public Xosrv_msg Test_parse_msg(String raw, String expd_cmd, String expd_id, String expd_sender, String expd_recipient, String expd_date, String expd_text) {
byte[] raw_bry = Bry_.new_a7(raw);
msg_rdr_stream.Data_bry_(raw_bry).Read_limit_(raw_bry.length);
Xosrv_msg msg = msg_rdr.Read();
Tfds.Eq(String_.new_a7(msg.Cmd_name()) , expd_cmd);
Tfds.Eq(String_.new_a7(msg.Msg_id()) , expd_id);
Tfds.Eq(String_.new_a7(msg.Sender()) , expd_sender);
Tfds.Eq(String_.new_a7(msg.Recipient()) , expd_recipient);
Tfds.Eq(String_.new_a7(msg.Msg_date()) , expd_date);
Tfds.Eq(String_.new_a7(msg.Msg_text()) , expd_text);
return msg;
}
public void Test_parse_err(String raw, String expd_err) {
byte[] raw_bry = Bry_.new_a7(raw);
msg_rdr_stream.Data_bry_(raw_bry).Read_limit_(raw_bry.length);
Xosrv_msg msg = msg_rdr.Read();
String msg_text = String_.new_a7(msg.Msg_text());
Tfds.Eq_true(String_.Has_at_bgn(msg_text, expd_err), msg_text);
}
public void Test_print(Xosrv_msg msg, String expd) {
Bry_bfr bfr = Bry_bfr_.New();
msg.Print(bfr);
Tfds.Eq(expd, bfr.To_str_and_clear());
}
}

View File

@@ -13,116 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.primitives.*; import gplx.core.ios.*; import gplx.core.envs.*; import gplx.core.threads.*;
import gplx.gfui.controls.standards.*;
import gplx.langs.jsons.*;
public class Xosrv_server implements Gfo_invk {
private long last_cmd;
public Xosrv_socket_rdr Rdr() {return rdr;} private Xosrv_socket_rdr rdr = new Xosrv_socket_rdr();
public Xosrv_socket_wtr Wtr() {return wtr;} private Xosrv_socket_wtr wtr = new Xosrv_socket_wtr();
public int Rdr_port() {return rdr_port;} public Xosrv_server Rdr_port_(int v) {rdr_port = v; return this;} private int rdr_port = 55000;
public int Wtr_port() {return wtr_port;} public Xosrv_server Wtr_port_(int v) {wtr_port = v; return this;} private int wtr_port = 55001;
public int Shutdown_interval() {return shutdown_interval;} public Xosrv_server Shutdown_interval_(int v) {shutdown_interval = v; return this;} private int shutdown_interval = -1;
public String Wtr_host() {return wtr_host;} private String wtr_host = "localhost";
public boolean Running() {return running;} public Xosrv_server Running_(boolean v) {running = v; running_str = Bool_.To_str_lower(running); return this;} private boolean running = false;
public String Running_str() {return running_str;} String running_str = "false";
public void App_ctor(Xoae_app app) {this.app = app;}
public Xoae_app App() {return app;} private Xoae_app app;
public void Run() {
rdr.Init(this, rdr_port);
wtr.Init(wtr_host, wtr_port);
Gxw_html_server.Init_gui_for_server(app, wtr);
Thread_adp_.Start_by_key(gplx.xowa.apps.Xoa_thread_.Key_http_server_main, rdr, Xosrv_socket_rdr.Invk_start);
app.Usr_dlg().Note_many("", "", "server started: listening on ~{0}. Press Ctrl+C to exit", rdr_port);
last_cmd = System_.Ticks();
Running_(true);
while (running) {
if (shutdown_interval != -1 && System_.Ticks() - last_cmd > shutdown_interval) break;
Thread_adp_.Sleep(1000);
}
rdr.Rls();
wtr.Rls();
app.Usr_dlg().Note_many("", "", "server stopped", rdr_port);
}
public void Msg_rcvd(Xosrv_msg msg) {
try {
byte[] cmd_name = msg.Cmd_name();
byte[] rsp_name = Bry_.Empty;
long time_bgn = System_.Ticks();
last_cmd = time_bgn;
byte[] msg_bry = msg.Msg_text();
String msg_str = String_.new_u8(msg_bry);
app.Usr_dlg().Note_many("", "", "processing cmd: ~{0}", msg_str);
String rsp_str = null;
if (Bry_.Eq(cmd_name, Xosrv_cmd_types.Cmd_exec)) {rsp_name = Xosrv_cmd_types.Cmd_pass; rsp_str = Exec_cmd(msg_str);}
else if (Bry_.Eq(cmd_name, Xosrv_cmd_types.Js_exec)) {rsp_name = Xosrv_cmd_types.Js_pass; rsp_str = Exec_js(msg.Sender(), msg_bry);}
Xosrv_msg rsp_msg = Xosrv_msg.new_(rsp_name, msg.Msg_id(), msg.Recipient(), msg.Sender(), msg.Msg_date(), Bry_.new_u8(rsp_str));
app.Usr_dlg().Note_many("", "", "sending rsp: bytes=~{0}", String_.Len(rsp_str));
wtr.Write(rsp_msg);
app.Usr_dlg().Note_many("", "", "rsp sent: elapsed=~{0}", Time_span_.fracs_(System_.Ticks() - time_bgn).XtoStrUiAbbrv());
} catch (Exception e) {app.Usr_dlg().Warn_many("", "", "server error: ~{0}", Err_.Message_gplx_full(e));}
}
private String Exec_cmd(String msg_text) {
Object rv_obj = app.Gfs_mgr().Run_str(msg_text);
String rv = Type_.Eq_by_obj(rv_obj, String_.Cls_ref_type) ? (String)rv_obj : Object_.Xto_str_strict_or_null(rv_obj);
return rv;
}
public String Exec_js(byte[] sender, byte[] msg_text) {
String_obj_ref trace = String_obj_ref.new_("exec_js");
try {
Object[] xowa_exec_args = xowa_exec_parser.Parse_xowa_exec(msg_text);
trace.Val_("js_args");
// xowa_exec_args = (Object[])Array_.Resize(xowa_exec_args, xowa_exec_args.length + 1);
// xowa_exec_args[xowa_exec_args.length - 1] = sender;
Object rv_obj = Gfui_html.Js_args_exec(app.Gui_mgr().Browser_win().Active_html_itm().Js_cbk(), xowa_exec_args);
trace.Val_("json_write: " + Object_.Xto_str_strict_or_null_mark(rv_obj));
return json_wtr.Write_root(Bry_xowa_js_result, rv_obj).Bld_as_str();
} catch (Exception e) {throw Err_.new_exc(e, "http", "exec_js error", "trace", trace, "msg", msg_text);}
} private Xosrv_xowa_exec_parser xowa_exec_parser = new Xosrv_xowa_exec_parser(); private Json_doc_srl json_wtr = new Json_doc_srl(); private static final byte[] Bry_xowa_js_result = Bry_.new_a7("xowa_js_result");
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_rdr_port)) return rdr_port;
else if (ctx.Match(k, Invk_rdr_port_)) rdr_port = m.ReadInt("v");
else if (ctx.Match(k, Invk_wtr_port)) return wtr_port;
else if (ctx.Match(k, Invk_wtr_port_)) wtr_port = m.ReadInt("v");
else if (ctx.Match(k, Invk_wtr_host)) return wtr_host;
else if (ctx.Match(k, Invk_wtr_host_)) wtr_host = m.ReadStr("v");
else if (ctx.Match(k, Invk_shutdown_interval)) return shutdown_interval;
else if (ctx.Match(k, Invk_shutdown_interval_)) shutdown_interval = m.ReadInt("v");
else if (ctx.Match(k, Invk_stop)) running = false;
else return Gfo_invk_.Rv_unhandled;
return this;
}
public static final String Invk_stop = "stop", Invk_rdr_port = "rdr_port", Invk_rdr_port_ = "rdr_port_", Invk_wtr_port = "wtr_port", Invk_wtr_port_ = "wtr_port_", Invk_wtr_host = "wtr_host", Invk_wtr_host_ = "wtr_host_"
, Invk_shutdown_interval = "shutdown_interval", Invk_shutdown_interval_ = "shutdown_interval_";
}
class Xosrv_xowa_exec_parser {
private Json_parser json_parser = new Json_parser();
public Object[] Parse_xowa_exec(byte[] msg_text) { // parses JSON with format '{"args":["arg0","arg1","arg2"]}'
Json_doc doc = json_parser.Parse(msg_text);
Json_kv args_kv = (Json_kv)doc.Root_nde().Get_at(0); // get "args" kv
Json_ary args_ary = (Json_ary)args_kv.Val(); // get []
int len = args_ary.Len();
Object[] rv = new Object[len];
for (int i = 0; i < len; i++) { // extract args
Json_itm itm = args_ary.Get_at(i);
rv[i] = Parse_ary_itm(itm);
}
return rv;
}
private Object Parse_ary_itm(Json_itm itm) {
switch (itm.Tid()) {
case Json_itm_.Tid__str:
return String_.new_u8(itm.Data_bry());
case Json_itm_.Tid__ary:
Json_ary ary = (Json_ary)itm;
int len = ary.Len();
String[] rv = new String[len];
for (int i = 0; i < len; i++)
rv[i] = String_.new_u8(ary.Get_at(i).Data_bry());
return rv;
default:
throw Err_.new_unhandled(itm.Tid());
}
}
}

View File

@@ -13,26 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import org.junit.*;
import gplx.core.ios.*;
public class Xosrv_server_tst {
@Before public void init() {fxt.Clear();} private Xosrv_server_fxt fxt = new Xosrv_server_fxt();
@Test public void Exec_js() {
fxt.Test_exec_js("{\"args\":[\"xowa_exec_test\",\"a\",\"b\"]}", "{\"xowa_js_result\":\"xowa_exec_test|a|b\"}");
}
@Test public void Exec_js_ary() {
fxt.Test_exec_js("{\"args\":[\"xowa_exec_test_as_array\",\"a\",\"b\"]}", "{\"xowa_js_result\":[\"xowa_exec_test_as_array\",\"a\",\"b\"]}");
}
}
class Xosrv_server_fxt {
public Xosrv_server_fxt Clear() {
app = Xoa_app_fxt.Make__app__edit();
Xoa_app_fxt.Init_gui(app, null); // NOTE: null wiki does not matter for test
return this;
} private Xoae_app app;
public void Test_exec_js(String raw, String expd) {
String actl = app.Tcp_server().Exec_js(null, Bry_.new_a7(raw));
Tfds.Eq(expd, actl);
}
}

View File

@@ -13,34 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import gplx.core.ios.*; import gplx.core.ios.streams.*;
public class Xosrv_socket_rdr implements Gfo_invk {
private Socket_rdr rdr = new Socket_rdr();
public int Port() {return port;} private int port;
public void Init(Xosrv_server server, int port) {this.server = server; this.port = port;} private Xosrv_server server;
public void Start() {
rdr = new Socket_rdr();
try {
rdr.Ctor(port);
while (true) {
rdr.Open();
IoStream rdr_stream = rdr.Rdr_stream();
Xosrv_msg_rdr msg_rdr = new Xosrv_msg_rdr(new byte[24], rdr_stream);
Xosrv_msg msg = msg_rdr.Read();
if (msg == Xosrv_msg.Exit) continue;
server.Msg_rcvd(msg);
rdr.Close();
}
} catch (Exception e) {Err_.Noop(e);}
finally {rdr.Rls();}
}
public void Rls() {
rdr.Rls();
}
public Object Invk(GfsCtx ctx, int ikey, String k, GfoMsg m) {
if (ctx.Match(k, Invk_start)) this.Start();
else return Gfo_invk_.Rv_unhandled;
return this;
} public static final String Invk_start = "start";
}

View File

@@ -13,20 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
public class Xosrv_socket_wtr {
public String Host() {return host;} private String host = "localhost";
public int Port() {return port;} private int port;
private Socket_wtr wtr; private Bry_bfr msg_bfr = Bry_bfr_.Reset(4 * Io_mgr.Len_kb);
public void Init(String host, int port) {this.host = host; this.port = port; wtr = new Socket_wtr().Ctor(host, port);}
public void Write(Xosrv_msg msg) {
wtr.Open();
msg.Print(msg_bfr);
byte[] msg_bry = msg_bfr.To_bry_and_clear();
wtr.Write(msg_bry);
wtr.Close();
}
public void Rls() {
wtr.Rls();
}
}

View File

@@ -13,216 +13,3 @@ The terms of each license can be found in the source code repository:
GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt
Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
*/
package gplx.xowa.apps.servers.tcp; import gplx.*; import gplx.xowa.*; import gplx.xowa.apps.*; import gplx.xowa.apps.servers.*;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Xowa_tcp_console {
public static void main(String[] args) {
Xowa_tcp_console console = new Xowa_tcp_console();
console.Run(args);
}
private int server_send_port;
private int server_recv_port;
private String wiki_domain;
private int max_length;
private Xowa_tcp_sender sender;
public void Run(String[] args) {
Print_message_line("XOWA TCP client v0.0.0.0");
// parse args
if (!Parse_args(args)) {
Print_message_line("XOWA console requires 4 args: server_send_port, server_recv_port, wiki_domain, max_length.");
Print_message_line("For example, use '55000 55001 simple.wikipedia.org 1000'");
return;
}
// start sender
sender = new Xowa_tcp_sender(server_send_port);
// start console
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
Print_message_line("Enter page name. For example 'Earth'. Press Ctrl+C to exit. Enter '|server_stop' to stop server or '|exit' to exit.");
Print_message("> ");
try {
while (true) {
String page = Read_string(input);
if (page == null)
break;
else if ("|exit".equals(page))
break;
else if ("|server_stop".equals(page)) {
Send_message_server_stop();
}
else
Send_message_fetch_page(page);
}
}
catch (Exception e) {
Print_error(e);
}
}
private void Send_message_fetch_page(String page) {
Print_message_line("Sending request for " + page);
// String xowa_msg = "0|0000000128|0000000257|xowa.cmd.exec|id_0|sender_0|recipient_0|2013-07-18 01:23:45.678|app.shell.fetch_page('simple.wikipedia.org/wiki/Earth', 'html');";
String command = String.format("app.shell.fetch_page('%s/wiki/%s', 'wiki');", wiki_domain, page);
Send_message(command);
}
private void Send_message_server_stop() {
Print_message_line("Sending request to stop server");
Send_message("app.server.stop;");
}
private void Send_message(String command) {
String id = "id_is_for_client_usage";
String time = "time_is_for_client_usage";
String body = String.format("xowa.cmd.exec|%s|xowa_tcp_console|xowa_server|%s|%s", id, time, command);
int body_len = body.length();
int cksum = (body_len * 2) + 1;
String msg = String.format("0|%s|%s|%s", String.format("%010d", body_len), String.format("%010d", cksum), body);
Xowa_tcp_receiver receiver = new Xowa_tcp_receiver(server_recv_port, max_length);
new Thread(receiver).start();
sender.Send_command(msg);
}
private boolean Parse_args(String[] args) {
if (args.length != 4) {
Print_message_line("4 arguments must be supplied: " + args.length);
return false;
}
server_send_port = Parse_int(args[0]); if (server_send_port == -1) return false;
server_recv_port = Parse_int(args[1]); if (server_recv_port == -1) return false;
wiki_domain = args[2];
max_length = Parse_int(args[3]); if (max_length == -1) return false;
return true;
}
private static int Parse_int(String raw) {
try {return Integer.parseInt(raw);}
catch (Exception e) {
Print_message_line("argument must be numeric: " + raw);
return -1;
}
}
private static String Read_string(BufferedReader input) {
try {return input.readLine();}
catch (IOException e) {return null;}
}
public static void Print_message_line(String msg) {
System.out.println(msg);
}
public static void Print_message(String msg) {
System.out.print(msg);
}
public static void Print_error(Exception e) {
System.err.println(e.getMessage());
}
public static void Sleep(long millis) {
try {Thread.sleep(millis);}
catch (InterruptedException e) {Print_error(e);}
}
}
class Xowa_tcp_sender {
private int port;
private Socket socket;
private OutputStream output_stream;
public Xowa_tcp_sender(int port) {this.port = port;}
public boolean Open_socket() {
try {
socket = new Socket("localhost", port);
// socket.setSoTimeout(10000);
output_stream = socket.getOutputStream();
return true;
}
catch (Exception e) {
Xowa_tcp_console.Print_error(e);
return false;
}
}
public void Send_command(String msg) {
try {
while (!Open_socket()) {
Xowa_tcp_console.Sleep(100);
}
byte[] buffer = msg.getBytes();
output_stream.write(buffer, 0, buffer.length);
Close_socket();
}
catch (Exception e) {
Xowa_tcp_console.Print_error(e);
}
}
public void Close_socket() {
try {
output_stream.close();
socket.close();
}
catch (Exception e) {
Xowa_tcp_console.Print_error(e);
}
}
}
class Xowa_tcp_receiver implements Runnable {
private int port;
private int max_length;
private ServerSocket server_socket;
private Socket client_socket;
private InputStream input_stream;
public Xowa_tcp_receiver(int port, int max_length) {
this.port = port;
this.max_length = max_length;
}
public void run() {
try {
// initialization
server_socket = new ServerSocket(port);
client_socket = server_socket.accept();
// client_socket.setSoTimeout(10000);
byte[] buffer = new byte[65536];
input_stream = client_socket.getInputStream();
// read incoming messages
int read = 0;
while (true) {
String msg = "";
// read header
int body_len_max = 0, body_len_cur = 0;
read = input_stream.read(buffer, 0, 24);
if (read == -1) break;
String body_len_max_str = new String(buffer, 2, 10);
body_len_max = Integer.parseInt(body_len_max_str);
buffer = new byte[body_len_max];
// read rest of body
while (body_len_cur < body_len_max) {
read = input_stream.read(buffer);
if (read == -1) break;
body_len_cur += read;
msg += new String(buffer, 0, read);
}
int msg_length = msg.length();
if (msg_length > max_length) msg_length = max_length;
Xowa_tcp_console.Print_message_line(msg.substring(0, msg_length));
Xowa_tcp_console.Print_message("\n\n> ");
}
this.Close_socket();
}
catch (Exception e) {
Xowa_tcp_console.Print_error(e);
}
}
public void Close_socket() {
try {
input_stream.close();
client_socket.close();
server_socket.close();
}
catch (Exception e) {
// Xowa_tcp_console.Print_error(e); // ignore, else error will print in console
}
}
}