# HG changeset patch # User Olaf Wintermann # Date 1651920859 -7200 # Node ID a55491f6600352ef360793a888dd0c9ecbaaf900 # Parent bb536d4bc174f1ba0ee3a37612eddb4a3fca83ce fix and simplify chunked transfer encoding diff -r bb536d4bc174 -r a55491f66003 src/server/util/io.c --- a/src/server/util/io.c Fri May 06 22:45:53 2022 +0200 +++ b/src/server/util/io.c Sat May 07 12:54:19 2022 +0200 @@ -361,7 +361,11 @@ static ssize_t net_http_read_buffered(HttpStream *st, char *buf, size_t nbytes, WSBool read_data, WSBool *perform_io) { ssize_t r = 0; + //memset(buf, 'x', nbytes); + //char *orig_buf = buf; + // remaining bytes from the chunkbuf + /* if(st->remaining_len > 0) { size_t cplen = st->remaining_len > nbytes ? nbytes : st->remaining_len; WSBool ret = FALSE; @@ -388,6 +392,7 @@ return r; } } + */ // copy available data from st->readbuf to buf int pos = *st->bufpos; @@ -408,7 +413,10 @@ nbytes -= cplen; } - if(*perform_io && nbytes > 0) { + if(*perform_io && ((read_data && nbytes > 0 && st->max_read - st->read) || (!read_data && r == 0))) { + if(st->buflen - *st->bufpos > 0) { + printf("todo: fix, should not happen, remove later\n"); + } // fill buffer again ssize_t rlen = st->fd->read(st->fd, st->readbuf, st->bufsize); st->buflen = rlen; @@ -564,12 +572,13 @@ st->read = 0; st->remaining_len = chunkbuf_len - ret; if(st->remaining_len > 0) { - memcpy(st->remaining_buf, st->chunk_buf, HTTP_STREAM_CBUF_SIZE); - st->remaining_pos = st->chunk_buf_pos + ret; + //memcpy(st->remaining_buf, st->chunk_buf, HTTP_STREAM_CBUF_SIZE); + *st->bufpos -= st->remaining_len; + //st->remaining_pos = ret; } else { st->remaining_pos = 0; } - st->remaining_len = chunkbuf_len - ret; + //st->remaining_len = chunkbuf_len - ret; st->chunk_buf_pos = 0; if(chunklen == 0) { diff -r bb536d4bc174 -r a55491f66003 src/server/util/io.h --- a/src/server/util/io.h Fri May 06 22:45:53 2022 +0200 +++ b/src/server/util/io.h Sat May 07 12:54:19 2022 +0200 @@ -93,17 +93,55 @@ struct HttpStream { IOStream st; IOStream *fd; + + /* + * content-length or current chunk size + */ uint64_t max_read; + /* + * total bytes read (with content-length) or bytes read of current chunk + */ uint64_t read; + /* + * total bytes read with chunked transfer encoding + */ uint64_t read_total; + /* + * read buffer (used only with chunked transfer encoding) + */ char *readbuf; + /* + * readbuf size + */ size_t bufsize; // allocated buffer size + /* + * number of bytes currently stored in readbuf + */ size_t buflen; // currently number of bytes in the buffer + /* + * current position in the read buffer + */ int *bufpos; // current buffer position + /* + * current chunk_buf position + */ int chunk_buf_pos; + /* + * buffer used only for parsing chunk headers + */ char chunk_buf[HTTP_STREAM_CBUF_SIZE]; + /* + * after the chunk header is parsed, the content of chunk_buf + * will be moved to remaining_buf + */ char remaining_buf[HTTP_STREAM_CBUF_SIZE]; + /* + * number of bytes currently stored in remaining_buf + */ int remaining_len; + /* + * + */ int remaining_pos; WSBool chunked_enc; WSBool read_eof;