aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--package/uhttpd/Makefile2
-rw-r--r--package/uhttpd/files/uhttpd.config20
-rwxr-xr-xpackage/uhttpd/files/uhttpd.init1
-rw-r--r--package/uhttpd/src/uhttpd-cgi.c15
-rw-r--r--package/uhttpd/src/uhttpd-lua.c12
-rw-r--r--package/uhttpd/src/uhttpd-utils.h3
-rw-r--r--package/uhttpd/src/uhttpd.c27
-rw-r--r--package/uhttpd/src/uhttpd.h4
8 files changed, 67 insertions, 17 deletions
diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile
index d5c07a359a..3e7344911b 100644
--- a/package/uhttpd/Makefile
+++ b/package/uhttpd/Makefile
@@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=uhttpd
-PKG_RELEASE:=1
+PKG_RELEASE:=2
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
diff --git a/package/uhttpd/files/uhttpd.config b/package/uhttpd/files/uhttpd.config
index 0bca4f516b..79b018cf80 100644
--- a/package/uhttpd/files/uhttpd.config
+++ b/package/uhttpd/files/uhttpd.config
@@ -1,6 +1,14 @@
# Server configuration
config uhttpd main
+ # HTTP listen addresses, multiple allowed
+ list listen_http 0.0.0.0:80
+# list listen_http [::]:80
+
+ # HTTPS listen addresses, multiple allowed
+ list listen_https 0.0.0.0:443
+# list listen_https [::]:443
+
# Server document root
option home /www
@@ -19,13 +27,11 @@ config uhttpd main
# option lua_prefix /luci
# option lua_handler /usr/lib/lua/luci/sgi/uhttpd.lua
- # HTTP listen addresses, multiple allowed
- list listen_http 0.0.0.0:80
-# list listen_http [::]:80
-
- # HTTPS listen addresses, multiple allowed
- list listen_https 0.0.0.0:443
-# list listen_https [::]:443
+ # CGI/Lua timeout, if the called script does not
+ # write data within the given amount of seconds,
+ # the server will temrinate the request with
+ # 504 Gateway Timeout response.
+ option script_timeout 60
# Basic auth realm, defaults to local hostname
# option realm OpenWrt
diff --git a/package/uhttpd/files/uhttpd.init b/package/uhttpd/files/uhttpd.init
index a25bf789cb..ba7dd49fbd 100755
--- a/package/uhttpd/files/uhttpd.init
+++ b/package/uhttpd/files/uhttpd.init
@@ -65,6 +65,7 @@ start_instance()
append_arg "$cfg" cgi_prefix "-x"
append_arg "$cfg" lua_prefix "-l"
append_arg "$cfg" lua_handler "-L"
+ append_arg "$cfg" script_timeout "-t"
config_list_foreach "$cfg" listen_http \
append_listen_http
diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c
index 5565197ca7..4a30f2fc9a 100644
--- a/package/uhttpd/src/uhttpd-cgi.c
+++ b/package/uhttpd/src/uhttpd-cgi.c
@@ -372,7 +372,7 @@ void uh_cgi_request(struct client *cl, struct http_request *req, struct path_inf
FD_SET(rfd[0], &reader);
FD_SET(wfd[1], &writer);
- timeout.tv_sec = 15;
+ timeout.tv_sec = cl->server->conf->script_timeout;
timeout.tv_usec = 0;
/* wait until we can read or write or both */
@@ -538,11 +538,18 @@ void uh_cgi_request(struct client *cl, struct http_request *req, struct path_inf
}
}
- /* no activity for 15 seconds... looks dead */
+ /* timeout exceeded or interrupted by SIGCHLD */
else
{
- ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
- "The CGI script took too long to produce a response"));
+ if( (errno != EINTR) && ! header_sent )
+ {
+ ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
+ "The CGI script took too long to produce "
+ "a response"));
+ }
+
+ /* send final chunk if we're in chunked transfer mode */
+ ensure(uh_http_send(cl, req, "", 0));
break;
}
diff --git a/package/uhttpd/src/uhttpd-lua.c b/package/uhttpd/src/uhttpd-lua.c
index ab09841cd6..c1e7490438 100644
--- a/package/uhttpd/src/uhttpd-lua.c
+++ b/package/uhttpd/src/uhttpd-lua.c
@@ -448,7 +448,7 @@ void uh_lua_request(struct client *cl, struct http_request *req, lua_State *L)
FD_SET(rfd[0], &reader);
FD_SET(wfd[1], &writer);
- timeout.tv_sec = 15;
+ timeout.tv_sec = cl->server->conf->script_timeout;
timeout.tv_usec = 0;
/* wait until we can read or write or both */
@@ -512,11 +512,15 @@ void uh_lua_request(struct client *cl, struct http_request *req, lua_State *L)
}
}
- /* no activity for 15 seconds... looks dead */
+ /* timeout exceeded or interrupted by SIGCHLD */
else
{
- ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
- "The Lua handler took too long to produce a response"));
+ if( (errno != EINTR) && ! data_sent )
+ {
+ ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
+ "The Lua script took too long to produce "
+ "a response"));
+ }
break;
}
diff --git a/package/uhttpd/src/uhttpd-utils.h b/package/uhttpd/src/uhttpd-utils.h
index c7a6c90beb..43a74e5616 100644
--- a/package/uhttpd/src/uhttpd-utils.h
+++ b/package/uhttpd/src/uhttpd-utils.h
@@ -33,6 +33,9 @@
#define foreach_header(i, h) \
for( i = 0; (i + 1) < (sizeof(h) / sizeof(h[0])) && h[i]; i += 2 )
+#define fd_cloexec(fd) \
+ fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC)
+
struct path_info {
char *root;
char *phys;
diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c
index a7db794a5b..97c4f836b7 100644
--- a/package/uhttpd/src/uhttpd.c
+++ b/package/uhttpd/src/uhttpd.c
@@ -42,6 +42,11 @@ static void uh_sigterm(int sig)
run = 0;
}
+static void uh_sigchld(int sig)
+{
+ while( waitpid(-1, NULL, WNOHANG) > 0 ) { }
+}
+
static void uh_config_parse(const char *path)
{
FILE *c;
@@ -155,6 +160,7 @@ static int uh_socket_bind(
/* add socket to server fd set */
FD_SET(sock, serv_fds);
+ fd_cloexec(sock);
*max_fd = max(*max_fd, sock);
bound++;
@@ -432,6 +438,8 @@ int main (int argc, char **argv)
sa.sa_handler = SIG_IGN;
sigaction(SIGPIPE, &sa, NULL);
+
+ sa.sa_handler = uh_sigchld;
sigaction(SIGCHLD, &sa, NULL);
sa.sa_handler = uh_sigterm;
@@ -485,7 +493,7 @@ int main (int argc, char **argv)
}
#endif
- while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:")) > 0 )
+ while( (opt = getopt(argc, argv, "fC:K:p:s:h:c:l:L:d:r:m:x:t:")) > 0 )
{
switch(opt)
{
@@ -593,6 +601,13 @@ int main (int argc, char **argv)
break;
#endif
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ /* script timeout */
+ case 't':
+ conf.script_timeout = atoi(optarg);
+ break;
+#endif
+
/* no fork */
case 'f':
nofork = 1;
@@ -645,6 +660,9 @@ int main (int argc, char **argv)
#ifdef HAVE_CGI
" -x string URL prefix for CGI handler, default is '/cgi-bin'\n"
#endif
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ " -t seconds CGI and Lua script timeout in seconds, default is 60\n"
+#endif
" -d string URL decode given string\n"
" -r string Specify basic auth realm\n"
" -m string MD5 crypt given string\n"
@@ -684,6 +702,12 @@ int main (int argc, char **argv)
/* config file */
uh_config_parse(conf.file);
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ /* default script timeout */
+ if( conf.script_timeout <= 0 )
+ conf.script_timeout = 60;
+#endif
+
#ifdef HAVE_CGI
/* default cgi prefix */
if( ! conf.cgi_prefix )
@@ -794,6 +818,7 @@ int main (int argc, char **argv)
/* add client socket to global fdset */
FD_SET(new_fd, &used_fds);
+ fd_cloexec(new_fd);
max_fd = max(max_fd, new_fd);
}
diff --git a/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h
index bb08afa1a1..0e9f1ee886 100644
--- a/package/uhttpd/src/uhttpd.h
+++ b/package/uhttpd/src/uhttpd.h
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/select.h>
+#include <sys/wait.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/limits.h>
@@ -73,6 +74,9 @@ struct config {
void (*lua_close) (lua_State *L);
void (*lua_request) (struct client *cl, struct http_request *req, lua_State *L);
#endif
+#if defined(HAVE_CGI) || defined(HAVE_LUA)
+ int script_timeout;
+#endif
#ifdef HAVE_TLS
char *cert;
char *key;