[package] uhttpd:
- make script timeout configurable - catch SIGCHLD to properly interrupt select() - flag listen and client sockets as close-on-exec git-svn-id: svn://svn.openwrt.org/openwrt/trunk@20500 3c298f89-4303-0410-b956-a3cf2f4a3e73master
parent
78c616da82
commit
99e8e7cf2f
|
@ -8,7 +8,7 @@
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=uhttpd
|
PKG_NAME:=uhttpd
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
# Server configuration
|
# Server configuration
|
||||||
config uhttpd main
|
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
|
# Server document root
|
||||||
option home /www
|
option home /www
|
||||||
|
|
||||||
|
@ -19,13 +27,11 @@ config uhttpd main
|
||||||
# option lua_prefix /luci
|
# option lua_prefix /luci
|
||||||
# option lua_handler /usr/lib/lua/luci/sgi/uhttpd.lua
|
# option lua_handler /usr/lib/lua/luci/sgi/uhttpd.lua
|
||||||
|
|
||||||
# HTTP listen addresses, multiple allowed
|
# CGI/Lua timeout, if the called script does not
|
||||||
list listen_http 0.0.0.0:80
|
# write data within the given amount of seconds,
|
||||||
# list listen_http [::]:80
|
# the server will temrinate the request with
|
||||||
|
# 504 Gateway Timeout response.
|
||||||
# HTTPS listen addresses, multiple allowed
|
option script_timeout 60
|
||||||
list listen_https 0.0.0.0:443
|
|
||||||
# list listen_https [::]:443
|
|
||||||
|
|
||||||
# Basic auth realm, defaults to local hostname
|
# Basic auth realm, defaults to local hostname
|
||||||
# option realm OpenWrt
|
# option realm OpenWrt
|
||||||
|
|
|
@ -65,6 +65,7 @@ start_instance()
|
||||||
append_arg "$cfg" cgi_prefix "-x"
|
append_arg "$cfg" cgi_prefix "-x"
|
||||||
append_arg "$cfg" lua_prefix "-l"
|
append_arg "$cfg" lua_prefix "-l"
|
||||||
append_arg "$cfg" lua_handler "-L"
|
append_arg "$cfg" lua_handler "-L"
|
||||||
|
append_arg "$cfg" script_timeout "-t"
|
||||||
|
|
||||||
config_list_foreach "$cfg" listen_http \
|
config_list_foreach "$cfg" listen_http \
|
||||||
append_listen_http
|
append_listen_http
|
||||||
|
|
|
@ -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(rfd[0], &reader);
|
||||||
FD_SET(wfd[1], &writer);
|
FD_SET(wfd[1], &writer);
|
||||||
|
|
||||||
timeout.tv_sec = 15;
|
timeout.tv_sec = cl->server->conf->script_timeout;
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
/* wait until we can read or write or both */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
|
if( (errno != EINTR) && ! header_sent )
|
||||||
"The CGI script took too long to produce a response"));
|
{
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(rfd[0], &reader);
|
||||||
FD_SET(wfd[1], &writer);
|
FD_SET(wfd[1], &writer);
|
||||||
|
|
||||||
timeout.tv_sec = 15;
|
timeout.tv_sec = cl->server->conf->script_timeout;
|
||||||
timeout.tv_usec = 0;
|
timeout.tv_usec = 0;
|
||||||
|
|
||||||
/* wait until we can read or write or both */
|
/* 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
|
else
|
||||||
{
|
{
|
||||||
ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
|
if( (errno != EINTR) && ! data_sent )
|
||||||
"The Lua handler took too long to produce a response"));
|
{
|
||||||
|
ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
|
||||||
|
"The Lua script took too long to produce "
|
||||||
|
"a response"));
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,9 @@
|
||||||
#define foreach_header(i, h) \
|
#define foreach_header(i, h) \
|
||||||
for( i = 0; (i + 1) < (sizeof(h) / sizeof(h[0])) && h[i]; i += 2 )
|
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 {
|
struct path_info {
|
||||||
char *root;
|
char *root;
|
||||||
char *phys;
|
char *phys;
|
||||||
|
|
|
@ -42,6 +42,11 @@ static void uh_sigterm(int sig)
|
||||||
run = 0;
|
run = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uh_sigchld(int sig)
|
||||||
|
{
|
||||||
|
while( waitpid(-1, NULL, WNOHANG) > 0 ) { }
|
||||||
|
}
|
||||||
|
|
||||||
static void uh_config_parse(const char *path)
|
static void uh_config_parse(const char *path)
|
||||||
{
|
{
|
||||||
FILE *c;
|
FILE *c;
|
||||||
|
@ -155,6 +160,7 @@ static int uh_socket_bind(
|
||||||
|
|
||||||
/* add socket to server fd set */
|
/* add socket to server fd set */
|
||||||
FD_SET(sock, serv_fds);
|
FD_SET(sock, serv_fds);
|
||||||
|
fd_cloexec(sock);
|
||||||
*max_fd = max(*max_fd, sock);
|
*max_fd = max(*max_fd, sock);
|
||||||
|
|
||||||
bound++;
|
bound++;
|
||||||
|
@ -432,6 +438,8 @@ int main (int argc, char **argv)
|
||||||
|
|
||||||
sa.sa_handler = SIG_IGN;
|
sa.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGPIPE, &sa, NULL);
|
sigaction(SIGPIPE, &sa, NULL);
|
||||||
|
|
||||||
|
sa.sa_handler = uh_sigchld;
|
||||||
sigaction(SIGCHLD, &sa, NULL);
|
sigaction(SIGCHLD, &sa, NULL);
|
||||||
|
|
||||||
sa.sa_handler = uh_sigterm;
|
sa.sa_handler = uh_sigterm;
|
||||||
|
@ -485,7 +493,7 @@ int main (int argc, char **argv)
|
||||||
}
|
}
|
||||||
#endif
|
#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)
|
switch(opt)
|
||||||
{
|
{
|
||||||
|
@ -593,6 +601,13 @@ int main (int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_CGI) || defined(HAVE_LUA)
|
||||||
|
/* script timeout */
|
||||||
|
case 't':
|
||||||
|
conf.script_timeout = atoi(optarg);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* no fork */
|
/* no fork */
|
||||||
case 'f':
|
case 'f':
|
||||||
nofork = 1;
|
nofork = 1;
|
||||||
|
@ -644,6 +659,9 @@ int main (int argc, char **argv)
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_CGI
|
#ifdef HAVE_CGI
|
||||||
" -x string URL prefix for CGI handler, default is '/cgi-bin'\n"
|
" -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
|
#endif
|
||||||
" -d string URL decode given string\n"
|
" -d string URL decode given string\n"
|
||||||
" -r string Specify basic auth realm\n"
|
" -r string Specify basic auth realm\n"
|
||||||
|
@ -684,6 +702,12 @@ int main (int argc, char **argv)
|
||||||
/* config file */
|
/* config file */
|
||||||
uh_config_parse(conf.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
|
#ifdef HAVE_CGI
|
||||||
/* default cgi prefix */
|
/* default cgi prefix */
|
||||||
if( ! conf.cgi_prefix )
|
if( ! conf.cgi_prefix )
|
||||||
|
@ -794,6 +818,7 @@ int main (int argc, char **argv)
|
||||||
|
|
||||||
/* add client socket to global fdset */
|
/* add client socket to global fdset */
|
||||||
FD_SET(new_fd, &used_fds);
|
FD_SET(new_fd, &used_fds);
|
||||||
|
fd_cloexec(new_fd);
|
||||||
max_fd = max(max_fd, new_fd);
|
max_fd = max(max_fd, new_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <linux/limits.h>
|
#include <linux/limits.h>
|
||||||
|
@ -73,6 +74,9 @@ struct config {
|
||||||
void (*lua_close) (lua_State *L);
|
void (*lua_close) (lua_State *L);
|
||||||
void (*lua_request) (struct client *cl, struct http_request *req, lua_State *L);
|
void (*lua_request) (struct client *cl, struct http_request *req, lua_State *L);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_CGI) || defined(HAVE_LUA)
|
||||||
|
int script_timeout;
|
||||||
|
#endif
|
||||||
#ifdef HAVE_TLS
|
#ifdef HAVE_TLS
|
||||||
char *cert;
|
char *cert;
|
||||||
char *key;
|
char *key;
|
||||||
|
|
Loading…
Reference in New Issue