Created
January 15, 2013 17:04
-
-
Save nwalker/4540148 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/plugins/erlang/erlang.c b/plugins/erlang/erlang.c | |
index 4ac45cc..a8d23b8 100644 | |
--- a/plugins/erlang/erlang.c | |
+++ b/plugins/erlang/erlang.c | |
@@ -84,6 +84,91 @@ void dump_eterm(ei_x_buff *x) { | |
21 | |
} | |
+int erl_to_rpc_args(ei_x_buff *x, int *argc, char **argv, uint16_t *argvs) { | |
+ int etype, esize; | |
+ int arity; | |
+ int i; | |
+ size_t rsize; | |
+ | |
+ long long lnum; | |
+ double fnum; | |
+ char *buf; | |
+ long bin_size; | |
+ | |
+ | |
+ ei_get_type(x->buff, &x->index, &etype, &esize); | |
+ | |
+ if (etype != ERL_STRING_EXT && etype != ERL_LIST_EXT && etype != ERL_NIL_EXT) | |
+ return 1; // Wrong argument type | |
+ if (esize>255) | |
+ return 2; // Too long parameter list | |
+ | |
+ // ERL_STRING_EXT here means "list of short integers". | |
+ // If it is really string - someone didn't read docs of rpc:call and should be punished | |
+ if(etype == ERL_STRING_EXT) { | |
+ buf = uwsgi_malloc(esize); | |
+ ei_decode_string(x->buff, &x->index, buf); | |
+ | |
+ for(i=0; i<esize+1; i++) { | |
+ argv[i] = uwsgi_malloc(4); // | |
+ argvs[i] = snprintf(argv[i], 4, "%i", buf[i]); | |
+ } | |
+ | |
+ *argc = esize; | |
+ free(buf); | |
+ return 0; | |
+ } | |
+ | |
+ ei_decode_list_header(x->buff, &x->index, &arity); | |
+ *argc = arity; | |
+ | |
+ for (i=0; i<arity; 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, &lnum); | |
+ rsize = snprintf(NULL, 0, "%lli", lnum); | |
+ argv[i] = uwsgi_malloc(rsize+1); | |
+ argvs[i] = rsize; | |
+ snprintf(argv[i], rsize+1, "%lli", lnum); | |
+ break; | |
+ case ERL_FLOAT_EXT: | |
+ ei_decode_double(x->buff, &x->index, &fnum); | |
+ rsize = snprintf(NULL, 0, "%f", fnum); // be careful of precision loss | |
+ argv[i] = uwsgi_malloc(rsize+1); | |
+ argvs[i] = rsize; | |
+ snprintf(argv[i], rsize+1, "%f", fnum); | |
+ break; | |
+ case ERL_ATOM_EXT: | |
+ argv[i] = uwsgi_malloc(esize)+1; | |
+ argvs[i] = esize; | |
+ ei_decode_atom(x->buff, &x->index, argv[i]); | |
+ break; | |
+ // TODO: string and binary size should be checked | |
+ case ERL_STRING_EXT: | |
+ argv[i] = uwsgi_malloc(esize)+1; | |
+ argvs[i] = esize; | |
+ ei_decode_string(x->buff, &x->index, argv[i]); | |
+ break; | |
+ case ERL_BINARY_EXT: | |
+ argv[i] = uwsgi_malloc(esize)+1; | |
+ ei_decode_binary(x->buff, &x->index, argv[i], &bin_size); | |
+ argvs[i] = bin_size; | |
+ break; | |
+ default: | |
+#ifdef UWSGI_DEBUG | |
+ uwsgi_log("unsupported Erlang RPC argument at %i\n", i); | |
+ dump_eterm(x); | |
+#endif | |
+ return 3; | |
+ } | |
+ } | |
+ return 0; | |
+} | |
+ | |
void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) { | |
int etype, esize; | |
@@ -98,6 +183,7 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) { | |
uint16_t argvs[256] ; | |
int argc = 0; | |
uint16_t ret; | |
+ int err; | |
ei_x_buff xr; | |
erlang_ref eref; | |
@@ -210,19 +296,10 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) { | |
uwsgi_log("RPC %s %s\n", module, call); | |
#endif | |
- ei_get_type(x->buff, &x->index, &etype, &esize); | |
- | |
- if (etype == ERL_ATOM_EXT) { | |
- argc = 1; | |
- argv[0] = uwsgi_malloc(esize+1); | |
- ei_decode_atom(x->buff, &x->index, argv[0]); | |
- argvs[1] = esize; | |
- } | |
- else if (etype == ERL_STRING_EXT) { | |
- argc = 1; | |
- argv[0] = uwsgi_malloc(esize+1); | |
- ei_decode_string(x->buff, &x->index, argv[0]); | |
- argvs[1] = esize; | |
+ err = erl_to_rpc_args(x, &argc, argv, argvs); | |
+ if(err) { | |
+ uwsgi_log("Malformed Erlang RPC request"); | |
+ return; | |
} | |
ret = uwsgi_rpc(call, argc, argv, argvs, buffer); | |
@@ -240,8 +317,6 @@ void uwsgi_erlang_rpc(int fd, erlang_pid *from, ei_x_buff *x) { | |
uwsgi_log("ei_send to %d %s %d %d %d: %d %d\n", fd, from->node, from->num , from->serial, from->creation, xr.index, ei_send(fd, from, xr.buff, xr.index)); | |
//uwsgi_log("ei_send to %d %s %d %d %d: %d %d\n", fd, from->node, from->num , from->serial, from->creation, xr.index, ei_reg_send(&uerl.cnode, fd, "rex", xr.buff, xr.index)); | |
- | |
- | |
} | |
void erlang_loop(int id, void *data) { | |
@@ -290,8 +365,9 @@ void erlang_loop(int id, void *data) { | |
if (em.msgtype == ERL_TICK) | |
continue; | |
+#ifdef UWSGI_DEBUG | |
uwsgi_log("[erlang] message From: %s To (process): %s\n", em.from.node, em.toname); | |
- | |
+#endif | |
x.index = 0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import uwsgi, atexit | |
def func(*args, **kwargs): | |
print('call: ', args, kwargs) | |
return "test" | |
uwsgi.register_rpc('hello', func) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(uwsgi_test). | |
-export([start/2, loop/3]). | |
start(Name, Fun) -> | |
Str = random_string(30*1024, "abcdefgh1234567890"), | |
spawn(uwsgi_test, loop, [Name, Fun, Str]). | |
loop(Name, Fun, Str) -> | |
rpc:call(Name, unused, Fun, [Str]), | |
loop(Name, Fun, Str). | |
random_string(Length, AllowedChars) -> | |
lists:foldl(fun(_, Acc) -> | |
[lists:nth(random:uniform(length(AllowedChars)), | |
AllowedChars)] | |
++ Acc | |
end, [], lists:seq(1, Length)). | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment