diff --git a/package/uhttpd/Makefile b/package/uhttpd/Makefile
index de9eee9e9fbd28040a61d675c0f89a44a3c8d478..1227174536a50ab3e3f95e1007b70a409b1c74b0 100644
--- a/package/uhttpd/Makefile
+++ b/package/uhttpd/Makefile
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=uhttpd
-PKG_RELEASE:=15
+PKG_RELEASE:=16
 
 PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
 PKG_BUILD_DEPENDS := libcyassl liblua
diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c
index f9dd9810daa737d84b1af665f75cdf1774377ec2..8c17251b317b56de857e0854b69167b5ec3f15fc 100644
--- a/package/uhttpd/src/uhttpd-cgi.c
+++ b/package/uhttpd/src/uhttpd-cgi.c
@@ -139,7 +139,7 @@ void uh_cgi_request(
 	struct client *cl, struct http_request *req,
 	struct path_info *pi, struct interpreter *ip
 ) {
-	int i, hdroff, bufoff;
+	int i, hdroff, bufoff, rv;
 	int hdrlen = 0;
 	int buflen = 0;
 	int fd_max = 0;
@@ -376,12 +376,6 @@ void uh_cgi_request(
 
 			memset(hdr, 0, sizeof(hdr));
 
-			timeout.tv_sec = cl->server->conf->script_timeout;
-			timeout.tv_usec = 0;
-
-#define ensure(x) \
-	do { if( x < 0 ) goto out; } while(0)
-
 			/* I/O loop, watch our pipe ends and dispatch child reads/writes from/to socket */
 			while( 1 )
 			{
@@ -391,11 +385,21 @@ void uh_cgi_request(
 				FD_SET(rfd[0], &reader);
 				FD_SET(wfd[1], &writer);
 
+				timeout.tv_sec = (header_sent < 1) ? cl->server->conf->script_timeout : 3;
+				timeout.tv_usec = 0;
+
+				ensure_out(rv = select_intr(fd_max, &reader,
+					(content_length > -1) ? &writer : NULL, NULL, &timeout));
+
+				/* timeout */
+				if( rv == 0 )
+				{
+					ensure_out(kill(child, 0));
+				}
+
 				/* wait until we can read or write or both */
-				if( select_intr(fd_max, &reader,
-					(content_length > -1) ? &writer : NULL, NULL,
-					(header_sent < 1) ? &timeout : NULL) > 0
-				) {
+				else if( rv > 0 )
+				{
 					/* ready to write to cgi program */
 					if( FD_ISSET(wfd[1], &writer) )
 					{
@@ -403,7 +407,10 @@ void uh_cgi_request(
 						if( content_length > 0 )
 						{
 							/* read it from socket ... */
-							if( (buflen = uh_tcp_recv(cl, buf, min(content_length, sizeof(buf)))) > 0 )
+							ensure_out(buflen = uh_tcp_recv(cl, buf,
+								min(content_length, sizeof(buf))));
+
+							if( buflen > 0 )
 							{
 								/* ... and write it to child's stdin */
 								if( write(wfd[1], buf, buflen) < 0 )
@@ -456,7 +463,7 @@ void uh_cgi_request(
 								if( (res = uh_cgi_header_parse(hdr, hdrlen, &hdroff)) != NULL )
 								{
 									/* write status */
-									ensure(uh_http_sendf(cl, NULL,
+									ensure_out(uh_http_sendf(cl, NULL,
 										"HTTP/%.1f %03d %s\r\n"
 										"Connection: close\r\n",
 										req->version, res->statuscode,
@@ -466,7 +473,7 @@ void uh_cgi_request(
 									if( !uh_cgi_header_lookup(res, "Location") &&
 									    !uh_cgi_header_lookup(res, "Content-Type")
 									) {
-										ensure(uh_http_send(cl, NULL,
+										ensure_out(uh_http_send(cl, NULL,
 											"Content-Type: text/plain\r\n", -1));
 									}
 
@@ -474,32 +481,32 @@ void uh_cgi_request(
 									if( (req->version > 1.0) &&
 									    !uh_cgi_header_lookup(res, "Transfer-Encoding")
 									) {
-										ensure(uh_http_send(cl, NULL,
+										ensure_out(uh_http_send(cl, NULL,
 											"Transfer-Encoding: chunked\r\n", -1));
 									}
 
 									/* write headers from CGI program */
 									foreach_header(i, res->headers)
 									{
-										ensure(uh_http_sendf(cl, NULL, "%s: %s\r\n",
+										ensure_out(uh_http_sendf(cl, NULL, "%s: %s\r\n",
 											res->headers[i], res->headers[i+1]));
 									}
 
 									/* terminate header */
-									ensure(uh_http_send(cl, NULL, "\r\n", -1));
+									ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
 
 									/* push out remaining head buffer */
 									if( hdroff < hdrlen )
-										ensure(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff));
+										ensure_out(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff));
 								}
 
 								/* ... failed and head buffer exceeded */
 								else if( hdrlen >= sizeof(hdr) )
 								{
-									ensure(uh_cgi_error_500(cl, req,
+									ensure_out(uh_cgi_error_500(cl, req,
 										"The CGI program generated an invalid response:\n\n"));
 
-									ensure(uh_http_send(cl, req, hdr, hdrlen));
+									ensure_out(uh_http_send(cl, req, hdr, hdrlen));
 								}
 
 								/* ... failed but free buffer space, try again */
@@ -510,7 +517,7 @@ void uh_cgi_request(
 
 								/* push out remaining read buffer */
 								if( bufoff < buflen )
-									ensure(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff));
+									ensure_out(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff));
 
 								header_sent = 1;
 								continue;
@@ -518,7 +525,7 @@ void uh_cgi_request(
 
 
 							/* headers complete, pass through buffer to socket */
-							ensure(uh_http_send(cl, req, buf, buflen));
+							ensure_out(uh_http_send(cl, req, buf, buflen));
 						}
 
 						/* looks like eof from child */
@@ -538,7 +545,7 @@ void uh_cgi_request(
 								 * build the required headers here.
 								 */
 
-								ensure(uh_http_sendf(cl, NULL,
+								ensure_out(uh_http_sendf(cl, NULL,
 									"HTTP/%.1f 200 OK\r\n"
 									"Content-Type: text/plain\r\n"
 									"%s\r\n",
@@ -546,11 +553,11 @@ void uh_cgi_request(
 											? "Transfer-Encoding: chunked\r\n" : ""
 								));
 
-								ensure(uh_http_send(cl, req, hdr, hdrlen));
+								ensure_out(uh_http_send(cl, req, hdr, hdrlen));
 							}
 
 							/* send final chunk if we're in chunked transfer mode */
-							ensure(uh_http_send(cl, req, "", 0));
+							ensure_out(uh_http_send(cl, req, "", 0));
 							break;
 						}
 					}
@@ -561,13 +568,13 @@ void uh_cgi_request(
 				{
 					if( (errno != EINTR) && ! header_sent )
 					{
-						ensure(uh_http_sendhf(cl, 504, "Gateway Timeout",
+						ensure_out(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));
+					ensure_out(uh_http_send(cl, req, "", 0));
 
 					break;
 				}
diff --git a/package/uhttpd/src/uhttpd-file.c b/package/uhttpd/src/uhttpd-file.c
index 25a5f6ece3534b0ff2198e350d2fe9c14efc939e..fda86d72631031c7f1884e58590a99a0df3c0c63 100644
--- a/package/uhttpd/src/uhttpd-file.c
+++ b/package/uhttpd/src/uhttpd-file.c
@@ -97,8 +97,6 @@ static char * uh_file_header_lookup(struct http_request *req, const char *name)
 	return NULL;
 }
 
-#define ensure_ret(x) \
-	do { if( x < 0 ) return -1; } while(0)
 
 static int uh_file_response_ok_hdrs(struct client *cl, struct http_request *req, struct stat *s)
 {
@@ -132,7 +130,7 @@ static int uh_file_response_412(struct client *cl, struct http_request *req)
 		"Connection: close\r\n", req->version);
 }
 
-static int uh_file_if_match(struct client *cl, struct http_request *req, struct stat *s)
+static int uh_file_if_match(struct client *cl, struct http_request *req, struct stat *s, int *ok)
 {
 	const char *tag = uh_file_mktag(s);
 	char *hdr = uh_file_header_lookup(req, "If-Match");
@@ -152,43 +150,44 @@ static int uh_file_if_match(struct client *cl, struct http_request *req, struct
 			}
 			else if( !strcmp(p, "*") || !strcmp(p, tag) )
 			{
-				return 1;
+				*ok = 1;
+				return *ok;
 			}
 		}
 
-		uh_file_response_412(cl, req);
-		return 0;
+		*ok = 0;
+		ensure_ret(uh_file_response_412(cl, req));
+		return *ok;
 	}
 
-	return 1;
+	*ok = 1;
+	return *ok;
 }
 
-static int uh_file_if_modified_since(struct client *cl, struct http_request *req, struct stat *s)
+static int uh_file_if_modified_since(struct client *cl, struct http_request *req, struct stat *s, int *ok)
 {
 	char *hdr = uh_file_header_lookup(req, "If-Modified-Since");
+	*ok = 1;
 
 	if( hdr )
 	{
-		if( uh_file_date2unix(hdr) < s->st_mtime )
+		if( uh_file_date2unix(hdr) >= s->st_mtime )
 		{
-			return 1;
-		}
-		else
-		{
-			uh_file_response_304(cl, req, s);
-			return 0;
+			*ok = 0;
+			ensure_ret(uh_file_response_304(cl, req, s));
 		}
 	}
 
-	return 1;
+	return *ok;
 }
 
-static int uh_file_if_none_match(struct client *cl, struct http_request *req, struct stat *s)
+static int uh_file_if_none_match(struct client *cl, struct http_request *req, struct stat *s, int *ok)
 {
 	const char *tag = uh_file_mktag(s);
 	char *hdr = uh_file_header_lookup(req, "If-None-Match");
 	char *p;
 	int i;
+	*ok = 1;
 
 	if( hdr )
 	{
@@ -203,53 +202,54 @@ static int uh_file_if_none_match(struct client *cl, struct http_request *req, st
 			}
 			else if( !strcmp(p, "*") || !strcmp(p, tag) )
 			{
+				*ok = 0;
+
 				if( (req->method == UH_HTTP_MSG_GET) ||
 				    (req->method == UH_HTTP_MSG_HEAD) )
-					uh_file_response_304(cl, req, s);
+					ensure_ret(uh_file_response_304(cl, req, s));
 				else
-					uh_file_response_412(cl, req);
+					ensure_ret(uh_file_response_412(cl, req));
 
-				return 0;
+				break;
 			}
 		}
 	}
 
-	return 1;
+	return *ok;
 }
 
-static int uh_file_if_range(struct client *cl, struct http_request *req, struct stat *s)
+static int uh_file_if_range(struct client *cl, struct http_request *req, struct stat *s, int *ok)
 {
 	char *hdr = uh_file_header_lookup(req, "If-Range");
+	*ok = 1;
 
 	if( hdr )
 	{
-		uh_file_response_412(cl, req);
-		return 0;
+		*ok = 0;
+		ensure_ret(uh_file_response_412(cl, req));
 	}
 
-	return 1;
+	return *ok;
 }
 
-static int uh_file_if_unmodified_since(struct client *cl, struct http_request *req, struct stat *s)
+static int uh_file_if_unmodified_since(struct client *cl, struct http_request *req, struct stat *s, int *ok)
 {
 	char *hdr = uh_file_header_lookup(req, "If-Unmodified-Since");
+	*ok = 1;
 
 	if( hdr )
 	{
 		if( uh_file_date2unix(hdr) <= s->st_mtime )
 		{
-			uh_file_response_412(cl, req);
-			return 0;
+			*ok = 0;
+			ensure_ret(uh_file_response_412(cl, req));
 		}
 	}
 
-	return 1;
+	return *ok;
 }
 
 
-#define ensure_out(x) \
-	do { if( x < 0 ) goto out; } while(0)
-
 static int uh_file_scandir_filter_dir(const struct dirent *e)
 {
 	return strcmp(e->d_name, ".") ? 1 : 0;
@@ -335,6 +335,7 @@ out:
 void uh_file_request(struct client *cl, struct http_request *req, struct path_info *pi)
 {
 	int rlen;
+	int ok = 1;
 	int fd = -1;
 	char buf[UH_LIMIT_MSGHEAD];
 
@@ -342,13 +343,14 @@ void uh_file_request(struct client *cl, struct http_request *req, struct path_in
 	if( (pi->stat.st_mode & S_IFREG) && ((fd = open(pi->phys, O_RDONLY)) > 0) )
 	{
 		/* test preconditions */
-		if(
-			uh_file_if_modified_since(cl, req, &pi->stat)  	&&
-			uh_file_if_match(cl, req, &pi->stat)           	&&
-			uh_file_if_range(cl, req, &pi->stat)           	&&
-			uh_file_if_unmodified_since(cl, req, &pi->stat)	&&
-			uh_file_if_none_match(cl, req, &pi->stat)
-		) {
+		if(ok) ensure_out(uh_file_if_modified_since(cl, req, &pi->stat, &ok));
+		if(ok) ensure_out(uh_file_if_match(cl, req, &pi->stat, &ok));
+		if(ok) ensure_out(uh_file_if_range(cl, req, &pi->stat, &ok));
+		if(ok) ensure_out(uh_file_if_unmodified_since(cl, req, &pi->stat, &ok));
+		if(ok) ensure_out(uh_file_if_none_match(cl, req, &pi->stat, &ok));
+
+		if( ok > 0 )
+		{
 			/* write status */
 			ensure_out(uh_file_response_200(cl, req, &pi->stat));
 
diff --git a/package/uhttpd/src/uhttpd-tls.c b/package/uhttpd/src/uhttpd-tls.c
index 26143ddf7108c0c9f084a6036a1fab18b6bdbd3c..008f8e0df6a7e873a96ec0a3182cad60243155a5 100644
--- a/package/uhttpd/src/uhttpd-tls.c
+++ b/package/uhttpd/src/uhttpd-tls.c
@@ -70,12 +70,14 @@ void uh_tls_client_accept(struct client *c)
 
 int uh_tls_client_recv(struct client *c, void *buf, int len)
 {
-	return SSL_read(c->tls, buf, len);
+	int rv = SSL_read(c->tls, buf, len);
+	return (rv > 0) ? rv : -1;
 }
 
 int uh_tls_client_send(struct client *c, void *buf, int len)
 {
-	return SSL_write(c->tls, buf, len);
+	int rv = SSL_write(c->tls, buf, len);
+	return (rv > 0) ? rv : -1;
 }
 
 void uh_tls_client_close(struct client *c)
diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c
index e68926e9350c075990aeb664b1658594375991db..8a06c930af6d99c748b33f1e30e149904acd1448 100644
--- a/package/uhttpd/src/uhttpd-utils.c
+++ b/package/uhttpd/src/uhttpd-utils.c
@@ -112,6 +112,7 @@ int select_intr(int n, fd_set *r, fd_set *w, fd_set *e, struct timeval *t)
 	/* unblock SIGCHLD */
 	sigemptyset(&ssn);
 	sigaddset(&ssn, SIGCHLD);
+	sigaddset(&ssn, SIGPIPE);
 	sigprocmask(SIG_UNBLOCK, &ssn, &sso);
 
 	rv = select(n, r, w, e, t);
@@ -193,8 +194,6 @@ int uh_tcp_recv(struct client *cl, char *buf, int len)
 	return sz;
 }
 
-#define ensure(x) \
-	do { if( x < 0 ) return -1; } while(0)
 
 int uh_http_sendhf(struct client *cl, int code, const char *summary, const char *fmt, ...)
 {
@@ -211,14 +210,14 @@ int uh_http_sendhf(struct client *cl, int code, const char *summary, const char
 			code, summary
 	);
 
-	ensure(uh_tcp_send(cl, buffer, len));
+	ensure_ret(uh_tcp_send(cl, buffer, len));
 
 	va_start(ap, fmt);
 	len = vsnprintf(buffer, sizeof(buffer), fmt, ap);
 	va_end(ap);
 
-	ensure(uh_http_sendc(cl, buffer, len));
-	ensure(uh_http_sendc(cl, NULL, 0));
+	ensure_ret(uh_http_sendc(cl, buffer, len));
+	ensure_ret(uh_http_sendc(cl, NULL, 0));
 
 	return 0;
 }
@@ -235,13 +234,13 @@ int uh_http_sendc(struct client *cl, const char *data, int len)
 	if( len > 0 )
 	{
 	 	clen = snprintf(chunk, sizeof(chunk), "%X\r\n", len);
-		ensure(uh_tcp_send(cl, chunk, clen));
-		ensure(uh_tcp_send(cl, data, len));
-		ensure(uh_tcp_send(cl, "\r\n", 2));
+		ensure_ret(uh_tcp_send(cl, chunk, clen));
+		ensure_ret(uh_tcp_send(cl, data, len));
+		ensure_ret(uh_tcp_send(cl, "\r\n", 2));
 	}
 	else
 	{
-		ensure(uh_tcp_send(cl, "0\r\n\r\n", 5));
+		ensure_ret(uh_tcp_send(cl, "0\r\n\r\n", 5));
 	}
 
 	return 0;
@@ -259,9 +258,9 @@ int uh_http_sendf(
 	va_end(ap);
 
 	if( (req != NULL) && (req->version > 1.0) )
-		ensure(uh_http_sendc(cl, buffer, len));
+		ensure_ret(uh_http_sendc(cl, buffer, len));
 	else if( len > 0 )
-		ensure(uh_tcp_send(cl, buffer, len));
+		ensure_ret(uh_tcp_send(cl, buffer, len));
 
 	return 0;
 }
@@ -273,9 +272,9 @@ int uh_http_send(
 		len = strlen(buf);
 
 	if( (req != NULL) && (req->version > 1.0) )
-		ensure(uh_http_sendc(cl, buf, len));
+		ensure_ret(uh_http_sendc(cl, buf, len));
 	else if( len > 0 )
-		ensure(uh_tcp_send(cl, buf, len));
+		ensure_ret(uh_tcp_send(cl, buf, len));
 
 	return 0;
 }
@@ -639,7 +638,7 @@ struct auth_realm * uh_auth_add(char *path, char *user, char *pass)
 			) {
 				memcpy(new->pass, pwd->pw_passwd,
 					min(strlen(pwd->pw_passwd), sizeof(new->pass) - 1));
-			}			
+			}
 		}
 
 		/* ordinary pwd */
diff --git a/package/uhttpd/src/uhttpd-utils.h b/package/uhttpd/src/uhttpd-utils.h
index 95535d6fe74ce5138d4ccd60342bd9ce3c2145cc..3514ce1caca730337caf04a926de0f212b5ac01a 100644
--- a/package/uhttpd/src/uhttpd-utils.h
+++ b/package/uhttpd/src/uhttpd-utils.h
@@ -36,6 +36,13 @@
 #define fd_cloexec(fd) \
 	fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC)
 
+#define ensure_out(x) \
+	do { if((x) < 0) goto out; } while(0)
+
+#define ensure_ret(x) \
+	do { if((x) < 0) return -1; } while(0)
+
+
 struct path_info {
 	char *root;
 	char *phys;
diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c
index 6406e459ada1e2b25a28d3f77d2dddacee0e70ae..6f5e616345121205a0a4fb4a93daaaab33108854 100644
--- a/package/uhttpd/src/uhttpd.c
+++ b/package/uhttpd/src/uhttpd.c
@@ -96,17 +96,18 @@ static void uh_config_parse(struct config *conf)
 				conf->error_handler = strdup(col1);
 			}
 #ifdef HAVE_CGI
-			else if( (line[0] == '.') && (strchr(line, ':') != NULL) )
+			else if( (line[0] == '*') && (strchr(line, ':') != NULL) )
 			{
-				if( !(col1 = strchr(line, ':')) || (*col1++ = 0) ||
-				    !(eol = strchr(col1, '\n')) || (*eol++  = 0) )
+				if( !(col1 = strchr(line, '*')) || (*col1++ = 0) ||
+				    !(col2 = strchr(col1, ':')) || (*col2++ = 0) ||
+				    !(eol = strchr(col2, '\n')) || (*eol++  = 0) )
 						continue;
 
-				if( !uh_interpreter_add(line, col1) )
+				if( !uh_interpreter_add(col1, col2) )
 				{
 					fprintf(stderr,
 						"Unable to add interpreter %s for extension %s: "
-						"Out of memory\n", col1, line
+						"Out of memory\n", col2, col1
 					);
 				}
 			}
@@ -126,6 +127,10 @@ static int uh_socket_bind(
 	int status;
 	int bound = 0;
 
+	int tcp_ka_idl = 1;
+	int tcp_ka_int = 1;
+	int tcp_ka_cnt = 3;
+
 	struct listener *l = NULL;
 	struct addrinfo *addrs = NULL, *p = NULL;
 
@@ -145,12 +150,22 @@ static int uh_socket_bind(
 		}
 
 		/* "address already in use" */
-		if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1 )
+		if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) )
 		{
 			perror("setsockopt()");
 			goto error;
 		}
 
+		/* TCP keep-alive */
+		if( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) ||
+		    setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,  &tcp_ka_idl, sizeof(tcp_ka_idl)) ||
+		    setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &tcp_ka_int, sizeof(tcp_ka_int)) ||
+		    setsockopt(sock, SOL_TCP, TCP_KEEPCNT,   &tcp_ka_cnt, sizeof(tcp_ka_cnt)) )
+		{
+		    fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n",
+		    	strerror(errno));
+		}
+
 		/* required to get parallel v4 + v6 working */
 		if( p->ai_family == AF_INET6 )
 		{
@@ -355,7 +370,6 @@ static struct http_request * uh_http_header_recv(struct client *cl)
 	ssize_t blen = sizeof(buffer)-1;
 	ssize_t rlen = 0;
 
-
 	memset(buffer, 0, sizeof(buffer));
 
 	while( blen > 0 )
@@ -371,41 +385,37 @@ static struct http_request * uh_http_header_recv(struct client *cl)
 		if( select(cl->socket + 1, &reader, NULL, NULL, &timeout) > 0 )
 		{
 			/* receive data */
-			rlen = uh_tcp_peek(cl, bufptr, blen);
+			ensure_out(rlen = uh_tcp_peek(cl, bufptr, blen));
 
-			if( rlen > 0 )
+			if( (idxptr = strfind(buffer, sizeof(buffer), "\r\n\r\n", 4)) )
 			{
-				if( (idxptr = strfind(buffer, sizeof(buffer), "\r\n\r\n", 4)) )
-				{
-					blen -= uh_tcp_recv(cl, bufptr, (int)(idxptr - bufptr) + 4);
+				ensure_out(rlen = uh_tcp_recv(cl, bufptr,
+					(int)(idxptr - bufptr) + 4));
 
-					/* header read complete ... */
-					return uh_http_header_parse(cl, buffer, sizeof(buffer) - blen - 1);
-				}
-				else
-				{
-					rlen = uh_tcp_recv(cl, bufptr, rlen);
-					blen -= rlen;
-					bufptr += rlen;
-				}
+				/* header read complete ... */
+				blen -= rlen;
+				return uh_http_header_parse(cl, buffer,
+					sizeof(buffer) - blen - 1);
 			}
 			else
 			{
-				/* invalid request (unexpected eof/timeout) */
-				uh_http_response(cl, 408, "Request Timeout");
-				return NULL;
+				ensure_out(rlen = uh_tcp_recv(cl, bufptr, rlen));
+
+				blen -= rlen;
+				bufptr += rlen;
 			}
 		}
 		else
 		{
 			/* invalid request (unexpected eof/timeout) */
-			uh_http_response(cl, 408, "Request Timeout");
 			return NULL;
 		}
 	}
 
 	/* request entity too large */
 	uh_http_response(cl, 413, "Request Entity Too Large");
+
+out:
 	return NULL;
 }
 
diff --git a/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h
index 78cca7b3b2a0e27689da21294d883d400415d94f..6747b905ff459f7a69ccbc9ec187904b8c226a74 100644
--- a/package/uhttpd/src/uhttpd.h
+++ b/package/uhttpd/src/uhttpd.h
@@ -28,6 +28,7 @@
 #include <sys/select.h>
 #include <sys/wait.h>
 #include <netinet/in.h>
+#include <netinet/tcp.h>
 #include <arpa/inet.h>
 #include <linux/limits.h>
 #include <netdb.h>
@@ -44,6 +45,11 @@
 #include <openssl/ssl.h>
 #endif
 
+/* uClibc... */
+#ifndef SOL_TCP
+#define SOL_TCP	6
+#endif
+
 
 #define UH_LIMIT_MSGHEAD	4096
 #define UH_LIMIT_HEADERS	64