uhttpd: add support for adding arbitrary headers via handler scripts
authorFelix Fietkau <nbd@nbd.name>
Thu, 16 Jun 2016 16:26:18 +0000 (18:26 +0200)
committerFelix Fietkau <nbd@nbd.name>
Thu, 16 Jun 2016 16:26:18 +0000 (18:26 +0200)
Signed-off-by: Felix Fietkau <nbd@nbd.name>
client.c
file.c
handler.c
uhttpd.h

index 73e0e49c3bf55bbeb40c6018db482d4c91d81950..05044ed9d38dc3755a80a9cd8e2c7cc2cbf631c9 100644 (file)
--- a/client.c
+++ b/client.c
@@ -45,8 +45,10 @@ const char * const http_methods[] = {
 void uh_http_header(struct client *cl, int code, const char *summary)
 {
        struct http_request *r = &cl->request;
+       struct blob_attr *cur;
        const char *enc = "Transfer-Encoding: chunked\r\n";
        const char *conn;
+       int rem;
 
        cl->http_code = code;
 
@@ -64,6 +66,10 @@ void uh_http_header(struct client *cl, int code, const char *summary)
 
        if (!r->connection_close)
                ustream_printf(cl->us, "Keep-Alive: timeout=%d\r\n", conf.http_keepalive);
+
+       blobmsg_for_each_attr(cur, cl->hdr_response.head, rem)
+               ustream_printf(cl->us, "%s: %s\r\n", blobmsg_name(cur),
+                              blobmsg_get_string(cur));
 }
 
 static void uh_connection_close(struct client *cl)
@@ -114,6 +120,7 @@ void uh_request_done(struct client *cl)
 {
        uh_chunk_eof(cl);
        uh_dispatch_done(cl);
+       blob_buf_init(&cl->hdr_response, 0);
        memset(&cl->dispatch, 0, sizeof(cl->dispatch));
 
        if (!conf.http_keepalive || cl->request.connection_close)
@@ -530,6 +537,7 @@ static void client_close(struct client *cl)
        close(cl->sfd.fd.fd);
        list_del(&cl->list);
        blob_buf_free(&cl->hdr);
+       blob_buf_free(&cl->hdr_response);
        free(cl);
 
        uh_unblock_listeners();
diff --git a/file.c b/file.c
index 12aa130343b14e20334774875698be7e7a168aa1..e801a9ecc29286405944641169bed1ec78fb77ff 100644 (file)
--- a/file.c
+++ b/file.c
@@ -863,6 +863,7 @@ void uh_handle_request(struct client *cl)
        char *url = blobmsg_data(blob_data(cl->hdr.head));
        char *error_handler;
 
+       blob_buf_init(&cl->hdr_response, 0);
        url = uh_handle_alias(url);
 
        uh_handler_run(cl, &url, false);
index 8e8b9c8c3fc832522d2244933b750af1eb366134..0279a6c1e24228f7e8beed303d84ba8cd89ac686 100644 (file)
--- a/handler.c
+++ b/handler.c
@@ -102,6 +102,24 @@ handle_set_uri(struct json_script_ctx *ctx, struct blob_attr *data)
        json_script_abort(ctx);
 }
 
+static void
+handle_add_header(struct json_script_ctx *ctx, struct blob_attr *data)
+{
+       struct client *cl = cur_client;
+       static struct blobmsg_policy policy[2] = {
+                { .type = BLOBMSG_TYPE_STRING },
+                { .type = BLOBMSG_TYPE_STRING },
+       };
+       struct blob_attr *tb[2];
+
+       blobmsg_parse_array(policy, ARRAY_SIZE(tb), tb, blobmsg_data(data), blobmsg_data_len(data));
+       if (!tb[0] || !tb[1])
+               return;
+
+       blobmsg_add_string(&cl->hdr_response, blobmsg_get_string(tb[0]),
+                          blobmsg_get_string(tb[1]));
+}
+
 static void
 handle_command(struct json_script_ctx *ctx, const char *name,
               struct blob_attr *data, struct blob_attr *vars)
@@ -111,7 +129,8 @@ handle_command(struct json_script_ctx *ctx, const char *name,
                void (*func)(struct json_script_ctx *ctx, struct blob_attr *data);
        } cmds[] = {
                { "redirect", handle_redirect },
-               { "rewrite", handle_set_uri }
+               { "rewrite", handle_set_uri },
+               { "add-header", handle_add_header },
        };
        int i;
 
index f9ea76196ec1706553fab7a1adc9741ca45cb2ff..b022ecf509ece2579ee9c80aada1f54b44c6f8d3 100644 (file)
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -258,6 +258,7 @@ struct client {
        struct uh_addr srv_addr, peer_addr;
 
        struct blob_buf hdr;
+       struct blob_buf hdr_response;
        struct dispatch dispatch;
 };