From 660d719a2ae841106b8a3d7009eb8b06b869ae14 Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Wed, 23 Sep 2020 10:05:04 -0400 Subject: [PATCH] [multiple] code reuse chunkqueue_peek_data() code reuse of chunkqueue_peek_data() and chunkqueue_read_data() --- src/mod_fastcgi.c | 50 ++++++++++++++++------------------------------ src/mod_wstunnel.c | 20 ++++--------------- src/response.c | 20 ++++++++++--------- 3 files changed, 32 insertions(+), 58 deletions(-) diff --git a/src/mod_fastcgi.c b/src/mod_fastcgi.c index b4811045..5125f3a1 100644 --- a/src/mod_fastcgi.c +++ b/src/mod_fastcgi.c @@ -337,7 +337,6 @@ typedef struct { static int fastcgi_get_packet(handler_ctx *hctx, fastcgi_response_packet *packet) { FCGI_Header header; - size_t toread = sizeof(FCGI_Header), flen = 0; off_t rblen = chunkqueue_length(hctx->rb); if (rblen < (off_t)sizeof(FCGI_Header)) { /* no header */ @@ -348,23 +347,14 @@ static int fastcgi_get_packet(handler_ctx *hctx, fastcgi_response_packet *packet } return -1; } - #ifdef __clang_analyzer__ - /*(unnecessary (length checked above); init to quiet scan-build)*/ - memset(&header, 0, sizeof(FCGI_Header)); - #endif - - /* get at least the FastCGI header */ - for (chunk *c = hctx->rb->first; c; c = c->next) { - size_t weHave = buffer_string_length(c->mem) - c->offset; - if (weHave >= toread) { - memcpy((char *)&header + flen, c->mem->ptr + c->offset, toread); - break; - } - - memcpy((char *)&header + flen, c->mem->ptr + c->offset, weHave); - flen += weHave; - toread -= weHave; - } + char *ptr = (char *)&header; + uint32_t rd = sizeof(FCGI_Header); + if (chunkqueue_peek_data(hctx->rb, &ptr, &rd, hctx->r->conf.errh) < 0) + return -1; + if (rd != sizeof(FCGI_Header)) + return -1; + if (ptr != (char *)&header) /* copy into aligned struct */ + memcpy(&header, ptr, sizeof(FCGI_Header)); /* we have at least a header, now check how much we have to fetch */ packet->len = (header.contentLengthB0 | (header.contentLengthB1 << 8)) + header.paddingLength; @@ -380,21 +370,15 @@ static int fastcgi_get_packet(handler_ctx *hctx, fastcgi_response_packet *packet return 0; } -static void fastcgi_get_packet_body(buffer *b, handler_ctx *hctx, fastcgi_response_packet *packet) { - /* copy content; hctx->rb must contain at least packet->len content */ - size_t toread = packet->len - packet->padding; - buffer_string_prepare_append(b, toread); - for (chunk *c = hctx->rb->first; c; c = c->next) { - size_t weHave = buffer_string_length(c->mem) - c->offset; - if (weHave >= toread) { - buffer_append_string_len(b, c->mem->ptr + c->offset, toread); - break; - } - - buffer_append_string_len(b, c->mem->ptr + c->offset, weHave); - toread -= weHave; - } - chunkqueue_mark_written(hctx->rb, packet->len); +static void fastcgi_get_packet_body(buffer * const b, handler_ctx * const hctx, const fastcgi_response_packet * const packet) { + /* copy content; hctx->rb must contain at least packet->len content */ + /* (read entire packet and then truncate padding, if present) */ + const uint32_t blen = buffer_string_length(b); + if (chunkqueue_read_data(hctx->rb, + buffer_string_prepare_append(b, packet->len), + packet->len, hctx->r->conf.errh) < 0) + return; /*(should not happen; should all be in memory)*/ + buffer_string_set_length(b, blen + packet->len - packet->padding); } static int diff --git a/src/mod_wstunnel.c b/src/mod_wstunnel.c index 47f43b3a..07352818 100644 --- a/src/mod_wstunnel.c +++ b/src/mod_wstunnel.c @@ -653,26 +653,14 @@ int mod_wstunnel_plugin_init(plugin *p) { #include "sys-crypto-md.h" /* lighttpd */ #include "sys-endian.h" /* lighttpd */ -static int get_key3(request_st * const r, char *buf) { +static int get_key3(request_st * const r, char *buf, uint32_t bytes) { /* 8 bytes should have been sent with request * for draft-ietf-hybi-thewebsocketprotocol-00 */ chunkqueue *cq = r->reqbody_queue; - size_t bytes = 8; /*(caller should ensure bytes available prior to calling this routine)*/ /*assert(chunkqueue_length(cq) >= 8);*/ - for (chunk *c = cq->first; NULL != c; c = c->next) { - /*(chunk_remaining_length() on MEM_CHUNK)*/ - size_t n = (size_t)(buffer_string_length(c->mem) - c->offset); - /*(expecting 8 bytes to be in memory directly after headers)*/ - if (c->type != MEM_CHUNK) break; /* FILE_CHUNK not handled here */ - if (n > bytes) n = bytes; - memcpy(buf, c->mem->ptr+c->offset, n); - buf += n; - if (0 == (bytes -= n)) break; - } - if (0 != bytes) return -1; - chunkqueue_mark_written(cq, 8); - return 0; + /*assert(8 == bytes);*/ + return chunkqueue_read_data(cq, buf, bytes, r->conf.errh); } static int get_key_number(uint32_t *ret, const buffer *b) { @@ -707,7 +695,7 @@ static int create_MD5_sum(request_st * const r) { if (NULL == key1 || get_key_number(buf+0, key1) < 0 || NULL == key2 || get_key_number(buf+1, key2) < 0 || - get_key3(r, (char *)(buf+2)) < 0) { + get_key3(r, (char *)(buf+2), 2*sizeof(uint32_t)) < 0) { return -1; } #ifdef __BIG_ENDIAN__ diff --git a/src/response.c b/src/response.c index a3f15565..4379a38e 100644 --- a/src/response.c +++ b/src/response.c @@ -53,19 +53,21 @@ __attribute_cold__ static void http_response_write_header_partial_1xx (request_st * const r, buffer * const b) { + /* take data in con->write_queue and move into b + * (to be sent prior to final response headers in r->write_queue) */ connection * const con = r->con; /*assert(r->write_queue != con->write_queue);*/ chunkqueue * const cq = con->write_queue; - const uint32_t len = (uint32_t)chunkqueue_length(cq); - chunk *c = cq->first; - /*assert(c->type == MEM_CHUNK);*/ - if (c->next) { - chunkqueue_compact_mem(cq, len); - c = cq->first; /*(reload c after chunkqueue_compact_mem())*/ - } - buffer_copy_string_len(b, c->mem->ptr + c->offset, len); - chunkqueue_free(cq); con->write_queue = r->write_queue; + + /*assert(0 == buffer_string_length(b));*//*expect empty buffer from caller*/ + uint32_t len = (uint32_t)chunkqueue_length(cq); + /*(expecting MEM_CHUNK(s), so not expecting error reading files)*/ + if (chunkqueue_read_data(cq, buffer_string_prepare_append(b, len), + len, r->conf.errh) < 0) + len = 0; + buffer_string_set_length(b, len);/*expect initial empty buffer from caller*/ + chunkqueue_free(cq); }