Hi, this patch simplifies chunk printing when chunked transfer encoding is used in a response... And it comes handy when gzip content encoding will be used.
Signed-off-by: Andrej Krpic <[email protected]> --- client.c | 17 +++++++++++++++++ file.c | 6 ++++-- uhttpd.h | 1 + utils.c | 31 +++++++------------------------ 4 files changed, 29 insertions(+), 26 deletions(-) diff --git a/client.c b/client.c index dbdd1a3..8569b21 100644 --- a/client.c +++ b/client.c @@ -42,6 +42,21 @@ const char * const http_methods[] = { [UH_HTTP_MSG_OPTIONS] = "OPTIONS", }; +static int chunked_write_cb(struct ustream *s, const char *buf, int len, bool more) +{ + struct client *cl = container_of(s, struct client, chunked); + ustream_printf(cl->us, "%X\r\n", len); + ustream_write(cl->us, buf, len, more); + ustream_printf(cl->us, "\r\n"); + return len; +} + +static void chunked_init(struct client *cl) +{ + ustream_init_defaults(&cl->chunked); + cl->chunked.write = &chunked_write_cb; +} + void uh_http_header(struct client *cl, int code, const char *summary) { struct http_request *r = &cl->request; @@ -52,6 +67,8 @@ void uh_http_header(struct client *cl, int code, const char *summary) if (!cl->request.respond_chunked) enc = ""; + else + chunked_init(cl); if (r->connection_close) conn = "Connection: close"; diff --git a/file.c b/file.c index 9a2880f..9254e63 100644 --- a/file.c +++ b/file.c @@ -579,8 +579,10 @@ static void uh_file_data(struct client *cl, struct path_info *pi, int fd) ustream_printf(cl->us, "Content-Type: %s\r\n", uh_file_mime_lookup(pi->name)); - ustream_printf(cl->us, "Content-Length: %" PRIu64 "\r\n\r\n", - pi->stat.st_size); + if (!cl->request.respond_chunked) + ustream_printf(cl->us, "Content-Length: %" PRIu64 "\r\n", + pi->stat.st_size); + ustream_printf(cl->us, "\r\n"); /* send body */ diff --git a/uhttpd.h b/uhttpd.h index fbcb1ed..dd41c25 100644 --- a/uhttpd.h +++ b/uhttpd.h @@ -236,6 +236,7 @@ struct client { struct ustream *us; struct ustream_fd sfd; + struct ustream chunked; #ifdef HAVE_TLS struct ustream_ssl ssl; #endif diff --git a/utils.c b/utils.c index 857e326..572beb9 100644 --- a/utils.c +++ b/utils.c @@ -37,44 +37,27 @@ bool uh_use_chunked(struct client *cl) void uh_chunk_write(struct client *cl, const void *data, int len) { - bool chunked = cl->request.respond_chunked; - if (cl->state == CLIENT_STATE_CLEANUP) return; uloop_timeout_set(&cl->timeout, conf.network_timeout * 1000); - if (chunked) - ustream_printf(cl->us, "%X\r\n", len); - ustream_write(cl->us, data, len, true); - if (chunked) - ustream_printf(cl->us, "\r\n", len); + + if (!cl->request.respond_chunked) + ustream_write(cl->us, data, len, true); + else + ustream_write(&cl->chunked, data, len, true); } void uh_chunk_vprintf(struct client *cl, const char *format, va_list arg) { - char buf[256]; - va_list arg2; - int len; - if (cl->state == CLIENT_STATE_CLEANUP) return; uloop_timeout_set(&cl->timeout, conf.network_timeout * 1000); - if (!cl->request.respond_chunked) { + if (!cl->request.respond_chunked) ustream_vprintf(cl->us, format, arg); - return; - } - - va_copy(arg2, arg); - len = vsnprintf(buf, sizeof(buf), format, arg2); - va_end(arg2); - - ustream_printf(cl->us, "%X\r\n", len); - if (len < sizeof(buf)) - ustream_write(cl->us, buf, len, true); else - ustream_vprintf(cl->us, format, arg); - ustream_printf(cl->us, "\r\n", len); + ustream_vprintf(&cl->chunked, format, arg); } void uh_chunk_printf(struct client *cl, const char *format, ...) -- 2.4.6 _______________________________________________ openwrt-devel mailing list [email protected] https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
