Mercurial > urweb
changeset 1942:a671e5258a2c
Raise exception when recv()ing from someone else's channel; improve setting of client ID in RPCs
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Fri, 27 Dec 2013 12:10:03 -0500 |
parents | 9f3597979e98 |
children | 3ecd0b6360eb |
files | lib/js/urweb.js src/c/urweb.c tests/channelThief.ur tests/channelThief.urp tests/channelThief.urs |
diffstat | 5 files changed, 64 insertions(+), 28 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/js/urweb.js Wed Dec 25 13:11:43 2013 -0500 +++ b/lib/js/urweb.js Fri Dec 27 12:10:03 2013 -0500 @@ -1575,7 +1575,7 @@ er("May not 'recv' in main thread of 'code' for <active>"); if (chn == null) - return; + er("Client-side code tried to recv() from a channel belonging to a different page view."); if (chn < 0) whine("Out-of-bounds channel receive");
--- a/src/c/urweb.c Wed Dec 25 13:11:43 2013 -0500 +++ b/src/c/urweb.c Fri Dec 27 12:10:03 2013 -0500 @@ -734,36 +734,34 @@ char *uw_Basis_htmlifyString(uw_context, const char *); void uw_login(uw_context ctx) { - if (ctx->needs_push) { - char *id_s, *pass_s; - - if ((id_s = uw_Basis_requestHeader(ctx, "UrWeb-Client")) - && (pass_s = uw_Basis_requestHeader(ctx, "UrWeb-Pass"))) { - unsigned id = atoi(id_s); - int pass = atoi(pass_s); - client *c = find_client(id); - - if (c == NULL) - uw_error(ctx, FATAL, "Unknown client ID in HTTP headers (%s, %s)", uw_Basis_htmlifyString(ctx, id_s), uw_Basis_htmlifyString(ctx, pass_s)); - else { - use_client(c); - ctx->client = c; - - if (c->mode != USED) - uw_error(ctx, FATAL, "Stale client ID (%u) in subscription request", id); - if (c->pass != pass) - uw_error(ctx, FATAL, "Wrong client password (%u, %d) in subscription request", id, pass); - } - } else { - client *c = new_client(); - - if (c == NULL) - uw_error(ctx, FATAL, "Limit exceeded on number of message-passing clients"); - + char *id_s, *pass_s; + + if ((id_s = uw_Basis_requestHeader(ctx, "UrWeb-Client")) + && (pass_s = uw_Basis_requestHeader(ctx, "UrWeb-Pass"))) { + unsigned id = atoi(id_s); + int pass = atoi(pass_s); + client *c = find_client(id); + + if (c == NULL) + uw_error(ctx, FATAL, "Unknown client ID in HTTP headers (%s, %s)", uw_Basis_htmlifyString(ctx, id_s), uw_Basis_htmlifyString(ctx, pass_s)); + else { use_client(c); - uw_copy_client_data(c->data, ctx->client_data); ctx->client = c; + + if (c->mode != USED) + uw_error(ctx, FATAL, "Stale client ID (%u) in subscription request", id); + if (c->pass != pass) + uw_error(ctx, FATAL, "Wrong client password (%u, %d) in subscription request", id, pass); } + } else if (ctx->needs_push) { + client *c = new_client(); + + if (c == NULL) + uw_error(ctx, FATAL, "Limit exceeded on number of message-passing clients"); + + use_client(c); + uw_copy_client_data(c->data, ctx->client_data); + ctx->client = c; } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/channelThief.ur Fri Dec 27 12:10:03 2013 -0500 @@ -0,0 +1,32 @@ +table t : { Ch : channel string } + +fun go () = + let + fun overwrite () = + dml (DELETE FROM t WHERE TRUE); + ch <- channel; + dml (INSERT INTO t (Ch) VALUES ({[ch]})); + return ch + + fun retrieve () = + oneRowE1 (SELECT (t.Ch) FROM t) + + fun transmit () = + ch <- retrieve (); + send ch "Test" + + fun listenOn ch = + s <- recv ch; + alert s + in + ch <- overwrite (); + return <xml><body onload={listenOn ch}> + <button value="overwrite" onclick={fn _ => ch <- rpc (overwrite ()); listenOn ch}/> + <button value="retrieve" onclick={fn _ => ch <- rpc (retrieve ()); listenOn ch}/> + <button value="transmit" onclick={fn _ => rpc (transmit ())}/> + </body></xml> + end + +fun main () = return <xml><body> + <form><submit action={go}/></form> +</body></xml>