commit d48ffc6605b4a30e0e4356cf2d53383c2a223067 from: Omar Polo date: Thu Aug 31 14:57:45 2023 UTC amused-web: tweak bufio APIs for future HTTP usage add bufio_free() to free the bufio without re-initialization, add support for writing HTTP-style chunks and add ability to extract data from the read buffer via the bufio_* layer instead of peeking at the internals. commit - 1fcd7cb2373bf5bff5c010481d1f68c52104b141 commit + d48ffc6605b4a30e0e4356cf2d53383c2a223067 blob - 7cedaf5a03b59e15e93d21af7ec4eee35dfa6c23 blob + 2ac55ff421bd9138cb0ba175c1effde736316b60 --- web/bufio.c +++ web/bufio.c @@ -113,14 +113,20 @@ bufio_init(struct bufio *bio) return (0); } -int -bufio_reset(struct bufio *bio) +void +bufio_free(struct bufio *bio) { if (bio->fd != -1) close(bio->fd); buf_free(&bio->rbuf); buf_free(&bio->wbuf); +} + +int +bufio_reset(struct bufio *bio) +{ + bufio_free(bio); return (bufio_init(bio)); } @@ -130,6 +136,12 @@ bufio_set_fd(struct bufio *bio, int fd) bio->fd = fd; } +void +bufio_set_chunked(struct bufio *bio, int chunked) +{ + bio->chunked = chunked; +} + short bufio_pollev(struct bufio *bio) { @@ -161,6 +173,18 @@ bufio_read(struct bufio *bio) return (r); } +size_t +bufio_drain(struct bufio *bio, void *d, size_t len) +{ + struct buffer *rbuf = &bio->rbuf; + + if (len > rbuf->len) + len = rbuf->len; + memcpy(d, rbuf->buf, len); + buf_drain(rbuf, len); + return (len); +} + ssize_t bufio_write(struct bufio *bio) { @@ -174,11 +198,14 @@ bufio_write(struct bufio *bio) return (w); } -int -bufio_compose(struct bufio *bio, const void *d, size_t len) +static int +bufio_append(struct bufio *bio, const void *d, size_t len) { struct buffer *wbuf = &bio->wbuf; + if (len == 0) + return (0); + while (wbuf->cap - wbuf->len < len) { if (buf_grow(wbuf) == -1) return (-1); @@ -190,6 +217,29 @@ bufio_compose(struct bufio *bio, const void *d, size_t } int +bufio_compose(struct bufio *bio, const void *d, size_t len) +{ + char n[16]; + int r; + + if (bio->chunked) { + r = snprintf(n, sizeof(n), "%zx\r\n", len); + if (r < 0 || (size_t)r >= sizeof(n)) + return (-1); + if (bufio_append(bio, n, r) == -1) + return (-1); + } + + if (bufio_append(bio, d, len) == -1) + return (-1); + + if (bio->chunked) + return bufio_append(bio, "\r\n", 2); + + return (0); +} + +int bufio_compose_str(struct bufio *bio, const char *str) { return (bufio_compose(bio, str, strlen(str))); blob - 99c863ef377f7718706f618719de7d16bcd11557 blob + 823ac23e75511a2a22fa33bb96944c3ae2f5af79 --- web/bufio.h +++ web/bufio.h @@ -32,6 +32,7 @@ struct buffer { struct bufio { int fd; + int chunked; struct buffer wbuf; struct buffer rbuf; }; @@ -43,10 +44,13 @@ void buf_drain_line(struct buffer *, const char *); void buf_free(struct buffer *); int bufio_init(struct bufio *); +void bufio_free(struct bufio *); int bufio_reset(struct bufio *); void bufio_set_fd(struct bufio *, int); +void bufio_set_chunked(struct bufio *, int); short bufio_pollev(struct bufio *); ssize_t bufio_read(struct bufio *); +size_t bufio_drain(struct bufio *, void *, size_t); ssize_t bufio_write(struct bufio *); int bufio_compose(struct bufio *, const void *, size_t); int bufio_compose_str(struct bufio *, const char *);