started memcache work, sockets
This commit is contained in:
parent
b1b4a0267a
commit
9388093d92
Binary file not shown.
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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
37
test/memcached.uce
Normal 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>
|
||||
</>
|
||||
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
|
||||
|
||||
RENDER()
|
||||
{
|
||||
|
||||
DTree t;
|
||||
|
||||
echo(json_encode(t));
|
||||
|
||||
echo(string("PATH: ") + context->server->config.COMPILER_SYS_PATH + "\n");
|
||||
|
||||
}
|
||||
3
todo.txt
3
todo.txt
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user