Browse Source

[multiple] code reuse chunkqueue_peek_data()

code reuse of chunkqueue_peek_data() and chunkqueue_read_data()
master
Glenn Strauss 1 year ago
parent
commit
660d719a2a
  1. 50
      src/mod_fastcgi.c
  2. 20
      src/mod_wstunnel.c
  3. 20
      src/response.c

50
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

20
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__

20
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);
}

Loading…
Cancel
Save