changeset 1471:67ebd30a2283

Keep user-set response headers on indirect returns
author Adam Chlipala <adam@chlipala.net>
date Sun, 12 Jun 2011 17:44:34 -0400
parents 5018878ca645
children 18d18a70821e
files src/c/urweb.c tests/blob.ur tests/blob.urp tests/blob.urs
diffstat 4 files changed, 34 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/src/c/urweb.c	Wed Jun 01 07:23:27 2011 -0400
+++ b/src/c/urweb.c	Sun Jun 12 17:44:34 2011 -0400
@@ -3488,14 +3488,34 @@
   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 @@
   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_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 @@
   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);
--- a/tests/blob.ur	Wed Jun 01 07:23:27 2011 -0400
+++ b/tests/blob.ur	Sun Jun 12 17:44:34 2011 -0400
@@ -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")
--- a/tests/blob.urp	Wed Jun 01 07:23:27 2011 -0400
+++ b/tests/blob.urp	Sun Jun 12 17:44:34 2011 -0400
@@ -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
--- a/tests/blob.urs	Wed Jun 01 07:23:27 2011 -0400
+++ b/tests/blob.urs	Sun Jun 12 17:44:34 2011 -0400
@@ -1,1 +1,2 @@
 val main : unit -> transaction page
+val bad : unit -> transaction page