started memcache work, sockets

This commit is contained in:
Udo 2021-11-21 17:02:18 +00:00
parent b1b4a0267a
commit 9388093d92
8 changed files with 158 additions and 24 deletions

Binary file not shown.

View File

@ -1,4 +1,4 @@
#define RENDER() extern "C" void render()
#define RENDER() extern "C" void render(DTree& call)
string process_html_literal(Request* context, SharedUnit* su, string content)
{
@ -253,7 +253,7 @@ SharedUnit* get_shared_unit(Request* context, string file_name)
return(su);
}
void compiler_invoke(Request* context, string file_name)
void compiler_invoke(Request* context, string file_name, DTree& call_param)
{
if(file_name[0] != '/')
{
@ -270,6 +270,7 @@ void compiler_invoke(Request* context, string file_name)
}
else if(!su->on_render)
{
context->header["Content-Type"] = "text/plain";
context->print("Compiler error: "+su->compiler_messages);
}
else
@ -281,7 +282,7 @@ void compiler_invoke(Request* context, string file_name)
string prev_wd = get_cwd();
set_cwd(su->src_path);
su->on_setup(context);
su->on_render();
su->on_render(call_param);
set_cwd(prev_wd);
}
}

View File

@ -1,5 +1,10 @@
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
string shell_exec(string cmd)
{
@ -222,4 +227,94 @@ u64 parse_time(string time_string)
return(int_val(trim(shell_exec("date -u -d '"+time_string+"' +'%s'"))));
}
u64 socket_connect(string host, short port)
{
/*struct addrinfo {
int ai_flags;
int ai_family;
int ai_socktype;
int ai_protocol;
socklen_t ai_addrlen;
struct sockaddr *ai_addr;
char *ai_canonname;
struct addrinfo *ai_next;
};*/
auto sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if(sockfd < 0)
{
echo("SOCKET ERROR (could not open socket)\n");
perror("SOCKET ERROR ");
return(0);
}
struct sockaddr_in addr = {0};
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = inet_addr(host.c_str());
if(connect(sockfd, (struct sockaddr*) &addr, sizeof(addr)) < 0)
{
echo("SOCKET ERROR (could not connect to address " + string(host) + ":" + std::to_string(port) + ")\n");
perror("SOCKET ERROR ");
return(0);
}
context->resources.sockets.push_back(sockfd);
return(sockfd);
}
void socket_close(u64 sockfd)
{
close(sockfd);
}
bool socket_write(u64 sockfd, string data)
{
return(write(sockfd, data.c_str(), data.length()) >= 0);
}
string socket_read(u64 sockfd, u32 max_length = 1024*128, u32 timeout = 1)
{
struct timeval tv;
tv.tv_sec = timeout;
tv.tv_usec = 0;
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&tv, sizeof tv);
char buf[max_length+1];
auto byte_count = recv(sockfd, buf, sizeof(buf), 0);
if(byte_count > 0)
{
buf[byte_count] = 0;
string result(buf, byte_count+1);
return(result);
}
return("");
}
u64 memcache_connect(string host = "127.0.0.1", short port = 11211)
{
return(socket_connect(host, port));
}
string memcache_get_raw(u64 connection, string command)
{
socket_write(connection, command+"\r\n");
return(socket_read(connection)); // FIXME: do multi-chunk until END line is received!
}
bool memcache_set(u64 connection, string key, string value, u64 expires_in = 60*60)
{
// to do: escape key string
socket_write(connection,
// set KEY META_DATA EXPIRY_TIME LENGTH_IN_BYTES
string("set ") + (key) + " 0 " + std::to_string(expires_in) + " " + std::to_string(value.length()) + "\r\n" +
value + "\r\n");
return("STORED" == trim(socket_read(connection)));
}
string memcache_get(u64 connection, string key)
{
// to do: escape key string
auto res = memcache_get_raw(connection, string("get ")+key);
}

View File

@ -39,11 +39,10 @@ typedef long long s64;
typedef std::map<string, string> StringMap;
typedef std::list<string> StringList;
typedef void (*invoke_handler)(string file_name);
struct Request;
struct DTree;
typedef void (*call_handler)();
typedef void (*call_handler)(DTree& call_param);
typedef void (*request_handler)(Request* request);
string to_string(u64 v) { return(std::to_string(v)); }
@ -107,8 +106,6 @@ struct ServerState {
};
void compiler_invoke(Request* context, string file_name);
struct URI {
StringMap query;
@ -145,6 +142,8 @@ string to_hex(ITYPE w, size_t hex_len = sizeof(ITYPE)<<1)
#include "dtree.h"
void compiler_invoke(Request* context, string file_name, DTree& call_param);
struct Request {
ServerState* server;
@ -172,9 +171,19 @@ struct Request {
f64 time_start;
f64 time_end;
struct Resources {
std::vector<u64> sockets;
} resources;
void invoke(string file_name)
{
compiler_invoke(this, file_name);
DTree call_param;
compiler_invoke(this, file_name, call_param);
}
void invoke(string file_name, DTree& call_param)
{
compiler_invoke(this, file_name, call_param);
}
void print(string s)
@ -182,6 +191,12 @@ struct Request {
out.append(s);
}
~Request()
{
for(auto& sockfd : resources.sockets)
close(sockfd);
}
};
typedef Request FastCGIRequest;

View File

@ -19,6 +19,7 @@ RENDER()
<li><a href="session.uce">Session</a></li>
<li><a href="dtree.uce">DTree</a></li>
<li><a href="json.uce">JSON</a></li>
<li><a href="memcached.uce">Memcached</a></li>
</ul>
<pre><?= var_dump(context->params) ?></pre>
</>

37
test/memcached.uce Normal file
View File

@ -0,0 +1,37 @@
RENDER()
{
DTree t;
<>
<link rel="stylesheet" href='style.css'></link>
<h1>
<a href="index.uce">UCE Test</a>:
MemcacheD
</h1>
Stats:
<pre><?
auto sfd = memcache_connect();
echo(memcache_get_raw(sfd, "stats"));
?></pre>
Set/Get:
<pre><?
memcache_set(sfd, "test_key", "test_value");
echo(memcache_get_raw(sfd, "get test_key"));
?></pre>
Params
<pre><?= var_dump(context->params) ?></pre>
</>
}

View File

@ -1,12 +0,0 @@
RENDER()
{
DTree t;
echo(json_encode(t));
echo(string("PATH: ") + context->server->config.COMPILER_SYS_PATH + "\n");
}

View File

@ -4,7 +4,6 @@ Library
- mysql
- sha1 / md5 / meow
- cache
- json_encode / json_decode
- curl
- random
- pseudorandom
@ -14,8 +13,6 @@ Bugs
=================================
- shell_escape()
- we crash on illegal paths
- you should not be able to invoke() outside of DOCUMENT_ROOT
- invoke path should not be the same as cwd (cwd should be path of entry point file)
Framework