diff options
author | Adam Chlipala <adam@chlipala.net> | 2011-08-28 17:16:54 -0400 |
---|---|---|
committer | Adam Chlipala <adam@chlipala.net> | 2011-08-28 17:16:54 -0400 |
commit | ca0e7da014bf885d5f2acc887667368475f55520 (patch) | |
tree | 57bb51d132b4f81840f3ec44eba22addcf822f52 | |
parent | d91328bc0c51c399b2a6926ba04cead7bccc67da (diff) |
Gentle handling of back-button returns to pages with stale message-passing credentials
-rw-r--r-- | lib/js/urweb.js | 10 | ||||
-rw-r--r-- | src/c/urweb.c | 16 | ||||
-rw-r--r-- | tests/goback.ur | 20 | ||||
-rw-r--r-- | tests/goback.urp | 6 | ||||
-rw-r--r-- | tests/goback.urs | 1 |
5 files changed, 49 insertions, 4 deletions
diff --git a/lib/js/urweb.js b/lib/js/urweb.js index f0d9b693..42660bf0 100644 --- a/lib/js/urweb.js +++ b/lib/js/urweb.js @@ -736,6 +736,7 @@ var client_id = null; var client_pass = 0; var url_prefix = "/"; var timeout = 60; +var isPost = false; function getXHR(uri) { @@ -909,6 +910,15 @@ function listener() { return; var lines = text.split("\n"); + if (lines.length == 1 && lines[0] == "R") { + if (isPost) + history.back(); + else + location.reload(); + + return; + } + if (lines.length < 2) { discon(); return; diff --git a/src/c/urweb.c b/src/c/urweb.c index 5dc2ce5b..2a593767 100644 --- a/src/c/urweb.c +++ b/src/c/urweb.c @@ -247,6 +247,13 @@ void uw_set_on_success(char *s) { on_success = s; } +static void chastise(int (*send)(int sockfd, const void *buf, ssize_t len), int sock) { + send(sock, on_success, strlen(on_success)); + send(sock, begin_msgs, sizeof(begin_msgs) - 1); + send(sock, "R", 1); + close(sock); +} + void uw_client_connect(unsigned id, int pass, int sock, int (*send)(int sockfd, const void *buf, ssize_t len), int (*close)(int fd), @@ -254,7 +261,7 @@ void uw_client_connect(unsigned id, int pass, int sock, client *c = find_client(id); if (c == NULL) { - close(sock); + chastise(send, sock); log_error(logger_data, "Out-of-bounds client request (%u)\n", id); return; } @@ -263,14 +270,14 @@ void uw_client_connect(unsigned id, int pass, int sock, if (c->mode != USED) { pthread_mutex_unlock(&c->lock); - close(sock); + chastise(send, sock); log_error(logger_data, "Client request for unused slot (%u)\n", id); return; } if (pass != c->pass) { pthread_mutex_unlock(&c->lock); - close(sock); + chastise(send, sock); log_error(logger_data, "Wrong client password (%u, %d)\n", id, pass); return; } @@ -1342,7 +1349,8 @@ const char *uw_Basis_get_settings(uw_context ctx, uw_unit u) { char *sig = ctx->needs_sig ? ctx->app->cookie_sig(ctx) : ""; char *r = uw_malloc(ctx, 59 + 3 * INTS_MAX + strlen(ctx->app->url_prefix) + (ctx->needs_sig ? strlen(sig) + 7 : 0)); - sprintf(r, "client_id=%u;client_pass=%d;url_prefix=\"%s\";timeout=%d;%s%s%slistener();", + sprintf(r, "isPost=%s;client_id=%u;client_pass=%d;url_prefix=\"%s\";timeout=%d;%s%s%slistener();", + (ctx->isPost ? "true" : "false"), ctx->client->id, ctx->client->pass, ctx->app->url_prefix, diff --git a/tests/goback.ur b/tests/goback.ur new file mode 100644 index 00000000..ef61a817 --- /dev/null +++ b/tests/goback.ur @@ -0,0 +1,20 @@ +table channels : { Channel : channel {} } + +fun get () = + ch <- channel; + dml (INSERT INTO channels (Channel) VALUES ({[ch]})); + return <xml><body onload={recv ch}> + Hi. + </body></xml> + +fun post () = + ch <- channel; + dml (INSERT INTO channels (Channel) VALUES ({[ch]})); + return <xml><body onload={recv ch}> + Hi! + </body></xml> + +fun main () = return <xml><body> + <li><a link={get ()}>Get</a></li> + <li><form><submit action={post}/></form></li> +</body></xml> diff --git a/tests/goback.urp b/tests/goback.urp new file mode 100644 index 00000000..8db1b3a6 --- /dev/null +++ b/tests/goback.urp @@ -0,0 +1,6 @@ +database dbname=goback +sql goback.sql +rewrite all Goback/* +safeGet get + +goback diff --git a/tests/goback.urs b/tests/goback.urs new file mode 100644 index 00000000..901d6bf2 --- /dev/null +++ b/tests/goback.urs @@ -0,0 +1 @@ +val main : {} -> transaction page |