Mercurial > urweb
comparison src/c/urweb.c @ 1877:22b44fe822bf
Take proper account of signatures changing during page generation
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Thu, 10 Oct 2013 14:48:43 -0400 |
parents | 216a3a67ebe3 |
children | 0354df1b6849 |
comparison
equal
deleted
inserted
replaced
1876:fdafa3f92e40 | 1877:22b44fe822bf |
---|---|
469 unsigned nextId; | 469 unsigned nextId; |
470 | 470 |
471 int amInitializing; | 471 int amInitializing; |
472 | 472 |
473 char error_message[ERROR_BUF_LEN]; | 473 char error_message[ERROR_BUF_LEN]; |
474 | |
475 int usedSig, needsResig; | |
474 }; | 476 }; |
475 | 477 |
476 size_t uw_headers_max = SIZE_MAX; | 478 size_t uw_headers_max = SIZE_MAX; |
477 size_t uw_page_max = SIZE_MAX; | 479 size_t uw_page_max = SIZE_MAX; |
478 size_t uw_heap_max = SIZE_MAX; | 480 size_t uw_heap_max = SIZE_MAX; |
543 ctx->queryString = NULL; | 545 ctx->queryString = NULL; |
544 | 546 |
545 ctx->nextId = 0; | 547 ctx->nextId = 0; |
546 | 548 |
547 ctx->amInitializing = 0; | 549 ctx->amInitializing = 0; |
550 | |
551 ctx->usedSig = 0; | |
552 ctx->needsResig = 0; | |
548 | 553 |
549 return ctx; | 554 return ctx; |
550 } | 555 } |
551 | 556 |
552 size_t uw_inputs_max = SIZE_MAX; | 557 size_t uw_inputs_max = SIZE_MAX; |
622 ctx->used_transactionals = 0; | 627 ctx->used_transactionals = 0; |
623 ctx->script_header = ""; | 628 ctx->script_header = ""; |
624 ctx->queryString = NULL; | 629 ctx->queryString = NULL; |
625 ctx->nextId = 0; | 630 ctx->nextId = 0; |
626 ctx->amInitializing = 0; | 631 ctx->amInitializing = 0; |
632 ctx->usedSig = 0; | |
633 ctx->needsResig = 0; | |
627 } | 634 } |
628 | 635 |
629 void uw_reset_keep_request(uw_context ctx) { | 636 void uw_reset_keep_request(uw_context ctx) { |
630 uw_reset_keep_error_message(ctx); | 637 uw_reset_keep_error_message(ctx); |
631 ctx->error_message[0] = 0; | 638 ctx->error_message[0] = 0; |
3081 } | 3088 } |
3082 | 3089 |
3083 return NULL; | 3090 return NULL; |
3084 } | 3091 } |
3085 | 3092 |
3093 static void set_cookie(uw_context ctx) { | |
3094 if (ctx->usedSig) | |
3095 ctx->needsResig = 1; | |
3096 } | |
3097 | |
3086 uw_unit uw_Basis_set_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c, uw_Basis_string v, uw_Basis_time *expires, uw_Basis_bool secure) { | 3098 uw_unit uw_Basis_set_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c, uw_Basis_string v, uw_Basis_time *expires, uw_Basis_bool secure) { |
3087 uw_write_header(ctx, "Set-Cookie: "); | 3099 uw_write_header(ctx, "Set-Cookie: "); |
3088 uw_write_header(ctx, c); | 3100 uw_write_header(ctx, c); |
3089 uw_write_header(ctx, "="); | 3101 uw_write_header(ctx, "="); |
3090 uw_write_header(ctx, v); | 3102 uw_write_header(ctx, v); |
3103 uw_write_header(ctx, formatted); | 3115 uw_write_header(ctx, formatted); |
3104 } | 3116 } |
3105 if (secure) | 3117 if (secure) |
3106 uw_write_header(ctx, "; secure"); | 3118 uw_write_header(ctx, "; secure"); |
3107 uw_write_header(ctx, "\r\n"); | 3119 uw_write_header(ctx, "\r\n"); |
3120 set_cookie(ctx); | |
3108 | 3121 |
3109 return uw_unit_v; | 3122 return uw_unit_v; |
3110 } | 3123 } |
3111 | 3124 |
3112 uw_unit uw_Basis_clear_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c) { | 3125 uw_unit uw_Basis_clear_cookie(uw_context ctx, uw_Basis_string prefix, uw_Basis_string c) { |
3113 uw_write_header(ctx, "Set-Cookie: "); | 3126 uw_write_header(ctx, "Set-Cookie: "); |
3114 uw_write_header(ctx, c); | 3127 uw_write_header(ctx, c); |
3115 uw_write_header(ctx, "=; path="); | 3128 uw_write_header(ctx, "=; path="); |
3116 uw_write_header(ctx, prefix); | 3129 uw_write_header(ctx, prefix); |
3117 uw_write_header(ctx, "; " THE_PAST "\r\n"); | 3130 uw_write_header(ctx, "; " THE_PAST "\r\n"); |
3131 set_cookie(ctx); | |
3118 | 3132 |
3119 return uw_unit_v; | 3133 return uw_unit_v; |
3120 } | 3134 } |
3121 | 3135 |
3122 size_t uw_deltas_max = SIZE_MAX; | 3136 size_t uw_deltas_max = SIZE_MAX; |
3190 return ctx->app ? ctx->app->db_rollback(ctx) : 0; | 3204 return ctx->app ? ctx->app->db_rollback(ctx) : 0; |
3191 } | 3205 } |
3192 | 3206 |
3193 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; | 3207 static const char begin_xhtml[] = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">"; |
3194 | 3208 |
3209 extern int uw_hash_blocksize; | |
3210 | |
3211 static const char sig_intro[] = "<input type=\"hidden\" name=\"Sig\" value=\""; | |
3212 | |
3213 static char *find_sig(char *haystack) { | |
3214 int i; | |
3215 char *s = strstr(haystack, sig_intro); | |
3216 | |
3217 if (!s || strlen(haystack) - (s - haystack) - (sizeof sig_intro - 1) < uw_hash_blocksize*2+1) | |
3218 return NULL; | |
3219 | |
3220 s += sizeof sig_intro - 1; | |
3221 | |
3222 for (i = 0; i < uw_hash_blocksize*2; ++i) | |
3223 if (!isxdigit((int)s[i])) | |
3224 return NULL; | |
3225 | |
3226 if (s[i] != '"') | |
3227 return NULL; | |
3228 | |
3229 return s; | |
3230 } | |
3231 | |
3195 void uw_commit(uw_context ctx) { | 3232 void uw_commit(uw_context ctx) { |
3196 int i; | 3233 int i; |
3234 char *sig; | |
3197 | 3235 |
3198 if (uw_has_error(ctx)) { | 3236 if (uw_has_error(ctx)) { |
3199 uw_rollback(ctx, 0); | 3237 uw_rollback(ctx, 0); |
3200 return; | 3238 return; |
3201 } | 3239 } |
3312 ctx->page.front += lenP; | 3350 ctx->page.front += lenP; |
3313 memcpy(start, "<head>", 6); | 3351 memcpy(start, "<head>", 6); |
3314 memcpy(start + 6, ctx->script_header, lenH); | 3352 memcpy(start + 6, ctx->script_header, lenH); |
3315 memcpy(start + 6 + lenH, "</head>", 7); | 3353 memcpy(start + 6 + lenH, "</head>", 7); |
3316 } | 3354 } |
3355 } | |
3356 } | |
3357 | |
3358 if (ctx->needsResig) { | |
3359 sig = find_sig(ctx->page.start); | |
3360 if (sig) { | |
3361 char *realsig = ctx->app->cookie_sig(ctx); | |
3362 | |
3363 do { | |
3364 memcpy(sig, realsig, 2*uw_hash_blocksize); | |
3365 sig = find_sig(sig); | |
3366 } while (sig); | |
3317 } | 3367 } |
3318 } | 3368 } |
3319 } | 3369 } |
3320 | 3370 |
3321 | 3371 |
3559 | 3609 |
3560 uw_Basis_string uw_unnull(uw_Basis_string s) { | 3610 uw_Basis_string uw_unnull(uw_Basis_string s) { |
3561 return s ? s : ""; | 3611 return s ? s : ""; |
3562 } | 3612 } |
3563 | 3613 |
3564 extern int uw_hash_blocksize; | |
3565 | |
3566 uw_Basis_string uw_Basis_makeSigString(uw_context ctx, uw_Basis_string sig) { | 3614 uw_Basis_string uw_Basis_makeSigString(uw_context ctx, uw_Basis_string sig) { |
3567 uw_Basis_string r = uw_malloc(ctx, 2 * uw_hash_blocksize + 1); | 3615 uw_Basis_string r = uw_malloc(ctx, 2 * uw_hash_blocksize + 1); |
3568 int i; | 3616 int i; |
3569 | 3617 |
3570 for (i = 0; i < uw_hash_blocksize; ++i) | 3618 for (i = 0; i < uw_hash_blocksize; ++i) |
3589 | 3637 |
3590 return x == 0; | 3638 return x == 0; |
3591 } | 3639 } |
3592 | 3640 |
3593 uw_Basis_string uw_Basis_sigString(uw_context ctx, uw_unit u) { | 3641 uw_Basis_string uw_Basis_sigString(uw_context ctx, uw_unit u) { |
3642 ctx->usedSig = 1; | |
3594 return ctx->app->cookie_sig(ctx); | 3643 return ctx->app->cookie_sig(ctx); |
3595 } | 3644 } |
3596 | 3645 |
3597 uw_Basis_string uw_Basis_fileName(uw_context ctx, uw_Basis_file f) { | 3646 uw_Basis_string uw_Basis_fileName(uw_context ctx, uw_Basis_file f) { |
3598 return f.name; | 3647 return f.name; |