[OpenWrt-Devel] [PATCH 1/2] uhttpd: use separate ustream for chunked transfer encoding
Andrej Krpic
ak77 at tnode.com
Thu Oct 1 18:22:13 EDT 2015
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 <ak77 at tnode.com>
---
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
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel
More information about the openwrt-devel
mailing list