Mercurial > urweb
comparison src/c/urweb.c @ 1949:d7bec4e63415
Do a bit of extra userspace copying to send HTTP response with a single system call
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Tue, 31 Dec 2013 09:34:41 -0500 |
parents | 3ecd0b6360eb |
children | ac1be85e91ad |
comparison
equal
deleted
inserted
replaced
1948:6b80900ddc66 | 1949:d7bec4e63415 |
---|---|
472 int amInitializing; | 472 int amInitializing; |
473 | 473 |
474 char error_message[ERROR_BUF_LEN]; | 474 char error_message[ERROR_BUF_LEN]; |
475 | 475 |
476 int usedSig, needsResig; | 476 int usedSig, needsResig; |
477 | |
478 char *output_buffer; | |
479 size_t output_buffer_size; | |
477 }; | 480 }; |
478 | 481 |
479 size_t uw_headers_max = SIZE_MAX; | 482 size_t uw_headers_max = SIZE_MAX; |
480 size_t uw_page_max = SIZE_MAX; | 483 size_t uw_page_max = SIZE_MAX; |
481 size_t uw_heap_max = SIZE_MAX; | 484 size_t uw_heap_max = SIZE_MAX; |
551 | 554 |
552 ctx->amInitializing = 0; | 555 ctx->amInitializing = 0; |
553 | 556 |
554 ctx->usedSig = 0; | 557 ctx->usedSig = 0; |
555 ctx->needsResig = 0; | 558 ctx->needsResig = 0; |
559 | |
560 ctx->output_buffer = malloc(1); | |
561 ctx->output_buffer_size = 1; | |
556 | 562 |
557 return ctx; | 563 return ctx; |
558 } | 564 } |
559 | 565 |
560 size_t uw_inputs_max = SIZE_MAX; | 566 size_t uw_inputs_max = SIZE_MAX; |
609 | 615 |
610 for (i = 0; i < ctx->n_globals; ++i) | 616 for (i = 0; i < ctx->n_globals; ++i) |
611 if (ctx->globals[i].free) | 617 if (ctx->globals[i].free) |
612 ctx->globals[i].free(ctx->globals[i].data); | 618 ctx->globals[i].free(ctx->globals[i].data); |
613 free(ctx->globals); | 619 free(ctx->globals); |
620 | |
621 free(ctx->output_buffer); | |
614 | 622 |
615 free(ctx); | 623 free(ctx); |
616 } | 624 } |
617 | 625 |
618 void uw_reset_keep_error_message(uw_context ctx) { | 626 void uw_reset_keep_error_message(uw_context ctx) { |
1295 int uw_pagelen(uw_context ctx) { | 1303 int uw_pagelen(uw_context ctx) { |
1296 return ctx->page.front - ctx->page.start; | 1304 return ctx->page.front - ctx->page.start; |
1297 } | 1305 } |
1298 | 1306 |
1299 int uw_send(uw_context ctx, int sock) { | 1307 int uw_send(uw_context ctx, int sock) { |
1300 int n = uw_really_send(sock, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); | 1308 size_t target_length = (ctx->outHeaders.front - ctx->outHeaders.start) + 2 + (ctx->page.front - ctx->page.start); |
1301 | 1309 |
1302 if (n < 0) | 1310 if (ctx->output_buffer_size < target_length) { |
1303 return n; | 1311 do { |
1304 | 1312 ctx->output_buffer_size *= 2; |
1305 n = uw_really_send(sock, "\r\n", 2); | 1313 } while (ctx->output_buffer_size < target_length); |
1306 | 1314 ctx->output_buffer = realloc(ctx->output_buffer, ctx->output_buffer_size); |
1307 if (n < 0) | 1315 } |
1308 return n; | 1316 |
1309 | 1317 memcpy(ctx->output_buffer, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); |
1310 return uw_really_send(sock, ctx->page.start, ctx->page.front - ctx->page.start); | 1318 memcpy(ctx->output_buffer + (ctx->outHeaders.front - ctx->outHeaders.start), "\r\n", 2); |
1319 memcpy(ctx->output_buffer + (ctx->outHeaders.front - ctx->outHeaders.start) + 2, ctx->page.start, ctx->page.front - ctx->page.start); | |
1320 | |
1321 return uw_really_send(sock, ctx->output_buffer, target_length); | |
1311 } | 1322 } |
1312 | 1323 |
1313 int uw_print(uw_context ctx, int fd) { | 1324 int uw_print(uw_context ctx, int fd) { |
1314 int n = uw_really_write(fd, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); | 1325 int n = uw_really_write(fd, ctx->outHeaders.start, ctx->outHeaders.front - ctx->outHeaders.start); |
1315 | 1326 |