sub-invoke()
This commit is contained in:
parent
a65a3d1207
commit
fa432a0482
Binary file not shown.
@ -16,14 +16,13 @@ mkdir bin/assets > /dev/null 2>&1
|
||||
mkdir work > /dev/null 2>&1
|
||||
|
||||
COMPILER="clang++"
|
||||
FLAGS="-w -Wall -$OPT_FLAG -std=c++17 -fpermissive -ffast-math"
|
||||
FLAGS="-g -w -Wall -$OPT_FLAG -std=c++17 -fpermissive -ffast-math"
|
||||
|
||||
LIBS="-ldl -lm -lpthread "
|
||||
SRCFLAGS="-D EXEC_NAME=\"$GF\" -D PLATFORM_NAME=\"linux\""
|
||||
|
||||
echo "Compliling executable..."
|
||||
#time -p
|
||||
$COMPILER src/linux_fastcgi.cpp $SRCFLAGS $FLAGS $LIBS -o bin/$GF.$BUILDMODE.linux.bin 2>&1
|
||||
time -p $COMPILER src/linux_fastcgi.cpp $SRCFLAGS $FLAGS $LIBS -o bin/$GF.$BUILDMODE.linux.bin 2>&1
|
||||
|
||||
if [ $? -eq 0 ]
|
||||
then
|
||||
|
||||
@ -1,31 +1,6 @@
|
||||
#include <dlfcn.h>
|
||||
|
||||
#define RENDER() extern "C" void render()
|
||||
|
||||
typedef void (*call_handler)();
|
||||
typedef void (*request_handler)(Request* request);
|
||||
|
||||
struct SharedUnit {
|
||||
string file_name;
|
||||
string so_name;
|
||||
void* so_handle;
|
||||
request_handler on_setup;
|
||||
call_handler on_render;
|
||||
string compiler_messages;
|
||||
time_t last_compiled;
|
||||
|
||||
~SharedUnit()
|
||||
{
|
||||
if(so_handle)
|
||||
{
|
||||
dlclose(so_handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::map<string, SharedUnit*> units;
|
||||
|
||||
string process_html_literal(string content, string file_name)
|
||||
string process_html_literal(SharedUnit* su, string content)
|
||||
{
|
||||
string pc;
|
||||
string HT_START = "context->print(R\"(";
|
||||
@ -99,9 +74,10 @@ string process_html_literal(string content, string file_name)
|
||||
return(HT_START + pc + HT_END);
|
||||
}
|
||||
|
||||
string preprocess(string content, string file_name)
|
||||
string preprocess_shared_unit(SharedUnit* su)
|
||||
{
|
||||
string pc = "#include \""+get_cwd()+"/src/lib/uce_gen.h\" \n";
|
||||
string content = file_get_contents(su->file_name);
|
||||
string pc = "#include \""+context->server_state->config.COMPILER_SYS_PATH +"/src/lib/uce_gen.h\" \n";
|
||||
string token = "";
|
||||
string html_buffer = "";
|
||||
u8 mode = 0;
|
||||
@ -117,11 +93,11 @@ string preprocess(string content, string file_name)
|
||||
u32 len = token.length() + 3 + end_pos - i;
|
||||
html_buffer.append(content.substr(i, len - (token.length() == 0 ? 3 : 0)));
|
||||
i += len - 1;
|
||||
pc.append(process_html_literal(html_buffer, file_name));
|
||||
pc.append(process_html_literal(su, html_buffer));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("(!) unterminated HTML literal <%s> in %s", token.c_str(), file_name.c_str());
|
||||
printf("(!) unterminated HTML literal <%s> in %s", token.c_str(), su->file_name.c_str());
|
||||
}
|
||||
mode = 0;
|
||||
}
|
||||
@ -160,9 +136,39 @@ string preprocess(string content, string file_name)
|
||||
return(pc);
|
||||
}
|
||||
|
||||
void load_shared_unit(SharedUnit* su)
|
||||
void setup_unit_paths(SharedUnit* su, string file_name)
|
||||
{
|
||||
su->file_name = file_name;
|
||||
|
||||
if(su->src_path.length() > 0) // we did this already
|
||||
return;
|
||||
|
||||
su->src_path = dirname(file_name);
|
||||
su->bin_path = context->server_state->config.BIN_DIRECTORY + su->src_path;
|
||||
su->pre_path = context->server_state->config.BIN_DIRECTORY + su->src_path;
|
||||
|
||||
su->src_file_name = basename(file_name);
|
||||
su->bin_file_name = su->src_file_name + ".so";
|
||||
su->pre_file_name = su->src_file_name + ".cpp";
|
||||
|
||||
su->so_name = su->bin_path + "/" + su->bin_file_name;
|
||||
}
|
||||
|
||||
void load_shared_unit(SharedUnit* su, string file_name)
|
||||
{
|
||||
setup_unit_paths(su, file_name);
|
||||
|
||||
su->on_render = 0;
|
||||
su->on_setup = 0;
|
||||
su->compiler_messages = "";
|
||||
|
||||
if(!file_exists(su->so_name))
|
||||
{
|
||||
printf("(i) unit file not found: %s\n", su->so_name.c_str());
|
||||
su->compiler_messages = "unit file not found";
|
||||
return;
|
||||
}
|
||||
|
||||
su->so_handle = dlopen(su->so_name.c_str(), RTLD_NOW);
|
||||
if(su->so_handle)
|
||||
{
|
||||
@ -181,79 +187,95 @@ void load_shared_unit(SharedUnit* su)
|
||||
}
|
||||
}
|
||||
|
||||
SharedUnit* compile_shared_unit(string file_name)
|
||||
void compile_shared_unit(SharedUnit* su, string file_name)
|
||||
{
|
||||
SharedUnit* su = new SharedUnit();
|
||||
setup_unit_paths(su, file_name);
|
||||
|
||||
string src_path = dirname(file_name);
|
||||
string src_fn = basename(file_name);
|
||||
string dest_path = Config.BIN_DIRECTORY + src_path;
|
||||
string pp_fn = src_fn + ".cpp";
|
||||
string so_fn = src_fn + ".so";
|
||||
if(!file_exists(su->file_name))
|
||||
{
|
||||
su->compiler_messages = "source file not found";
|
||||
return;
|
||||
}
|
||||
|
||||
su->file_name = file_name;
|
||||
su->so_name = dest_path + "/" + so_fn;
|
||||
shell_exec("mkdir -p " + shell_escape(su->pre_path));
|
||||
file_put_contents(su->pre_path + "/" + su->pre_file_name, preprocess_shared_unit(su));
|
||||
|
||||
string pc = preprocess(file_get_contents(file_name), file_name);
|
||||
file_put_contents(dest_path + "/" + pp_fn, pc);
|
||||
printf("Config.COMPILE_SCRIPT %s\n", string(su->pre_path + "/" + su->pre_file_name).c_str());
|
||||
|
||||
su->compiler_messages = trim(shell_exec(Config.COMPILE_SCRIPT+" "+
|
||||
shell_escape(src_path)+" "+
|
||||
shell_escape(dest_path)+" "+
|
||||
shell_escape(src_fn)+" "+
|
||||
shell_escape(pp_fn)+" "+
|
||||
shell_escape(so_fn)
|
||||
su->compiler_messages = trim(shell_exec(context->server_state->config.COMPILE_SCRIPT+" "+
|
||||
shell_escape(su->src_path)+" "+
|
||||
shell_escape(su->bin_path)+" "+
|
||||
shell_escape(su->file_name)+" "+
|
||||
shell_escape(su->pre_file_name)+" "+
|
||||
shell_escape(su->bin_file_name)
|
||||
));
|
||||
|
||||
if(su->compiler_messages.length() > 0)
|
||||
{
|
||||
printf("%s \n", su->compiler_messages.c_str());
|
||||
|
||||
printf("(i) compiled unit %s\n", file_name.c_str());
|
||||
|
||||
load_shared_unit(su);
|
||||
|
||||
return(su);
|
||||
}
|
||||
else
|
||||
{
|
||||
load_shared_unit(su, file_name);
|
||||
printf("(i) compiled unit %s\n", file_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
SharedUnit* get_shared_unit(string file_name)
|
||||
{
|
||||
SharedUnit* su = units[file_name];
|
||||
if(su && su->last_compiled < file_mtime(file_name))
|
||||
SharedUnit* su = context->server_state->units[file_name];
|
||||
auto mod_time = file_mtime(file_name);
|
||||
bool do_recompile = false;
|
||||
if(su && (su->last_compiled < mod_time || mod_time == 0))
|
||||
{
|
||||
delete su;
|
||||
su = 0;
|
||||
do_recompile = true;
|
||||
}
|
||||
if(!su)
|
||||
{
|
||||
su = units[file_name] = compile_shared_unit(file_name);
|
||||
su = new SharedUnit();
|
||||
|
||||
if(do_recompile)
|
||||
{
|
||||
compile_shared_unit(su, file_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
load_shared_unit(su, file_name);
|
||||
if(!su->so_handle)
|
||||
compile_shared_unit(su, file_name);
|
||||
}
|
||||
|
||||
context->server_state->units[file_name] = su;
|
||||
}
|
||||
return(su);
|
||||
}
|
||||
|
||||
void invoke(Request* req, string file_name)
|
||||
void invoke(string file_name)
|
||||
{
|
||||
printf("(i) invoke(%s)\n", file_name.c_str());
|
||||
auto su = get_shared_unit(file_name);
|
||||
if(!su)
|
||||
{
|
||||
printf("Error loading unit %s\n", su->file_name.c_str());
|
||||
printf("Error loading unit %s\n", file_name.c_str());
|
||||
context->print("Error loading unit: "+file_name);
|
||||
}
|
||||
else if(!su->on_render)
|
||||
{
|
||||
req->print("Compiler error: "+su->compiler_messages);
|
||||
context->print("Compiler error: "+su->compiler_messages);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(su->compiler_messages.length() > 0)
|
||||
req->print(su->compiler_messages);
|
||||
context->print(su->compiler_messages);
|
||||
else
|
||||
{
|
||||
su->on_setup(req);
|
||||
string prev_wd = get_cwd();
|
||||
set_cwd(su->src_path);
|
||||
su->on_setup(context);
|
||||
su->on_render();
|
||||
set_cwd(prev_wd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void invoke(string file_name)
|
||||
{
|
||||
return(invoke(context, file_name));
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
struct Settings {
|
||||
struct ServerSettings {
|
||||
|
||||
string BIN_DIRECTORY = "work";
|
||||
string COMPILE_SCRIPT = "scripts/compile";
|
||||
@ -6,6 +6,7 @@ struct Settings {
|
||||
string CONTENT_TYPE = "text/html; charset=utf-8";
|
||||
string SOCKET_PATH = "/run/uce.sock";
|
||||
string TMP_UPLOAD = "/tmp";
|
||||
string COMPILER_SYS_PATH = "";
|
||||
u32 LISTEN_PORT = 9993;
|
||||
|
||||
} Config;
|
||||
};
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
string shell_exec(string cmd)
|
||||
{
|
||||
printf("(i) shell_exec(%s)\n", cmd.c_str());
|
||||
string data;
|
||||
FILE * stream;
|
||||
const int max_buffer = 256;
|
||||
@ -98,6 +99,11 @@ string get_cwd()
|
||||
return(std::filesystem::current_path());
|
||||
}
|
||||
|
||||
void set_cwd(string path)
|
||||
{
|
||||
chdir(path.c_str());
|
||||
}
|
||||
|
||||
time_t file_mtime(string file_name)
|
||||
{
|
||||
struct stat info;
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
#include <sys/stat.h>
|
||||
#include <ctime>
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef std::string string;
|
||||
|
||||
@ -33,11 +34,47 @@ typedef long long s64;
|
||||
typedef std::map<string, string> StringMap;
|
||||
typedef std::vector<string> StringList;
|
||||
|
||||
typedef void (*invoke_handler)(string file_name);
|
||||
|
||||
struct UploadedFile {
|
||||
string file_name;
|
||||
string tmp_name;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct Request;
|
||||
|
||||
typedef void (*call_handler)();
|
||||
typedef void (*request_handler)(Request* request);
|
||||
|
||||
struct SharedUnit {
|
||||
|
||||
string file_name;
|
||||
string so_name;
|
||||
|
||||
string src_path;
|
||||
string bin_path;
|
||||
string pre_path;
|
||||
string src_file_name;
|
||||
string bin_file_name;
|
||||
string pre_file_name;
|
||||
|
||||
void* so_handle;
|
||||
|
||||
request_handler on_setup;
|
||||
call_handler on_render;
|
||||
|
||||
string compiler_messages;
|
||||
time_t last_compiled;
|
||||
|
||||
~SharedUnit()
|
||||
{
|
||||
if(so_handle)
|
||||
{
|
||||
dlclose(so_handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#include "dtree.h"
|
||||
|
||||
|
||||
@ -3,9 +3,17 @@
|
||||
#include "datastructures.h"
|
||||
#include "sys.h"
|
||||
#include "time.h"
|
||||
#include "uri.h"
|
||||
|
||||
struct FastCGIRequest {
|
||||
struct ServerState {
|
||||
|
||||
std::map<string, SharedUnit*> units;
|
||||
ServerSettings config;
|
||||
|
||||
} server_state;
|
||||
|
||||
struct Request {
|
||||
|
||||
ServerState* server_state;
|
||||
|
||||
StringMap params;
|
||||
StringMap get;
|
||||
@ -29,13 +37,15 @@ struct FastCGIRequest {
|
||||
|
||||
};
|
||||
|
||||
typedef FastCGIRequest Request;
|
||||
typedef Request FastCGIRequest;
|
||||
|
||||
Request* context;
|
||||
|
||||
#include "uri.h"
|
||||
#include "compiler.h"
|
||||
|
||||
extern "C" void set_current_request(Request* _request)
|
||||
{
|
||||
context = _request;
|
||||
}
|
||||
|
||||
#include "compiler.h"
|
||||
|
||||
@ -177,7 +177,7 @@ struct URI {
|
||||
{
|
||||
nibble("=\"", field);
|
||||
UploadedFile f;
|
||||
f.tmp_name = Config.TMP_UPLOAD + to_string(rand());
|
||||
f.tmp_name = context->server_state->config.TMP_UPLOAD + to_string(rand());
|
||||
f.file_name = nibble("\"", field);
|
||||
string bin = field.substr(4, field.length()-6);
|
||||
f.size = bin.length();
|
||||
|
||||
@ -38,9 +38,11 @@ int handle_complete(FastCGIRequest& request) {
|
||||
// The event handler can also be a class member function. This
|
||||
// event occurs when the parameters and standard input streams are
|
||||
// both closed, and thus the request is complete.
|
||||
context = &request;
|
||||
request.server_state = &server_state;
|
||||
request.time_start = microtime();
|
||||
|
||||
request.header["Content-Type"] = Config.CONTENT_TYPE;
|
||||
request.header["Content-Type"] = context->server_state->config.CONTENT_TYPE;
|
||||
request.get = URI::parse_query(request.params["QUERY_STRING"]);
|
||||
|
||||
string ct_info = request.params["CONTENT_TYPE"];
|
||||
@ -59,7 +61,7 @@ int handle_complete(FastCGIRequest& request) {
|
||||
}
|
||||
}
|
||||
|
||||
invoke(&request, request.params["SCRIPT_FILENAME"]);
|
||||
invoke(request.params["SCRIPT_FILENAME"]);
|
||||
|
||||
string headers = var_dump(request.header, "", "\r\n") + "\r\n";
|
||||
request.out = headers + request.out;
|
||||
@ -87,11 +89,17 @@ int main(int argc, char** argv)
|
||||
server.data_handler(&handle_data);
|
||||
server.complete_handler(&handle_complete);
|
||||
|
||||
if(Config.LISTEN_PORT)
|
||||
server.listen(Config.LISTEN_PORT);
|
||||
if(Config.SOCKET_PATH != "")
|
||||
server.listen(Config.SOCKET_PATH);
|
||||
chmod(Config.SOCKET_PATH.c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
if(server_state.config.COMPILER_SYS_PATH == "")
|
||||
server_state.config.COMPILER_SYS_PATH = get_cwd();
|
||||
server_state.config.BIN_DIRECTORY =
|
||||
server_state.config.COMPILER_SYS_PATH + "/" + server_state.config.BIN_DIRECTORY;
|
||||
server_state.config.COMPILE_SCRIPT =
|
||||
server_state.config.COMPILER_SYS_PATH + "/" + server_state.config.COMPILE_SCRIPT;
|
||||
if(server_state.config.LISTEN_PORT)
|
||||
server.listen(server_state.config.LISTEN_PORT);
|
||||
if(server_state.config.SOCKET_PATH != "")
|
||||
server.listen(server_state.config.SOCKET_PATH);
|
||||
chmod(server_state.config.SOCKET_PATH.c_str(), S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
|
||||
|
||||
//server.process(100);
|
||||
//server.process();
|
||||
|
||||
@ -4,7 +4,7 @@ RENDER()
|
||||
{
|
||||
|
||||
<html>
|
||||
<link rel="stylesheet" href='style.css?v=1'></link>
|
||||
<link rel="stylesheet" href='style.css'></link>
|
||||
<h1>
|
||||
<a href="index.uce">UCE Test</a>:
|
||||
Index
|
||||
@ -13,6 +13,7 @@ RENDER()
|
||||
<li><a href="hello.uce">Hello</a></li>
|
||||
<li><a href="post.uce">Form Post</a></li>
|
||||
<li><a href="post-multipart.uce">Form Multipart Post</a></li>
|
||||
<li><a href="working-dir.uce">Working Directory</a></li>
|
||||
</ul>
|
||||
<pre><?= var_dump(context->params) ?></pre>
|
||||
</html>
|
||||
|
||||
@ -65,7 +65,8 @@ textarea {
|
||||
pre {
|
||||
height: 20%;
|
||||
overflow: auto;
|
||||
padding. 8px;
|
||||
padding: 8px;
|
||||
border: 2px solid rgba(0,0,0,0.2);
|
||||
background: rgba(100,100,100,0.15);
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
6
test/test2/working-dir-test.uce
Normal file
6
test/test2/working-dir-test.uce
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
RENDER()
|
||||
{
|
||||
echo("Sub-Invoke Working dir: " + get_cwd() + "\n");
|
||||
}
|
||||
19
test/working-dir.uce
Normal file
19
test/working-dir.uce
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
|
||||
RENDER()
|
||||
{
|
||||
|
||||
<>
|
||||
<link rel="stylesheet" href='style.css'></link>
|
||||
<h1>
|
||||
<a href="index.uce">UCE Test</a>:
|
||||
Working Directory
|
||||
</h1>
|
||||
<pre><?
|
||||
echo("Base WD: " + get_cwd() + "\n");
|
||||
invoke("/Code/uce.openfu.com/uce/test/test2/working-dir-test.uce");
|
||||
?></pre>
|
||||
<pre><?= var_dump(context->params) ?></pre>
|
||||
</>
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user