This commit is contained in:
udo
2021-10-29 03:50:46 +00:00
parent 3f531aa48e
commit e630d10ad1
21 changed files with 335 additions and 37 deletions
+1 -1
View File
@@ -97,7 +97,7 @@ protected:
bool close_socket;
};
typedef std::map<std::string, std::string> Pairs;
typedef StringMap Pairs;
std::vector<int> listen_sockets;
std::vector<std::string> listen_unlink;
+22 -15
View File
@@ -1,6 +1,6 @@
#include <dlfcn.h>
#define RENDER() extern "C" void render()
#define RENDER() extern "C" void render()
typedef void (*call_handler)();
typedef void (*request_handler)(Request* request);
@@ -30,12 +30,12 @@ string process_html_literal(string content, string file_name)
string pc;
string HT_START = "context->print(R\"(";
string HT_END = ")\");";
u8 mode = 0;
bool inside_quote = false;
string code_buffer = "";
bool is_field = false;
for(u32 i = 0; i < content.length(); i++)
{
char c = content[i];
@@ -53,10 +53,10 @@ string process_html_literal(string content, string file_name)
if(is_field)
{
pc.append(
HT_END +
HT_END +
"echo(html_escape( " +
code_buffer +
" )); " +
" )); " +
HT_START
);
}
@@ -67,7 +67,7 @@ string process_html_literal(string content, string file_name)
}
else
{
code_buffer.append(1, c);
code_buffer.append(1, c);
}
}
else if(!inside_quote && c == '<' && content[i+1] == '?')
@@ -85,11 +85,11 @@ string process_html_literal(string content, string file_name)
}
mode = 1;
}
else if(c == '\"')
/*else if(c == '\"')
{
inside_quote = !inside_quote;
pc.append(1, c);
}
}*/
else
{
pc.append(1, c);
@@ -115,7 +115,7 @@ string preprocess(string content, string file_name)
if(end_pos != string::npos)
{
u32 len = token.length() + 3 + end_pos - i;
html_buffer.append(content.substr(i, len));
html_buffer.append(content.substr(i, len - (token.length() == 0 ? 3 : 0)));
i += len - 1;
pc.append(process_html_literal(html_buffer, file_name));
}
@@ -128,17 +128,24 @@ string preprocess(string content, string file_name)
else if(mode == 1)
{
if(isspace(c) || c == '>')
{
mode = 2;
if(token.length() > 0)
html_buffer.append(1, c);
}
else
{
token.append(1, c);
html_buffer.append(1, c);
html_buffer.append(1, c);
}
}
else if(!inside_quote && c == '<' && isalpha(content[i+1]))
else if(!inside_quote && c == '<' && (content[i+1] == '>' || isalpha(content[i+1])))
{
mode = 1;
token = "";
html_buffer = "";
html_buffer.append(1, c);
if(content[i+1] != '>')
html_buffer.append(1, c);
}
else if(c == '\"')
{
@@ -203,7 +210,7 @@ SharedUnit* compile_shared_unit(string file_name)
printf("(i) compiled unit %s\n", file_name.c_str());
load_shared_unit(su);
load_shared_unit(su);
return(su);
}
@@ -241,7 +248,7 @@ void invoke(Request* req, string file_name)
else
{
su->on_setup(req);
su->on_render();
su->on_render();
}
}
}
@@ -249,4 +256,4 @@ void invoke(Request* req, string file_name)
void invoke(string file_name)
{
return(invoke(context, file_name));
}
}
+19 -2
View File
@@ -71,7 +71,7 @@ string implode(StringList l, string delim = "\n")
string html_escape(string s)
{
string result;
for(u32 i = 0; i < s.length(); i++)
{
char c = s[i];
@@ -111,4 +111,21 @@ string html_escape(f64 a)
u64 int_val(string s, u32 base = 10)
{
return(strtoll(s.c_str(), 0, base));
}
}
string nibble(string div, string& haystack)
{
auto pos = haystack.find(div);
if(pos == string::npos)
{
auto result = haystack;
haystack.clear();
return(result);
}
else
{
auto result = haystack.substr(0, pos);
haystack.erase(0, pos+div.length());
return(result);
}
}
+2 -1
View File
@@ -5,6 +5,7 @@ struct Settings {
string LIT_ESC = "3d5b5_1";
string CONTENT_TYPE = "text/html; charset=utf-8";
string SOCKET_PATH = "/run/uce.sock";
string TMP_UPLOAD = "/tmp";
u32 LISTEN_PORT = 9993;
} Config;
} Config;
+5
View File
@@ -110,3 +110,8 @@ time_t file_mtime(string file_name)
return(info.st_mtime);
}
}
void unlink(string file_name)
{
remove(file_name.c_str());
}
+7
View File
@@ -2,6 +2,7 @@
#include <unistd.h>
#include <iostream>
#include <string>
//#include <unordered_map>
#include <map>
#include <filesystem>
#include <ctype.h>
@@ -32,5 +33,11 @@ typedef long long s64;
typedef std::map<string, string> StringMap;
typedef std::vector<string> StringList;
struct UploadedFile {
string file_name;
string tmp_name;
u32 size;
};
#include "dtree.h"
+7 -3
View File
@@ -6,14 +6,18 @@
#include "uri.h"
struct FastCGIRequest {
StringMap params;
StringMap get;
StringMap post;
std::vector<UploadedFile> uploaded_files;
StringMap header;
URI uri;
std::string in;
std::string out;
std::string err;
f64 time_init;
f64 time_start;
f64 time_end;
+43
View File
@@ -137,6 +137,7 @@ struct URI {
result[URI::decode(key)] = URI::decode(value);
key = "";
value = "";
is_key = true;
}
else if(is_key)
{
@@ -153,6 +154,48 @@ struct URI {
return(result);
}
static StringMap parse_multipart(string q, string boundary, std::vector<UploadedFile>& uploaded_files)
{
StringMap result;
auto i = boundary.length();
while(i < q.length())
{
auto end_pos = q.find(boundary, i);
if(end_pos != string::npos)
{
string field = q.substr(i, end_pos - i);
nibble(":", field);
string ftype = trim(nibble(";", field));
if(ftype == "form-data")
{
nibble("=\"", field);
string field_name = nibble("\"", field);
result[field_name] = field.substr(4, field.length()-6);
}
else if(ftype == "attachment")
{
nibble("=\"", field);
UploadedFile f;
f.tmp_name = Config.TMP_UPLOAD + to_string(rand());
f.file_name = nibble("\"", field);
string bin = field.substr(4, field.length()-6);
f.size = bin.length();
file_put_contents(f.tmp_name, bin);
uploaded_files.push_back(f);
}
}
else
{
// we're done
end_pos = q.length();
}
i = end_pos + boundary.length();
}
return(result);
}
static string decode(string q)
{
string result;
+26 -10
View File
@@ -11,9 +11,6 @@ int handle_request(FastCGIRequest& request) {
// server receives all parameters. There may be more data coming on the
// standard input stream.
request.time_init = microtime();
request.out.reserve(128 * 1024);
request.in.reserve(128 * 1024);
request.err.reserve(128 * 1024);
if (request.params.count("REQUEST_URI"))
return 0; // OK, continue processing
else
@@ -42,20 +39,39 @@ int handle_complete(FastCGIRequest& request) {
// event occurs when the parameters and standard input streams are
// both closed, and thus the request is complete.
request.time_start = microtime();
request.header["Content-Type"] = Config.CONTENT_TYPE;
request.uri = URI::parse(request.params["REQUEST_URI"]);
request.uri.parts["scheme"] = request.params["REQUEST_SCHEME"];
request.uri.parts["method"] = request.params["REQUEST_METHOD"];
request.uri.parts["host"] = request.params["HTTP_HOST"];
request.get = URI::parse_query(request.params["QUERY_STRING"]);
string ct_info = request.params["CONTENT_TYPE"];
string ct_type = nibble(";", ct_info);
if(request.params["REQUEST_METHOD"] == "POST")
{
if(ct_type == "multipart/form-data")
{
nibble("boundary=", ct_info);
request.post = URI::parse_multipart(request.in, string("--")+ct_info, request.uploaded_files);
}
else
{
request.post = URI::parse_query(request.in);
}
}
invoke(&request, request.params["SCRIPT_FILENAME"]);
string headers = var_dump(request.header, "", "\r\n") + "\r\n";
request.out = headers + request.out;
for( auto &f : request.uploaded_files)
{
unlink(f.tmp_name);
}
request.time_end = microtime();
printf("(r) %s\t%0.6fs\t%0.1fkB\n",
request.params["REQUEST_URI"].c_str(),
printf("(r) %s\t%0.6fs\t%0.1fkB\n",
request.params["REQUEST_URI"].c_str(),
request.time_end - request.time_start,
(f32)(request.out.length()/1024)
);