diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile
index cefd30bb8cd2440572004232655c073aff9a4f15..245426b4e2681675d09fcab48610a1c071c81733 100644
--- a/package/uhttpd/Makefile
+++ b/package/uhttpd/Makefile
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uhttpd
-PKG_RELEASE:=39
+PKG_RELEASE:=40
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 PKG_CONFIG_DEPENDS := \
diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c
index b46ebf2bdd7e60243ca902f233e4c90cc3d3bd23..69af90db4575145c1922dccb124b961a46695113 100644
--- a/package/uhttpd/src/uhttpd-cgi.c
+++ b/package/uhttpd/src/uhttpd-cgi.c
@@ -201,9 +201,10 @@ static bool uh_cgi_socket_cb(struct client *cl)
 			{
 				/* write status */
 				ensure_out(uh_http_sendf(cl, NULL,
-					"HTTP/%.1f %03d %s\r\n"
+					"%s %03d %s\r\n"
 					"Connection: close\r\n",
-					req->version, res->statuscode, res->statusmsg));
+					http_versions[req->version],
+					res->statuscode, res->statusmsg));
 
 				/* add Content-Type if no Location or Content-Type */
 				if (!uh_cgi_header_lookup(res, "Location") &&
@@ -214,7 +215,7 @@ static bool uh_cgi_socket_cb(struct client *cl)
 				}
 
 				/* if request was HTTP 1.1 we'll respond chunked */
-				if ((req->version > 1.0) &&
+				if ((req->version > UH_HTTP_VER_1_0) &&
 					!uh_cgi_header_lookup(res, "Transfer-Encoding"))
 				{
 					ensure_out(uh_http_send(cl, NULL,
@@ -260,10 +261,11 @@ static bool uh_cgi_socket_cb(struct client *cl)
 				 */
 
 				ensure_out(uh_http_sendf(cl, NULL,
-										 "HTTP/%.1f 200 OK\r\n"
+										 "%s 200 OK\r\n"
 										 "Content-Type: text/plain\r\n"
 										 "%s\r\n",
-										 req->version, (req->version > 1.0)
+										 http_versions[req->version],
+										 (req->version > UH_HTTP_VER_1_0)
 										 ? "Transfer-Encoding: chunked\r\n" : ""
 				));
 
@@ -427,26 +429,10 @@ bool uh_cgi_request(struct client *cl, struct path_info *pi,
 			}
 
 			/* http version */
-			if (req->version > 1.0)
-				setenv("SERVER_PROTOCOL", "HTTP/1.1", 1);
-			else
-				setenv("SERVER_PROTOCOL", "HTTP/1.0", 1);
+			setenv("SERVER_PROTOCOL", http_versions[req->version], 1);
 
 			/* request method */
-			switch (req->method)
-			{
-				case UH_HTTP_MSG_GET:
-					setenv("REQUEST_METHOD", "GET", 1);
-					break;
-
-				case UH_HTTP_MSG_HEAD:
-					setenv("REQUEST_METHOD", "HEAD", 1);
-					break;
-
-				case UH_HTTP_MSG_POST:
-					setenv("REQUEST_METHOD", "POST", 1);
-					break;
-			}
+			setenv("REQUEST_METHOD", http_methods[req->method], 1);
 
 			/* request url */
 			setenv("REQUEST_URI", req->url, 1);
diff --git a/package/uhttpd/src/uhttpd-file.c b/package/uhttpd/src/uhttpd-file.c
index 2e5914a3c0bd3248c7c4f82ab77fb044d51c3d53..0bafc2b38cdba7b2c706154f4a64586034ed81b0 100644
--- a/package/uhttpd/src/uhttpd-file.c
+++ b/package/uhttpd/src/uhttpd-file.c
@@ -113,16 +113,16 @@ static int uh_file_response_ok_hdrs(struct client *cl, struct stat *s)
 
 static int uh_file_response_200(struct client *cl, struct stat *s)
 {
-	ensure_ret(uh_http_sendf(cl, NULL, "HTTP/%.1f 200 OK\r\n",
-							 cl->request.version));
+	ensure_ret(uh_http_sendf(cl, NULL, "%s 200 OK\r\n",
+							 http_versions[cl->request.version]));
 
 	return uh_file_response_ok_hdrs(cl, s);
 }
 
 static int uh_file_response_304(struct client *cl, struct stat *s)
 {
-	ensure_ret(uh_http_sendf(cl, NULL, "HTTP/%.1f 304 Not Modified\r\n",
-							 cl->request.version));
+	ensure_ret(uh_http_sendf(cl, NULL, "%s 304 Not Modified\r\n",
+							 http_versions[cl->request.version]));
 
 	return uh_file_response_ok_hdrs(cl, s);
 }
@@ -130,8 +130,9 @@ static int uh_file_response_304(struct client *cl, struct stat *s)
 static int uh_file_response_412(struct client *cl)
 {
 	return uh_http_sendf(cl, NULL,
-						 "HTTP/%.1f 412 Precondition Failed\r\n"
-						 "Connection: close\r\n", cl->request.version);
+						 "%s 412 Precondition Failed\r\n"
+						 "Connection: close\r\n",
+	                     http_versions[cl->request.version]);
 }
 
 static int uh_file_if_match(struct client *cl, struct stat *s, int *ok)
diff --git a/package/uhttpd/src/uhttpd-lua.c b/package/uhttpd/src/uhttpd-lua.c
index 94626bb56b172dfb085b1fc977256aaf251f39e2..e113937399424cbbfaae3e41d3d4ad0dcf6bb126 100644
--- a/package/uhttpd/src/uhttpd-lua.c
+++ b/package/uhttpd/src/uhttpd-lua.c
@@ -66,7 +66,7 @@ static int uh_lua_recv(lua_State *L)
 	return 1;
 }
 
-static int uh_lua_send_common(lua_State *L, int chunked)
+static int uh_lua_send_common(lua_State *L, bool chunked)
 {
 	size_t length;
 
@@ -112,12 +112,12 @@ out:
 
 static int uh_lua_send(lua_State *L)
 {
-	return uh_lua_send_common(L, 0);
+	return uh_lua_send_common(L, false);
 }
 
 static int uh_lua_sendc(lua_State *L)
 {
-	return uh_lua_send_common(L, 1);
+	return uh_lua_send_common(L, true);
 }
 
 static int uh_lua_str2str(lua_State *L, int (*xlate_func) (char *, int, const char *, int))
@@ -414,21 +414,7 @@ bool uh_lua_request(struct client *cl, lua_State *L)
 		lua_newtable(L);
 
 		/* request method */
-		switch(req->method)
-		{
-			case UH_HTTP_MSG_GET:
-				lua_pushstring(L, "GET");
-				break;
-
-			case UH_HTTP_MSG_HEAD:
-				lua_pushstring(L, "HEAD");
-				break;
-
-			case UH_HTTP_MSG_POST:
-				lua_pushstring(L, "POST");
-				break;
-		}
-
+		lua_pushstring(L, http_methods[req->method]);
 		lua_setfield(L, -2, "REQUEST_METHOD");
 
 		/* request url */
@@ -462,14 +448,10 @@ bool uh_lua_request(struct client *cl, lua_State *L)
 		}
 
 		/* http protcol version */
-		lua_pushnumber(L, floor(req->version * 10) / 10);
+		lua_pushnumber(L, 0.9 + (req->version / 10.0));
 		lua_setfield(L, -2, "HTTP_VERSION");
 
-		if (req->version > 1.0)
-			lua_pushstring(L, "HTTP/1.1");
-		else
-			lua_pushstring(L, "HTTP/1.0");
-
+		lua_pushstring(L, http_versions[req->version]);
 		lua_setfield(L, -2, "SERVER_PROTOCOL");
 
 
@@ -529,12 +511,13 @@ bool uh_lua_request(struct client *cl, lua_State *L)
 				if (! err_str)
 					err_str = "Unknown error";
 
-				printf("HTTP/%.1f 500 Internal Server Error\r\n"
+				printf("%s 500 Internal Server Error\r\n"
 					   "Connection: close\r\n"
 					   "Content-Type: text/plain\r\n"
 					   "Content-Length: %i\r\n\r\n"
 					   "Lua raised a runtime error:\n  %s\n",
-					   req->version, 31 + strlen(err_str), err_str);
+					   http_versions[req->version],
+					   31 + strlen(err_str), err_str);
 
 				break;
 
diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c
index 50b10e605028db40ed66d6f224c65c84e0fa39af..c8d3bb40f48b41bf56beaec2c889e0b79123476f 100644
--- a/package/uhttpd/src/uhttpd-utils.c
+++ b/package/uhttpd/src/uhttpd-utils.c
@@ -334,7 +334,7 @@ int uh_http_sendf(struct client *cl, struct http_request *req,
 	len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
 	va_end(ap);
 
-	if ((req != NULL) && (req->version > 1.0))
+	if ((req != NULL) && (req->version > UH_HTTP_VER_1_0))
 		ensure_ret(uh_http_sendc(cl, buffer, len));
 	else if (len > 0)
 		ensure_ret(uh_tcp_send(cl, buffer, len));
@@ -348,7 +348,7 @@ int uh_http_send(struct client *cl, struct http_request *req,
 	if (len < 0)
 		len = strlen(buf);
 
-	if ((req != NULL) && (req->version > 1.0))
+	if ((req != NULL) && (req->version > UH_HTTP_VER_1_0))
 		ensure_ret(uh_http_sendc(cl, buf, len));
 	else if (len > 0)
 		ensure_ret(uh_tcp_send(cl, buf, len));
@@ -865,13 +865,13 @@ int uh_auth_check(struct client *cl, struct http_request *req,
 
 		/* 401 */
 		uh_http_sendf(cl, NULL,
-			"HTTP/%.1f 401 Authorization Required\r\n"
-			"WWW-Authenticate: Basic realm=\"%s\"\r\n"
-			"Content-Type: text/plain\r\n"
-			"Content-Length: 23\r\n\r\n"
-			"Authorization Required\n",
-				req->version, cl->server->conf->realm
-		);
+		              "%s 401 Authorization Required\r\n"
+		              "WWW-Authenticate: Basic realm=\"%s\"\r\n"
+		              "Content-Type: text/plain\r\n"
+		              "Content-Length: 23\r\n\r\n"
+		              "Authorization Required\n",
+		              http_versions[req->version],
+		              cl->server->conf->realm);
 
 		return 0;
 	}
@@ -922,7 +922,8 @@ struct listener * uh_listener_lookup(int sock)
 }
 
 
-struct client * uh_client_add(int sock, struct listener *serv)
+struct client * uh_client_add(int sock, struct listener *serv,
+                              struct sockaddr_in6 *peer)
 {
 	struct client *new = NULL;
 	socklen_t sl;
@@ -930,6 +931,7 @@ struct client * uh_client_add(int sock, struct listener *serv)
 	if ((new = (struct client *)malloc(sizeof(struct client))) != NULL)
 	{
 		memset(new, 0, sizeof(struct client));
+		memcpy(&new->peeraddr, peer, sizeof(new->peeraddr));
 
 		new->fd.fd  = sock;
 		new->server = serv;
@@ -937,14 +939,8 @@ struct client * uh_client_add(int sock, struct listener *serv)
 		new->rpipe.fd = -1;
 		new->wpipe.fd = -1;
 
-		/* get remote endpoint addr */
-		sl = sizeof(struct sockaddr_in6);
-		memset(&(new->peeraddr), 0, sl);
-		getpeername(sock, (struct sockaddr *) &(new->peeraddr), &sl);
-
 		/* get local endpoint addr */
 		sl = sizeof(struct sockaddr_in6);
-		memset(&(new->servaddr), 0, sl);
 		getsockname(sock, (struct sockaddr *) &(new->servaddr), &sl);
 
 		new->next = uh_clients;
@@ -988,7 +984,7 @@ void uh_client_remove(struct client *cl)
 
 	for (cur = uh_clients; cur; prv = cur, cur = cur->next)
 	{
-		if ((cur == cl) || (!cl && cur->dead))
+		if (cur == cl)
 		{
 			if (prv)
 				prv->next = cur->next;
diff --git a/package/uhttpd/src/uhttpd-utils.h b/package/uhttpd/src/uhttpd-utils.h
index 31047f55549f2de3748827f638e3865c495b2f69..9de9191948567c18833ce9008a71cf8368f33b2b 100644
--- a/package/uhttpd/src/uhttpd-utils.h
+++ b/package/uhttpd/src/uhttpd-utils.h
@@ -115,7 +115,9 @@ struct path_info * uh_path_lookup(struct client *cl, const char *url);
 struct listener * uh_listener_add(int sock, struct config *conf);
 struct listener * uh_listener_lookup(int sock);
 
-struct client * uh_client_add(int sock, struct listener *serv);
+struct client * uh_client_add(int sock, struct listener *serv,
+                              struct sockaddr_in6 *peer);
+
 struct client * uh_client_lookup(int sock);
 
 #define uh_client_error(cl, code, status, ...) do { \
diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c
index 9e5a5742639550766b01705ac72d4ec83aaa1ae7..1efcbf0f516ed4e521ce3ecea4e19eefc49967e5 100644
--- a/package/uhttpd/src/uhttpd.c
+++ b/package/uhttpd/src/uhttpd.c
@@ -35,6 +35,9 @@
 #endif
 
 
+const char * http_methods[] = { "GET", "POST", "HEAD", };
+const char * http_versions[] = { "HTTP/0.9", "HTTP/1.0", "HTTP/1.1", };
+
 static int run = 1;
 
 static void uh_sigterm(int sig)
@@ -123,10 +126,9 @@ static void uh_config_parse(struct config *conf)
 
 static void uh_listener_cb(struct uloop_fd *u, unsigned int events);
 
-static int uh_socket_bind(fd_set *serv_fds, int *max_fd,
-						  const char *host, const char *port,
-						  struct addrinfo *hints, int do_tls,
-						  struct config *conf)
+static int uh_socket_bind(const char *host, const char *port,
+                          struct addrinfo *hints, int do_tls,
+                          struct config *conf)
 {
 	int sock = -1;
 	int yes = 1;
@@ -213,11 +215,8 @@ static int uh_socket_bind(fd_set *serv_fds, int *max_fd,
 		l->tls = do_tls ? conf->tls : NULL;
 #endif
 
-		/* add socket to server fd set */
-		FD_SET(sock, serv_fds);
+		/* add socket to uloop */
 		fd_cloexec(sock);
-		*max_fd = max(*max_fd, sock);
-
 		uh_ufd_add(&l->fd, uh_listener_cb, ULOOP_READ);
 
 		bound++;
@@ -268,29 +267,18 @@ static struct http_request * uh_http_header_parse(struct client *cl,
 
 
 		/* check method */
-		if (strcmp(method, "GET") && strcmp(method, "HEAD") && strcmp(method, "POST"))
+		if (method && !strcmp(method, "GET"))
+			req->method = UH_HTTP_MSG_GET;
+		else if (method && !strcmp(method, "POST"))
+			req->method = UH_HTTP_MSG_POST;
+		else if (method && !strcmp(method, "HEAD"))
+			req->method = UH_HTTP_MSG_HEAD;
+		else
 		{
 			/* invalid method */
 			uh_http_response(cl, 405, "Method Not Allowed");
 			return NULL;
 		}
-		else
-		{
-			switch(method[0])
-			{
-				case 'G':
-					req->method = UH_HTTP_MSG_GET;
-					break;
-
-				case 'H':
-					req->method = UH_HTTP_MSG_HEAD;
-					break;
-
-				case 'P':
-					req->method = UH_HTTP_MSG_POST;
-					break;
-			}
-		}
 
 		/* check path */
 		if (!path || !strlen(path))
@@ -305,22 +293,21 @@ static struct http_request * uh_http_header_parse(struct client *cl,
 		}
 
 		/* check version */
-		if ((version == NULL) || (strcmp(version, "HTTP/0.9") &&
-		    strcmp(version, "HTTP/1.0") && strcmp(version, "HTTP/1.1")))
+		if (version && !strcmp(version, "HTTP/0.9"))
+			req->version = UH_HTTP_VER_0_9;
+		else if (version && !strcmp(version, "HTTP/1.0"))
+			req->version = UH_HTTP_VER_1_0;
+		else if (version && !strcmp(version, "HTTP/1.1"))
+			req->version = UH_HTTP_VER_1_1;
+		else
 		{
 			/* unsupported version */
 			uh_http_response(cl, 400, "Bad Request");
 			return NULL;
 		}
-		else
-		{
-			req->version = strtof(&version[5], NULL);
-		}
 
-		D("SRV: %s %s HTTP/%.1f\n",
-		  (req->method == UH_HTTP_MSG_POST) ? "POST" :
-			(req->method == UH_HTTP_MSG_GET) ? "GET" : "HEAD",
-		  req->url, req->version);
+		D("SRV: %s %s %s\n",
+		  http_methods[req->method], req->url, http_versions[req->version]);
 
 		/* process header fields */
 		for (i = (int)(headers - buffer); i < buflen; i++)
@@ -522,6 +509,9 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)
 	struct client *cl;
 	struct config *conf;
 
+	struct sockaddr_in6 sa;
+	socklen_t sl = sizeof(sa);
+
 	serv = container_of(u, struct listener, fd);
 	conf = serv->conf;
 
@@ -530,12 +520,12 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)
 		return;
 
 	/* handle new connections */
-	if ((new_fd = accept(u->fd, NULL, 0)) != -1)
+	if ((new_fd = accept(u->fd, (struct sockaddr *)&sa, &sl)) != -1)
 	{
 		D("SRV: Server(%d) accept => Client(%d)\n", u->fd, new_fd);
 
 		/* add to global client list */
-		if ((cl = uh_client_add(new_fd, serv)) != NULL)
+		if ((cl = uh_client_add(new_fd, serv, &sa)) != NULL)
 		{
 			/* add client socket to global fdset */
 			uh_ufd_add(&cl->fd, uh_socket_cb, ULOOP_READ);
@@ -785,16 +775,13 @@ static inline int uh_inittls(struct config *conf)
 
 int main (int argc, char **argv)
 {
-	/* master file descriptor list */
-	fd_set serv_fds;
-
 	/* working structs */
 	struct addrinfo hints;
 	struct sigaction sa;
 	struct config conf;
 
 	/* maximum file descriptor number */
-	int cur_fd, max_fd = 0;
+	int cur_fd = 0;
 
 #ifdef HAVE_TLS
 	int tls = 0;
@@ -806,16 +793,14 @@ int main (int argc, char **argv)
 
 	/* args */
 	int opt;
-	char bind[128];
+	char addr[128];
 	char *port = NULL;
 
-#ifdef HAVE_LUA
+#if defined(HAVE_LUA) || defined(HAVE_TLS) || defined(HAVE_UBUS)
 	/* library handle */
 	void *lib;
 #endif
 
-	FD_ZERO(&serv_fds);
-
 	/* handle SIGPIPE, SIGINT, SIGTERM */
 	sa.sa_flags = 0;
 	sigemptyset(&sa.sa_mask);
@@ -835,7 +820,6 @@ int main (int argc, char **argv)
 
 	/* parse args */
 	memset(&conf, 0, sizeof(conf));
-	memset(bind, 0, sizeof(bind));
 
 	uloop_init();
 
@@ -847,14 +831,16 @@ int main (int argc, char **argv)
 			/* [addr:]port */
 			case 'p':
 			case 's':
+				memset(addr, 0, sizeof(addr));
+
 				if ((port = strrchr(optarg, ':')) != NULL)
 				{
 					if ((optarg[0] == '[') && (port > optarg) && (port[-1] == ']'))
-						memcpy(bind, optarg + 1,
-							min(sizeof(bind), (int)(port - optarg) - 2));
+						memcpy(addr, optarg + 1,
+							min(sizeof(addr), (int)(port - optarg) - 2));
 					else
-						memcpy(bind, optarg,
-							min(sizeof(bind), (int)(port - optarg)));
+						memcpy(addr, optarg,
+							min(sizeof(addr), (int)(port - optarg)));
 
 					port++;
 				}
@@ -880,11 +866,8 @@ int main (int argc, char **argv)
 #endif
 
 				/* bind sockets */
-				bound += uh_socket_bind(&serv_fds, &max_fd,
-										bind[0] ? bind : NULL,
-										port, &hints, (opt == 's'), &conf);
-
-				memset(bind, 0, sizeof(bind));
+				bound += uh_socket_bind(addr[0] ? addr : NULL, port, &hints,
+				                        (opt == 's'), &conf);
 				break;
 
 #ifdef HAVE_TLS
@@ -919,6 +902,13 @@ int main (int argc, char **argv)
 				}
 
 				break;
+#else
+			case 'C':
+			case 'K':
+				fprintf(stderr,
+				        "Notice: TLS support not compiled, ignoring -%c\n",
+				        opt);
+				break;
 #endif
 
 			/* docroot */
@@ -991,6 +981,13 @@ int main (int argc, char **argv)
 					exit(1);
 				}
 				break;
+#else
+			case 'x':
+			case 'i':
+				fprintf(stderr,
+				        "Notice: CGI support not compiled, ignoring -%c\n",
+				        opt);
+				break;
 #endif
 
 #ifdef HAVE_LUA
@@ -1003,6 +1000,13 @@ int main (int argc, char **argv)
 			case 'L':
 				conf.lua_handler = optarg;
 				break;
+#else
+			case 'l':
+			case 'L':
+				fprintf(stderr,
+				        "Notice: Lua support not compiled, ignoring -%c\n",
+				        opt);
+				break;
 #endif
 
 #ifdef HAVE_UBUS
@@ -1015,6 +1019,13 @@ int main (int argc, char **argv)
 			case 'U':
 				conf.ubus_socket = optarg;
 				break;
+#else
+			case 'u':
+			case 'U':
+				fprintf(stderr,
+				        "Notice: UBUS support not compiled, ignoring -%c\n",
+				        opt);
+				break;
 #endif
 
 #if defined(HAVE_CGI) || defined(HAVE_LUA)
diff --git a/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h
index fe86b01d402f247ab54d09d7bcb9689bd892593a..f6982db32332bffd78cb8bf1ef07b257e0c76d85 100644
--- a/package/uhttpd/src/uhttpd.h
+++ b/package/uhttpd/src/uhttpd.h
@@ -63,15 +63,8 @@
 
 #define UH_LIMIT_MSGHEAD	4096
 #define UH_LIMIT_HEADERS	64
-
 #define UH_LIMIT_CLIENTS	64
 
-#define UH_HTTP_MSG_GET		0
-#define UH_HTTP_MSG_HEAD	1
-#define UH_HTTP_MSG_POST	2
-
-#define UH_SOCK_CLIENT		0
-#define UH_SOCK_SERVER		1
 
 struct listener;
 struct client;
@@ -128,9 +121,25 @@ struct config {
 #endif
 };
 
+enum http_method {
+	UH_HTTP_MSG_GET,
+	UH_HTTP_MSG_POST,
+	UH_HTTP_MSG_HEAD,
+};
+
+extern const char *http_methods[];
+
+enum http_version {
+	UH_HTTP_VER_0_9,
+	UH_HTTP_VER_1_0,
+	UH_HTTP_VER_1_1,
+};
+
+extern const char *http_versions[];
+
 struct http_request {
-	int	method;
-	float version;
+	enum http_method method;
+	enum http_version version;
 	int redirect_status;
 	char *url;
 	char *headers[UH_LIMIT_HEADERS];
@@ -167,7 +176,6 @@ struct client {
 	bool (*cb)(struct client *);
 	void *priv;
 	bool dispatched;
-	bool dead;
 	struct {
 		char buf[UH_LIMIT_MSGHEAD];
 		char *ptr;