mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-09-06 13:41:28 +00:00
another bunch of erlang features: atoms are mapped to unicode
This commit is contained in:
+31
-1
@@ -338,6 +338,9 @@ int erlang_init() {
|
||||
char *host;
|
||||
struct sockaddr_in sin;
|
||||
socklen_t slen = sizeof(struct sockaddr_in);
|
||||
char *ip = NULL;
|
||||
char *nodename;
|
||||
struct in_addr addr;
|
||||
|
||||
if (uerl.name) {
|
||||
|
||||
@@ -351,8 +354,35 @@ int erlang_init() {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
nodename = uwsgi_concat2n(uerl.name, host-uerl.name, "",0);
|
||||
ip = uwsgi_resolve_ip(host+1);
|
||||
if (ip) {
|
||||
#ifdef UWSGI_DEBUG
|
||||
uwsgi_log("ip: %s\n", ip);
|
||||
#endif
|
||||
addr.s_addr = inet_addr(ip);
|
||||
if (ei_connect_xinit(&uerl.cnode, host+1, nodename, uerl.name, &addr, uerl.cookie, 0) < 0) {
|
||||
uwsgi_log("unable to initialize erlang connection\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ei_connect_init(&uerl.cnode, nodename, uerl.cookie, 0) < 0) {
|
||||
uwsgi_log("unable to initialize erlang connection\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
free(nodename);
|
||||
}
|
||||
|
||||
if (ip) {
|
||||
uerl.fd = bind_to_tcp(ip, uwsgi.listen_queue, NULL);
|
||||
}
|
||||
else {
|
||||
uerl.fd = bind_to_tcp("", uwsgi.listen_queue, NULL);
|
||||
}
|
||||
|
||||
uerl.fd = bind_to_tcp("", uwsgi.listen_queue, NULL);
|
||||
if (uerl.fd < 0) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
+191
-8
@@ -15,46 +15,224 @@ PyObject *pyerl_connect(PyObject * self, PyObject * args) {
|
||||
|
||||
int py_to_erl(PyObject *, ei_x_buff*);
|
||||
|
||||
PyObject *pyerl_simple_send(PyObject * self, PyObject * args) {
|
||||
PyObject *erl_to_py(ei_x_buff* x) {
|
||||
|
||||
char *node;
|
||||
int etype, esize, arity;
|
||||
long long num;
|
||||
double fnum;
|
||||
char *atom, *binary;
|
||||
long bin_size;
|
||||
PyObject *pobj;
|
||||
PyObject *zero;
|
||||
erlang_pid epid;
|
||||
int i;
|
||||
|
||||
ei_get_type(x->buff, &x->index, &etype, &esize);
|
||||
|
||||
switch(etype) {
|
||||
case ERL_SMALL_INTEGER_EXT:
|
||||
case ERL_INTEGER_EXT:
|
||||
case ERL_SMALL_BIG_EXT:
|
||||
case ERL_LARGE_BIG_EXT:
|
||||
ei_decode_longlong(x->buff, &x->index, &num);
|
||||
return PyLong_FromLong(num);
|
||||
case ERL_FLOAT_EXT:
|
||||
ei_decode_double(x->buff, &x->index, &fnum);
|
||||
return PyFloat_FromDouble(fnum);
|
||||
case ERL_STRING_EXT:
|
||||
atom = uwsgi_malloc(esize+1);
|
||||
ei_decode_string(x->buff, &x->index, atom);
|
||||
pobj = PyString_FromString(atom);
|
||||
free(atom);
|
||||
return pobj;
|
||||
case ERL_ATOM_EXT:
|
||||
atom = uwsgi_malloc(esize+1);
|
||||
ei_decode_atom(x->buff, &x->index, atom);
|
||||
pobj = PyUnicode_FromString(atom);
|
||||
free(atom);
|
||||
return pobj;
|
||||
case ERL_SMALL_TUPLE_EXT:
|
||||
case ERL_LARGE_TUPLE_EXT:
|
||||
ei_decode_tuple_header(x->buff, &x->index, &arity);
|
||||
pobj = PyTuple_New(arity);
|
||||
for(i=0;i<arity;i++) {
|
||||
zero = erl_to_py(x);
|
||||
PyTuple_SetItem(pobj, i, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
return pobj;
|
||||
case ERL_LIST_EXT:
|
||||
case ERL_NIL_EXT:
|
||||
ei_decode_list_header(x->buff, &x->index, &arity);
|
||||
if (!arity) {
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
pobj = PyList_New(0);
|
||||
for(i=0;i<arity+1;i++) {
|
||||
zero = erl_to_py(x);
|
||||
PyList_Append(pobj, zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
return pobj;
|
||||
case ERL_BINARY_EXT:
|
||||
binary = uwsgi_malloc(esize);
|
||||
ei_decode_binary(x->buff, &x->index, binary, &bin_size);
|
||||
pobj = PyString_FromStringAndSize(binary, bin_size);
|
||||
free(binary);
|
||||
return pobj;
|
||||
case ERL_PID_EXT:
|
||||
ei_decode_pid(x->buff, &x->index, &epid);
|
||||
pobj = PyTuple_New(3);
|
||||
PyTuple_SetItem(pobj, 0, PyInt_FromLong(epid.num));
|
||||
PyTuple_SetItem(pobj, 1, PyInt_FromLong(epid.serial));
|
||||
PyTuple_SetItem(pobj, 2, PyInt_FromLong(epid.creation));
|
||||
return pobj;
|
||||
default:
|
||||
ei_skip_term(x->buff, &x->index);
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
|
||||
}
|
||||
|
||||
PyObject *pyerl_sr(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *node;
|
||||
char *reg;
|
||||
char *cnode;
|
||||
PyObject *pobj;
|
||||
ei_x_buff x;
|
||||
int fd;
|
||||
int close_fd = 0;
|
||||
erlang_msg em;
|
||||
int eversion;
|
||||
PyObject *res;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "ssO:erlang_simple_send", &node, ®, &pobj)) {
|
||||
if (!PyArg_ParseTuple(args, "OsO:erlang_sr", &node, ®, &pobj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd = ei_connect(pyerl_cnode, node);
|
||||
if (PyString_Check(node)) {
|
||||
cnode = PyString_AsString(node);
|
||||
fd = ei_connect(pyerl_cnode, cnode);
|
||||
close_fd = 1;
|
||||
}
|
||||
else if (PyInt_Check(node)) {
|
||||
fd = PyInt_AsLong(node);
|
||||
}
|
||||
else {
|
||||
return PyErr_Format(PyExc_ValueError, "invalid erlang node/descriptor");
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
return PyErr_Format(PyExc_ValueError, "Unable to connect to erlang node %s", node);
|
||||
return PyErr_Format(PyExc_ValueError, "Unable to connect to erlang node");
|
||||
}
|
||||
|
||||
ei_x_new_with_version(&x);
|
||||
|
||||
if (py_to_erl(pobj, &x) < 0) {
|
||||
ei_x_free(&x);
|
||||
if (close_fd) close(fd);
|
||||
return PyErr_Format(PyExc_ValueError, "Unsupported object in Python->Erlang translation");
|
||||
}
|
||||
|
||||
|
||||
ei_reg_send(pyerl_cnode, fd, reg, x.buff, x.index);
|
||||
|
||||
close(fd);
|
||||
|
||||
ei_x_free(&x);
|
||||
|
||||
ei_x_new(&x);
|
||||
|
||||
if (ei_xreceive_msg(fd, &em, &x) == ERL_MSG) {
|
||||
x.index = 0;
|
||||
ei_decode_version(x.buff, &x.index, &eversion);
|
||||
res = erl_to_py(&x);
|
||||
ei_x_free(&x);
|
||||
if (close_fd) close(fd);
|
||||
return res;
|
||||
}
|
||||
|
||||
ei_x_free(&x);
|
||||
if (close_fd) close(fd);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *pyerl_rpc(PyObject * self, PyObject * args) {
|
||||
|
||||
PyObject *node;
|
||||
char *mod, *fun;
|
||||
char *cnode;
|
||||
PyObject *pobj;
|
||||
ei_x_buff x;
|
||||
ei_x_buff xr;
|
||||
int fd;
|
||||
int close_fd = 0;
|
||||
int eversion;
|
||||
PyObject *res;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "OssO:erlang_rpc", &node, &mod, &fun, &pobj)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyString_Check(node)) {
|
||||
cnode = PyString_AsString(node);
|
||||
fd = ei_connect(pyerl_cnode, cnode);
|
||||
close_fd = 1;
|
||||
}
|
||||
else if (PyInt_Check(node)) {
|
||||
fd = PyInt_AsLong(node);
|
||||
}
|
||||
else {
|
||||
return PyErr_Format(PyExc_ValueError, "Invalid erlang node/descriptor");
|
||||
}
|
||||
|
||||
if (fd < 0) {
|
||||
return PyErr_Format(PyExc_ValueError, "Unable to connect to erlang node");
|
||||
}
|
||||
|
||||
ei_x_new(&x);
|
||||
|
||||
if (py_to_erl(pobj, &x) < 0) {
|
||||
ei_x_free(&x);
|
||||
if (close_fd) close(fd);
|
||||
return PyErr_Format(PyExc_ValueError, "Unsupported object in Python->Erlang translation");
|
||||
}
|
||||
|
||||
|
||||
ei_x_new(&xr);
|
||||
if (ei_rpc(pyerl_cnode, fd, mod, fun, x.buff, x.index, &xr) < 0) {
|
||||
if (close_fd) close(fd);
|
||||
ei_x_free(&x);
|
||||
ei_x_free(&xr);
|
||||
return PyErr_Format(PyExc_ValueError, "Error in Erlang rpc");
|
||||
}
|
||||
|
||||
xr.index = 0;
|
||||
ei_decode_version(xr.buff, &xr.index, &eversion);
|
||||
|
||||
res = erl_to_py(&xr);
|
||||
|
||||
if (close_fd) close(fd);
|
||||
ei_x_free(&x);
|
||||
ei_x_free(&xr);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
static PyMethodDef uwsgi_pyerl_methods[] = {
|
||||
{"erlang_connect", pyerl_connect, METH_VARARGS, ""},
|
||||
{"erlang_simple_send", pyerl_simple_send, METH_VARARGS, ""},
|
||||
//{"erlang_send_message", pyerl_send, METH_VARARGS, ""},
|
||||
//{"erlang_recv_message", pyerl_recv, METH_VARARGS, ""},
|
||||
{"erlang_sr", pyerl_sr, METH_VARARGS, ""},
|
||||
{"erlang_rpc", pyerl_rpc, METH_VARARGS, ""},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
@@ -62,6 +240,8 @@ void py_erl_init_functions() {
|
||||
|
||||
PyMethodDef *uwsgi_function;
|
||||
|
||||
PyDict_SetItemString(up.embedded_dict, "erlang_node", PyString_FromString(ei_thisnodename(pyerl_cnode)));
|
||||
|
||||
for (uwsgi_function = uwsgi_pyerl_methods; uwsgi_function->ml_name != NULL; uwsgi_function++) {
|
||||
PyObject *func = PyCFunction_New(uwsgi_function, NULL);
|
||||
PyDict_SetItemString(up.embedded_dict, uwsgi_function->ml_name, func);
|
||||
@@ -80,6 +260,9 @@ int py_to_erl(PyObject *pobj, ei_x_buff *x) {
|
||||
else if (PyString_Check(pobj)) {
|
||||
ei_x_encode_string(x, PyString_AsString(pobj));
|
||||
}
|
||||
else if (PyUnicode_Check(pobj)) {
|
||||
ei_x_encode_atom(x, PyString_AsString(pobj));
|
||||
}
|
||||
else if (PyInt_Check(pobj)) {
|
||||
ei_x_encode_long(x, PyInt_AsLong(pobj));
|
||||
}
|
||||
|
||||
@@ -83,14 +83,21 @@ void *uwsgi_request_subhandler_wsgi(struct wsgi_request *wsgi_req, struct uwsgi_
|
||||
PyDict_SetItemString(up.embedded_dict, "env", wsgi_req->async_environ);
|
||||
}
|
||||
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", PyString_FromString(UWSGI_VERSION));
|
||||
zero = PyString_FromString(UWSGI_VERSION);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.version", zero);
|
||||
Py_DECREF(zero);
|
||||
|
||||
if (uwsgi.cores > 1) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.core", PyInt_FromLong(wsgi_req->async_id));
|
||||
}
|
||||
|
||||
if (uwsgi.cluster_fd >= 0) {
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", PyString_FromString(uwsgi.cluster));
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", PyString_FromString(uwsgi.hostname));
|
||||
zero = PyString_FromString(uwsgi.cluster);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster", zero);
|
||||
Py_DECREF(zero);
|
||||
zero = PyString_FromString(uwsgi.hostname);
|
||||
PyDict_SetItemString(wsgi_req->async_environ, "uwsgi.cluster_node", zero);
|
||||
Py_DECREF(zero);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1256,6 +1256,17 @@ char *uwsgi_cheap_string(char *buf, int len) {
|
||||
return buf-1;
|
||||
}
|
||||
|
||||
char *uwsgi_resolve_ip(char *domain) {
|
||||
|
||||
struct hostent *he;
|
||||
|
||||
he = gethostbyname(domain);
|
||||
if (!he || !*he->h_addr_list || he->h_addrtype != AF_INET) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return inet_ntoa( *( struct in_addr*) he->h_addr_list[0]);
|
||||
}
|
||||
|
||||
char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[]) {
|
||||
|
||||
@@ -1267,7 +1278,6 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
char *uri, *colon;
|
||||
char *domain ;
|
||||
char *ip ;
|
||||
struct hostent *he;
|
||||
int body = 0;
|
||||
char *magic_buf;
|
||||
|
||||
@@ -1289,13 +1299,7 @@ char *uwsgi_open_and_read(char *url, int *size, int add_zero, char *magic_table[
|
||||
}
|
||||
|
||||
|
||||
he = gethostbyname(domain);
|
||||
if (!he || !*he->h_addr_list || he->h_addrtype != AF_INET) {
|
||||
uwsgi_log("unable to resolve address %s\n", domain);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ip = inet_ntoa( *( struct in_addr*) he->h_addr_list[0]);
|
||||
ip = uwsgi_resolve_ip(domain);
|
||||
if (!ip) {
|
||||
uwsgi_log("unable to resolve address %s\n", domain);
|
||||
exit(1);
|
||||
|
||||
Reference in New Issue
Block a user