Mercurial > urweb
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 } |