summaryrefslogtreecommitdiff
path: root/uhttpd.c
diff options
context:
space:
mode:
authorjow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73>2010-08-18 00:04:52 +0000
committerjow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73>2010-08-18 00:04:52 +0000
commita393073c9c8a8ad765a3d4ae4483677792152d3a (patch)
tree8a3f0e06d17073f400da47c8955a979558454edd /uhttpd.c
parent0bf05c0c6b9df2c91bdd6e51780e564568a5a282 (diff)
downloaduhttpd-a393073c9c8a8ad765a3d4ae4483677792152d3a.tar.gz
[package] uhttpd:
- fix parsing of interpreter entries in the config file, fixes serving of static files as .cgi with X-Wrt - better cope with connection aborts, especially during header transfer - fix return value checking of TLS reads and writes, solves some blocking issues git-svn-id: svn://svn.openwrt.org/openwrt/trunk/package/uhttpd/src@22692 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'uhttpd.c')
-rw-r--r--uhttpd.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/uhttpd.c b/uhttpd.c
index 6406e45..6f5e616 100644
--- a/uhttpd.c
+++ b/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;
}