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;