summaryrefslogtreecommitdiff
path: root/src/c
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2009-04-26 09:02:17 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2009-04-26 09:02:17 -0400
commit38507c697c6b5f277cabc5eb61afff14ea02da07 (patch)
tree0405c498a9fae8ff066ca8fdeafa8f85b0615dbe /src/c
parentd2274ae571370a5f0b88a6b0a5b264fde29378b9 (diff)
Returning a blob as page result
Diffstat (limited to 'src/c')
-rw-r--r--src/c/driver.c4
-rw-r--r--src/c/urweb.c38
2 files changed, 39 insertions, 3 deletions
diff --git a/src/c/driver.c b/src/c/driver.c
index c95f8886..63a7d224 100644
--- a/src/c/driver.c
+++ b/src/c/driver.c
@@ -194,7 +194,7 @@ static void *worker(void *data) {
if (s = strstr(buf, "\r\n\r\n")) {
failure_kind fk;
- int is_post = 0;
+ int is_post = 0, do_normal_send = 1;
char *boundary = NULL;
size_t boundary_len;
char *cmd, *path, *headers, path_copy[uw_bufsize+1], *inputs, *after_headers;
@@ -433,7 +433,7 @@ static void *worker(void *data) {
strcpy(path_copy, path);
fk = uw_begin(ctx, path_copy);
- if (fk == SUCCESS) {
+ if (fk == SUCCESS || fk == RETURN_BLOB) {
uw_commit(ctx);
break;
} else if (fk == BOUNDED_RETRY) {
diff --git a/src/c/urweb.c b/src/c/urweb.c
index ff4d5c8f..28364f2c 100644
--- a/src/c/urweb.c
+++ b/src/c/urweb.c
@@ -1,4 +1,4 @@
-#define _XOPEN_SOURCE
+#define _XOPEN_SOURCE 500
#include <stdlib.h>
#include <stdio.h>
@@ -8,6 +8,7 @@
#include <setjmp.h>
#include <stdarg.h>
#include <assert.h>
+#include <ctype.h>
#include <pthread.h>
@@ -2104,6 +2105,16 @@ uw_Basis_string uw_Basis_bless(uw_context ctx, uw_Basis_string s) {
return s;
}
+uw_Basis_string uw_Basis_blessMime(uw_context ctx, uw_Basis_string s) {
+ char *s2;
+
+ for (s2 = s; *s2; ++s2)
+ if (!isalnum(*s2) && *s2 != '/' && *s2 != '-' && *s2 != '.')
+ uw_error(ctx, FATAL, "MIME type \"%s\" contains invalid character %c\n", s, *s2);
+
+ return s;
+}
+
uw_Basis_string uw_unnull(uw_Basis_string s) {
return s ? s : "";
}
@@ -2135,3 +2146,28 @@ uw_Basis_string uw_Basis_fileMimeType(uw_context ctx, uw_Basis_file f) {
uw_Basis_blob uw_Basis_fileData(uw_context ctx, uw_Basis_file f) {
return f.data;
}
+
+__attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) {
+ cleanup *cl;
+ int len;
+
+ buf_reset(&ctx->outHeaders);
+ buf_reset(&ctx->page);
+
+ uw_write_header(ctx, "HTTP/1.1 200 OK\r\nContent-Type: ");
+ uw_write_header(ctx, mimeType);
+ uw_write_header(ctx, "\r\nContent-Length: ");
+ buf_check(&ctx->outHeaders, INTS_MAX);
+ sprintf(ctx->outHeaders.front, "%d%n", b.size, &len);
+ ctx->outHeaders.front += len;
+ uw_write_header(ctx, "\r\n");
+
+ buf_append(&ctx->page, b.data, b.size);
+
+ for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl)
+ cl->func(cl->arg);
+
+ ctx->cleanup_front = ctx->cleanup;
+
+ longjmp(ctx->jmp_buf, RETURN_BLOB);
+}