implement support for script timeout for cgi/lua
authorFelix Fietkau <nbd@openwrt.org>
Sat, 19 Jan 2013 18:06:25 +0000 (19:06 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Sat, 19 Jan 2013 18:31:21 +0000 (19:31 +0100)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
proc.c
relay.c
uhttpd.h

diff --git a/proc.c b/proc.c
index a1d48ad51ed61dd865db817eff384cccb007197c..02e056c15592dc569aed30e99257ea183df978c0 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -214,9 +214,11 @@ static void proc_handle_header(struct relay *r, const char *name, const char *va
 static void proc_handle_header_end(struct relay *r)
 {
        struct client *cl = r->cl;
+       struct dispatch_proc *p = &cl->dispatch.proc;
        struct blob_attr *cur;
        int rem;
 
+       uloop_timeout_cancel(&p->timeout);
        uh_http_header(cl, cl->dispatch.proc.status_code, cl->dispatch.proc.status_msg);
        blob_for_each_attr(cur, cl->dispatch.proc.hdr.head, rem)
                ustream_printf(cl->us, "%s: %s\r\n", blobmsg_name(cur), blobmsg_data(cur));
@@ -239,6 +241,8 @@ static void proc_write_close(struct client *cl)
 static void proc_free(struct client *cl)
 {
        struct dispatch_proc *p = &cl->dispatch.proc;
+
+       uloop_timeout_cancel(&p->timeout);
        blob_buf_free(&p->hdr);
        proc_write_close(cl);
        uh_relay_free(&p->r);
@@ -298,6 +302,14 @@ static int proc_data_send(struct client *cl, const char *data, int len)
        return retlen;
 }
 
+static void proc_timeout_cb(struct uloop_timeout *timeout)
+{
+       struct dispatch_proc *proc = container_of(timeout, struct dispatch_proc, timeout);
+       struct client *cl = container_of(proc, struct client, dispatch.proc);
+
+       uh_relay_kill(cl, &proc->r);
+}
+
 bool uh_create_process(struct client *cl, struct path_info *pi, char *url,
                       void (*cb)(struct client *cl, struct path_info *pi, char *url))
 {
@@ -352,6 +364,9 @@ bool uh_create_process(struct client *cl, struct path_info *pi, char *url,
        proc->r.header_end = proc_handle_header_end;
        proc->r.close = proc_handle_close;
        proc->wrfd.cb = proc_write_cb;
+       proc->timeout.cb = proc_timeout_cb;
+       if (conf.script_timeout > 0)
+               uloop_timeout_set(&proc->timeout, conf.script_timeout * 1000);
 
        return true;
 
diff --git a/relay.c b/relay.c
index 09f53a13c1d707de723a8741a691b11e0ada33e7..5de5cb403df735f4bdfd1d7de6ed421a59305ce4 100644 (file)
--- a/relay.c
+++ b/relay.c
@@ -162,6 +162,15 @@ static void relay_proc_cb(struct uloop_process *proc, int ret)
        relay_close_if_done(r);
 }
 
+void uh_relay_kill(struct client *cl, struct relay *r)
+{
+       struct ustream *us = &r->sfd.stream;
+
+       kill(r->proc.pid, SIGKILL);
+       us->eof = true;
+       ustream_state_change(us);
+}
+
 void uh_relay_open(struct client *cl, struct relay *r, int fd, int pid)
 {
        struct ustream *us = &r->sfd.stream;
index 807070c509a81c8a0f0601f0db7980a165b8cb94..c4afee8ed639c35439e0f204bed0be49fa886de0 100644 (file)
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -157,6 +157,7 @@ struct relay {
 };
 
 struct dispatch_proc {
+       struct uloop_timeout timeout;
        struct blob_buf hdr;
        struct uloop_fd wrfd;
        struct relay r;
@@ -286,6 +287,7 @@ void uh_dispatch_add(struct dispatch_handler *d);
 void uh_relay_open(struct client *cl, struct relay *r, int fd, int pid);
 void uh_relay_close(struct relay *r, int ret);
 void uh_relay_free(struct relay *r);
+void uh_relay_kill(struct client *cl, struct relay *r);
 
 struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi);
 bool uh_create_process(struct client *cl, struct path_info *pi, char *url,