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:
@@ -13,3 +13,22 @@ 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"));
|
||||
}
|
||||
|
||||
@@ -13,3 +13,13 @@ 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;
|
||||
}
|
||||
|
||||
@@ -13,3 +13,36 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,3 +13,144 @@ 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;
|
||||
}
|
||||
|
||||
@@ -13,3 +13,50 @@ 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";
|
||||
}
|
||||
|
||||
@@ -13,3 +13,171 @@ 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")
|
||||
;
|
||||
}
|
||||
|
||||
@@ -13,3 +13,25 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,3 +13,28 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,3 +13,29 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user