comparison src/c/urweb.c @ 1451:b6ce8ef0ea88

Before allowing an indirect return, check (dynamically, for now) that we aren't in an RPC handler
author Adam Chlipala <adam@chlipala.net>
date Sun, 17 Apr 2011 13:43:00 -0400
parents 0982f0242776
children aa2398e58306
comparison
equal deleted inserted replaced
1450:d40104c112df 1451:b6ce8ef0ea88
412 412
413 char *(*get_header)(void *, const char *); 413 char *(*get_header)(void *, const char *);
414 void *get_header_data; 414 void *get_header_data;
415 415
416 uw_buffer outHeaders, page, heap, script; 416 uw_buffer outHeaders, page, heap, script;
417 int returning_indirectly; 417 int allowed_to_return_indirectly, returning_indirectly;
418 input *inputs, *subinputs, *cur_container; 418 input *inputs, *subinputs, *cur_container;
419 size_t sz_inputs, n_subinputs, used_subinputs; 419 size_t sz_inputs, n_subinputs, used_subinputs;
420 420
421 unsigned long long source_count; 421 unsigned long long source_count;
422 422
475 475
476 uw_buffer_init(uw_headers_max, &ctx->outHeaders, 1); 476 uw_buffer_init(uw_headers_max, &ctx->outHeaders, 1);
477 ctx->outHeaders.start[0] = 0; 477 ctx->outHeaders.start[0] = 0;
478 uw_buffer_init(uw_page_max, &ctx->page, 1); 478 uw_buffer_init(uw_page_max, &ctx->page, 1);
479 ctx->page.start[0] = 0; 479 ctx->page.start[0] = 0;
480 ctx->returning_indirectly = 0; 480 ctx->allowed_to_return_indirectly = ctx->returning_indirectly = 0;
481 uw_buffer_init(uw_heap_max, &ctx->heap, uw_min_heap); 481 uw_buffer_init(uw_heap_max, &ctx->heap, uw_min_heap);
482 uw_buffer_init(uw_script_max, &ctx->script, 1); 482 uw_buffer_init(uw_script_max, &ctx->script, 1);
483 ctx->script.start[0] = 0; 483 ctx->script.start[0] = 0;
484 484
485 ctx->inputs = malloc(0); 485 ctx->inputs = malloc(0);
589 void uw_reset_keep_error_message(uw_context ctx) { 589 void uw_reset_keep_error_message(uw_context ctx) {
590 uw_buffer_reset(&ctx->outHeaders); 590 uw_buffer_reset(&ctx->outHeaders);
591 uw_buffer_reset(&ctx->script); 591 uw_buffer_reset(&ctx->script);
592 ctx->script.start[0] = 0; 592 ctx->script.start[0] = 0;
593 uw_buffer_reset(&ctx->page); 593 uw_buffer_reset(&ctx->page);
594 ctx->returning_indirectly = 0; 594 ctx->allowed_to_return_indirectly = ctx->returning_indirectly = 0;
595 uw_buffer_reset(&ctx->heap); 595 uw_buffer_reset(&ctx->heap);
596 ctx->regions = NULL; 596 ctx->regions = NULL;
597 ctx->cleanup_front = ctx->cleanup; 597 ctx->cleanup_front = ctx->cleanup;
598 ctx->used_deltas = 0; 598 ctx->used_deltas = 0;
599 ctx->client = NULL; 599 ctx->client = NULL;
3416 3416
3417 __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) { 3417 __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) {
3418 cleanup *cl; 3418 cleanup *cl;
3419 int len; 3419 int len;
3420 3420
3421 if (!ctx->allowed_to_return_indirectly)
3422 uw_error(ctx, FATAL, "Tried to return a blob from an RPC");
3423
3421 ctx->returning_indirectly = 1; 3424 ctx->returning_indirectly = 1;
3422 uw_buffer_reset(&ctx->outHeaders); 3425 uw_buffer_reset(&ctx->outHeaders);
3423 uw_buffer_reset(&ctx->page); 3426 uw_buffer_reset(&ctx->page);
3424 3427
3425 uw_write_header(ctx, on_success); 3428 uw_write_header(ctx, on_success);
3442 } 3445 }
3443 3446
3444 __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) { 3447 __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) {
3445 cleanup *cl; 3448 cleanup *cl;
3446 char *s; 3449 char *s;
3450
3451 if (!ctx->allowed_to_return_indirectly)
3452 uw_error(ctx, FATAL, "Tried to redirect from an RPC");
3447 3453
3448 ctx->returning_indirectly = 1; 3454 ctx->returning_indirectly = 1;
3449 uw_buffer_reset(&ctx->page); 3455 uw_buffer_reset(&ctx->page);
3450 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1); 3456 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1);
3451 memcpy(ctx->page.start, ctx->outHeaders.start, uw_buffer_used(&ctx->outHeaders)); 3457 memcpy(ctx->page.start, ctx->outHeaders.start, uw_buffer_used(&ctx->outHeaders));
3790 3796
3791 return r; 3797 return r;
3792 } else 3798 } else
3793 uw_error(ctx, FATAL, "Tried to run nonexistent onError handler"); 3799 uw_error(ctx, FATAL, "Tried to run nonexistent onError handler");
3794 } 3800 }
3801
3802 void uw_mayReturnIndirectly(uw_context ctx) {
3803 ctx->allowed_to_return_indirectly = 1;
3804 }