diff --git a/bin/uce_fastcgi.debug.linux.bin b/bin/uce_fastcgi.debug.linux.bin index 21af37e..e292064 100755 Binary files a/bin/uce_fastcgi.debug.linux.bin and b/bin/uce_fastcgi.debug.linux.bin differ diff --git a/src/lib/datastructures.h b/src/lib/datastructures.h index 027cc25..ee606be 100644 --- a/src/lib/datastructures.h +++ b/src/lib/datastructures.h @@ -38,7 +38,8 @@ u8 hex_to_u8(string src) return(char_to_u8(src[0])*16 + char_to_u8(src[1])); } -template string to_hex(ITYPE w, size_t hex_len = sizeof(ITYPE)<<1) +template +string to_hex(ITYPE w, size_t hex_len = sizeof(ITYPE)<<1) { static const char* digits = "0123456789ABCDEF"; string rc(hex_len,'0'); diff --git a/src/lib/sys.h b/src/lib/sys.h index 99e7fe8..d242833 100644 --- a/src/lib/sys.h +++ b/src/lib/sys.h @@ -66,6 +66,12 @@ string dirname(string fn) return(result); } +bool mkdir(string path) +{ + shell_exec(string("mkdir -p ")+" "+shell_escape(path)); + return(true); +} + bool file_exists(string path) { std::filesystem::path fp{ path }; diff --git a/src/lib/types.h b/src/lib/types.h index f91a630..c166c52 100644 --- a/src/lib/types.h +++ b/src/lib/types.h @@ -48,9 +48,11 @@ struct ServerSettings { string LIT_ESC = "3d5b5_1"; string CONTENT_TYPE = "text/html; charset=utf-8"; string SOCKET_PATH = "/run/uce.sock"; - string TMP_UPLOAD = "/tmp"; + string TMP_UPLOAD_PATH = "/tmp/uce/uploads"; + string SESSION_PATH = "/tmp/uce/sessions"; string COMPILER_SYS_PATH = ""; u32 LISTEN_PORT = 9993; + u64 SESSION_TIME = 60*60*24*30; }; @@ -106,6 +108,9 @@ struct Request { StringMap get; StringMap post; StringMap cookies; + StringMap session; + string session_id = ""; + string session_name = ""; std::vector uploaded_files; StringMap header; diff --git a/src/lib/uri.h b/src/lib/uri.h index a4861ab..48bc3d6 100644 --- a/src/lib/uri.h +++ b/src/lib/uri.h @@ -83,6 +83,20 @@ StringMap parse_query(string q) return(result); } +string encode_query(StringMap map) +{ + string result; + + for (auto it = map.begin(); it != map.end(); ++it) + { + if(result.length() > 0) + result.append(1, '&'); + result.append(uri_encode(it->first) + "=" + uri_encode(it->second)); + } + + return(result); +} + StringMap parse_multipart(string q, string boundary, std::vector& uploaded_files) { StringMap result; @@ -106,7 +120,7 @@ StringMap parse_multipart(string q, string boundary, std::vector& { nibble("=\"", field); UploadedFile f; - f.tmp_name = context->server_state->config.TMP_UPLOAD + to_string(rand()); + f.tmp_name = context->server_state->config.TMP_UPLOAD_PATH + to_string(rand()); f.file_name = nibble("\"", field); string bin = field.substr(4, field.length()-6); f.size = bin.length(); @@ -248,8 +262,8 @@ void set_cookie( cookie.append(uri_encode(name) + "=" + uri_encode(value)); if(expires > 0) cookie.append(string("; Expires=") + gmdate("RFC1123", expires)); - context->set_cookies.push_back(cookie); + context->cookies[name] = value; } StringMap parse_cookies(string cookie_string) @@ -263,3 +277,40 @@ StringMap parse_cookies(string cookie_string) } return(result); } + +string make_session_id() +{ + return(to_hex(rand())+to_hex(rand())+to_hex(rand())+to_hex(rand())); +} + +StringMap load_session_data(string session_id) +{ + return(parse_query(file_get_contents(context->server_state->config.SESSION_PATH + "/" + session_id))); +} + +void save_session_data(string session_id, StringMap data) +{ + file_put_contents(context->server_state->config.SESSION_PATH + "/" + session_id, encode_query(data)); +} + +string session_start(string session_name = "uce-session") +{ + if(context->cookies[session_name].length() == 0) + { + set_cookie(session_name, make_session_id(), time() + context->server_state->config.SESSION_TIME); + } + context->session_id = context->cookies[session_name]; + context->session_name = session_name; + context->session = load_session_data(context->session_id); + return(context->session_id); +} + +void session_destroy(string session_name = "uce-session") +{ + if(context->cookies[session_name].length() > 0) + { + set_cookie(session_name, "", time() - context->server_state->config.SESSION_TIME); + context->session.clear(); + context->session_id = ""; + } +} diff --git a/src/linux_fastcgi.cpp b/src/linux_fastcgi.cpp index de27a35..6ddac76 100644 --- a/src/linux_fastcgi.cpp +++ b/src/linux_fastcgi.cpp @@ -77,6 +77,9 @@ int handle_complete(FastCGIRequest& request) { unlink(f.tmp_name); } + if(request.session_id.length() > 0) + save_session_data(request.session_id, request.session); + request.time_end = microtime(); printf("(r) %s\t%0.6fs\t%0.1fkB\n", request.params["REQUEST_URI"].c_str(), @@ -90,6 +93,8 @@ FastCGIServer server; int main(int argc, char** argv) { + srand(time()); + // Set up our request handlers server.request_handler(&handle_request); server.data_handler(&handle_data); @@ -110,6 +115,9 @@ int main(int argc, char** argv) dirname(server_state.config.COMPILER_SYS_PATH); basename(server_state.config.COMPILER_SYS_PATH); + mkdir(server_state.config.TMP_UPLOAD_PATH); + mkdir(server_state.config.SESSION_PATH); + //server.process(100); //server.process(); server.process_forever(); diff --git a/test/cookie.uce b/test/cookie.uce index 9201215..c50a959 100644 --- a/test/cookie.uce +++ b/test/cookie.uce @@ -9,11 +9,7 @@ RENDER() UCE Test: Cookies -
cookies));
-
-		?>
+ Set
set_cookies));
 
 		?>
+ Get +
cookies));
+
+		?>
+ Params
params) ?>
diff --git a/test/index.uce b/test/index.uce index 1a49299..c162ed6 100644 --- a/test/index.uce +++ b/test/index.uce @@ -16,6 +16,7 @@ RENDER()
  • Working Directory
  • URI
  • Cookies
  • +
  • Session
  • params) ?>
    diff --git a/test/session.uce b/test/session.uce new file mode 100644 index 0000000..2cf988a --- /dev/null +++ b/test/session.uce @@ -0,0 +1,52 @@ + + +RENDER() +{ + + <> + +

    + UCE Test: + Session +

    + + + + string action = context->get["action"]; + if(context->cookies["uce-session"].length() > 0) + session_start(); + if(action == "start") + { + session_start(); + echo("action: starting session"); + } + else if(action == "store") + { + context->session["stored-value"] = make_session_id(); + echo("action: storing value "+context->session["stored-value"]); + } + else if(action == "destroy") + { + session_destroy(); + echo("action: destroying session"); + } + + <> +
    + Start Session | + Refresh | + Destroy Session | + Store Value | + Info +
    cookies));
    +		echo("SESSION:\n");
    +		echo(var_dump(context->session));
    +
    +		?>
    + Params +
    params) ?>
    + + +} diff --git a/todo.txt b/todo.txt index 2b27da9..a1792ce 100644 --- a/todo.txt +++ b/todo.txt @@ -5,7 +5,6 @@ Library - sha1 / md5 / meow - cache - json_encode / json_decode -- session - curl - random - pseudorandom @@ -20,7 +19,7 @@ Bugs Framework ================================= -- DTree +- DTree< - File Upload - Proxy mode - WebSockets