Mercurial > urweb
comparison src/c/urweb.c @ 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 | 8fce85939259 |
children | 3d0cc841cafd |
comparison
equal
deleted
inserted
replaced
1470:5018878ca645 | 1471:67ebd30a2283 |
---|---|
3486 | 3486 |
3487 uw_Basis_string uw_Basis_postData(uw_context ctx, uw_Basis_postBody pb) { | 3487 uw_Basis_string uw_Basis_postData(uw_context ctx, uw_Basis_postBody pb) { |
3488 return pb.data; | 3488 return pb.data; |
3489 } | 3489 } |
3490 | 3490 |
3491 static char *old_headers(uw_context ctx) { | |
3492 if (uw_buffer_used(&ctx->outHeaders) == 0) | |
3493 return NULL; | |
3494 else { | |
3495 char *s = strchr(ctx->outHeaders.start, '\n'); | |
3496 | |
3497 if (s == NULL || strncasecmp(s+1, "Content-type: ", 14)) | |
3498 return NULL; | |
3499 else { | |
3500 s = strchr(s+15, '\n'); | |
3501 if (s == NULL) | |
3502 return NULL; | |
3503 else | |
3504 return uw_strdup(ctx, s+1); | |
3505 } | |
3506 } | |
3507 } | |
3508 | |
3491 __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) { | 3509 __attribute__((noreturn)) void uw_return_blob(uw_context ctx, uw_Basis_blob b, uw_Basis_string mimeType) { |
3492 cleanup *cl; | 3510 cleanup *cl; |
3493 int len; | 3511 int len; |
3512 char *oldh; | |
3494 | 3513 |
3495 if (!ctx->allowed_to_return_indirectly) | 3514 if (!ctx->allowed_to_return_indirectly) |
3496 uw_error(ctx, FATAL, "Tried to return a blob from an RPC"); | 3515 uw_error(ctx, FATAL, "Tried to return a blob from an RPC"); |
3497 | 3516 |
3498 ctx->returning_indirectly = 1; | 3517 ctx->returning_indirectly = 1; |
3518 oldh = old_headers(ctx); | |
3499 uw_buffer_reset(&ctx->outHeaders); | 3519 uw_buffer_reset(&ctx->outHeaders); |
3500 uw_buffer_reset(&ctx->page); | 3520 uw_buffer_reset(&ctx->page); |
3501 | 3521 |
3502 uw_write_header(ctx, on_success); | 3522 uw_write_header(ctx, on_success); |
3503 uw_write_header(ctx, "Content-Type: "); | 3523 uw_write_header(ctx, "Content-Type: "); |
3505 uw_write_header(ctx, "\r\nContent-Length: "); | 3525 uw_write_header(ctx, "\r\nContent-Length: "); |
3506 ctx_uw_buffer_check(ctx, "headers", &ctx->outHeaders, INTS_MAX); | 3526 ctx_uw_buffer_check(ctx, "headers", &ctx->outHeaders, INTS_MAX); |
3507 sprintf(ctx->outHeaders.front, "%lu%n", (unsigned long)b.size, &len); | 3527 sprintf(ctx->outHeaders.front, "%lu%n", (unsigned long)b.size, &len); |
3508 ctx->outHeaders.front += len; | 3528 ctx->outHeaders.front += len; |
3509 uw_write_header(ctx, "\r\n"); | 3529 uw_write_header(ctx, "\r\n"); |
3530 if (oldh) uw_write_header(ctx, oldh); | |
3510 | 3531 |
3511 ctx_uw_buffer_append(ctx, "page", &ctx->page, b.data, b.size); | 3532 ctx_uw_buffer_append(ctx, "page", &ctx->page, b.data, b.size); |
3512 | 3533 |
3513 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) | 3534 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) |
3514 cl->func(cl->arg); | 3535 cl->func(cl->arg); |
3519 } | 3540 } |
3520 | 3541 |
3521 __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) { | 3542 __attribute__((noreturn)) void uw_redirect(uw_context ctx, uw_Basis_string url) { |
3522 cleanup *cl; | 3543 cleanup *cl; |
3523 char *s; | 3544 char *s; |
3545 char *oldh; | |
3524 | 3546 |
3525 if (!ctx->allowed_to_return_indirectly) | 3547 if (!ctx->allowed_to_return_indirectly) |
3526 uw_error(ctx, FATAL, "Tried to redirect from an RPC"); | 3548 uw_error(ctx, FATAL, "Tried to redirect from an RPC"); |
3527 | 3549 |
3528 ctx->returning_indirectly = 1; | 3550 ctx->returning_indirectly = 1; |
3551 oldh = old_headers(ctx); | |
3529 uw_buffer_reset(&ctx->page); | 3552 uw_buffer_reset(&ctx->page); |
3530 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1); | 3553 ctx_uw_buffer_check(ctx, "page", &ctx->page, uw_buffer_used(&ctx->outHeaders)+1); |
3531 memcpy(ctx->page.start, ctx->outHeaders.start, uw_buffer_used(&ctx->outHeaders)); | 3554 memcpy(ctx->page.start, ctx->outHeaders.start, uw_buffer_used(&ctx->outHeaders)); |
3532 ctx->page.start[uw_buffer_used(&ctx->outHeaders)] = 0; | 3555 ctx->page.start[uw_buffer_used(&ctx->outHeaders)] = 0; |
3533 uw_buffer_reset(&ctx->outHeaders); | 3556 uw_buffer_reset(&ctx->outHeaders); |
3550 } | 3573 } |
3551 | 3574 |
3552 uw_write_header(ctx, "Location: "); | 3575 uw_write_header(ctx, "Location: "); |
3553 uw_write_header(ctx, url); | 3576 uw_write_header(ctx, url); |
3554 uw_write_header(ctx, "\r\n\r\n"); | 3577 uw_write_header(ctx, "\r\n\r\n"); |
3578 if (oldh) uw_write_header(ctx, oldh); | |
3555 | 3579 |
3556 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) | 3580 for (cl = ctx->cleanup; cl < ctx->cleanup_front; ++cl) |
3557 cl->func(cl->arg); | 3581 cl->func(cl->arg); |
3558 | 3582 |
3559 ctx->cleanup_front = ctx->cleanup; | 3583 ctx->cleanup_front = ctx->cleanup; |