summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adam@chlipala.net>2011-08-28 17:16:54 -0400
committerGravatar Adam Chlipala <adam@chlipala.net>2011-08-28 17:16:54 -0400
commit30959446b17bea49d07d2ded62f3fc5b978be330 (patch)
tree57bb51d132b4f81840f3ec44eba22addcf822f52
parenteb1f7abebc8b0d88be660550258d5fe1e8610621 (diff)
Gentle handling of back-button returns to pages with stale message-passing credentials
-rw-r--r--lib/js/urweb.js10
-rw-r--r--src/c/urweb.c16
-rw-r--r--tests/goback.ur20
-rw-r--r--tests/goback.urp6
-rw-r--r--tests/goback.urs1
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