summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adam@chlipala.net>2011-06-12 17:44:34 -0400
committerGravatar Adam Chlipala <adam@chlipala.net>2011-06-12 17:44:34 -0400
commitb9e6f864a787d648a69f0a2a3009608043d04ae7 (patch)
tree22daca90ac99da0244b2cc1d24bef4c472af85f4
parent3b35eef00de0ddd2fe05fb763fd6c62432e03c45 (diff)
Keep user-set response headers on indirect returns
-rw-r--r--src/c/urweb.c24
-rw-r--r--tests/blob.ur32
-rw-r--r--tests/blob.urp8
-rw-r--r--tests/blob.urs1
4 files changed, 34 insertions, 31 deletions
diff --git a/src/c/urweb.c b/src/c/urweb.c
index 865ce024..3213d044 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -3488,14 +3488,34 @@ uw_Basis_string uw_Basis_postData(uw_context ctx, uw_Basis_postBody pb) {
return pb.data;
}
+static char *old_headers(uw_context ctx) {
+ if (uw_buffer_used(&ctx->outHeaders) == 0)
+ return NULL;
+ else {
+ char *s = strchr(ctx->outHeaders.start, '\n');
+
+ if (s == NULL || strncasecmp(s+1, "Content-type: ", 14))
+ return NULL;
+ else {
+ s = strchr(s+15, '\n');
+ if (s == NULL)
+ return NULL;
+ else
+ return uw_strdup(ctx, s+1);
+ }
+ }
+}
+
__attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) {
cleanup *cl;
int len;
+ char *oldh;
if (!ctx->allowed_to_return_indirectly)
uw_error(ctx, FATAL, "Tried to return a blob from an RPC");
ctx->returning_indirectly = 1;
+ oldh = old_headers(ctx);
uw_buffer_reset(&ctx->outHeaders);
uw_buffer_reset(&ctx->page);
@@ -3507,6 +3527,7 @@ __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, u
sprintf(ctx->outHeaders.front, "%lu%n", (unsigned long)b.size, &len);
ctx->outHeaders.front += len;
uw_write_header(ctx, "\r\n");
+ if (oldh) uw_write_header(ctx, oldh);
ctx_uw_buffer_append(ctx, "page", &ctx->page, b.data, b.size);
@@ -3521,11 +3542,13 @@ __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, u
__attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) {
cleanup *cl;
char *s;
+ char *oldh;
if (!ctx->allowed_to_return_indirectly)
uw_error(ctx, FATAL, "Tried to redirect from an RPC");
ctx->returning_indirectly = 1;
+ oldh = old_headers(ctx);
uw_buffer_reset(&ctx->page);
ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1);
memcpy(ctx->page.start, ctx->outHeaders.start, uw_buffer_used(&ctx->outHeaders));
@@ -3552,6 +3575,7 @@ __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url)
uw_write_header(ctx, "Location: ");
uw_write_header(ctx, url);
uw_write_header(ctx, "\r\n\r\n");
+ if (oldh) uw_write_header(ctx, oldh);
for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl)
cl->func(cl->arg);
diff --git a/tests/blob.ur b/tests/blob.ur
index c6106686..02f88f0d 100644
--- a/tests/blob.ur
+++ b/tests/blob.ur
@@ -1,27 +1,7 @@
-sequence s
-table t : { Id : int, Nam : option string, Data : blob, Desc : string, Typ : string }
+fun main () =
+ setHeader (blessResponseHeader "X-Test") "Test";
+ return <xml><body>Test</body></xml>
-fun see id =
- r <- oneRow (SELECT t.Data, t.Typ FROM t WHERE t.Id = {[id]});
- returnBlob r.T.Data (blessMime r.T.Typ)
-
-fun save r =
- id <- nextval s;
- dml (INSERT INTO t (Id, Nam, Data, Desc, Typ)
- VALUES ({[id]}, {[fileName r.Data]}, {[fileData r.Data]}, {[r.Desc]}, {[fileMimeType r.Data]}));
- main ()
-
-and main () =
- ls <- queryX (SELECT t.Id, t.Desc, octet_length(t.Data) AS Len FROM t ORDER BY t.Desc)
- (fn r => <xml><li><a link={see r.T.Id}>{[r.T.Desc]} ({[r.Len]})</a></li></xml>);
- return <xml><body>
- {ls}
-
- <br/>
-
- <form>
- <textbox{#Desc}/>
- <upload{#Data}/>
- <submit action={save}/>
- </form>
- </body></xml>
+fun bad () =
+ setHeader (blessResponseHeader "X-Test") "Test";
+ returnBlob (textBlob "hello") (blessMime "text/plain")
diff --git a/tests/blob.urp b/tests/blob.urp
index 6e0de2ee..1cec504a 100644
--- a/tests/blob.urp
+++ b/tests/blob.urp
@@ -1,7 +1,5 @@
-debug
-database dbname=blobo
-sql blob.sql
-allow mime image/gif
-allow mime image/png
+allow responseHeader X-Test
+allow mime text/plain
+rewrite url Blob/*
blob
diff --git a/tests/blob.urs b/tests/blob.urs
index 6ac44e0b..fa45e01a 100644
--- a/tests/blob.urs
+++ b/tests/blob.urs
@@ -1 +1,2 @@
val main : unit -> transaction page
+val bad : unit -> transaction page