diff options
-rw-r--r-- | src/c/urweb.c | 24 | ||||
-rw-r--r-- | tests/blob.ur | 32 | ||||
-rw-r--r-- | tests/blob.urp | 8 | ||||
-rw-r--r-- | tests/blob.urs | 1 |
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 |