X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/2540dbba3ba74ff9a4c81890397f3db069b27968..ddc9278d09957a5c6cb27ad0ca696f096476e38a:/package/uhttpd/src/uhttpd.c diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c index 6406e459a..1fd21344f 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,8 @@ static int uh_socket_bind( int status; int bound = 0; + int tcp_ka_idl, tcp_ka_int, tcp_ka_cnt; + struct listener *l = NULL; struct addrinfo *addrs = NULL, *p = NULL; @@ -145,12 +148,29 @@ 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( conf->tcp_keepalive > 0 ) + { + tcp_ka_idl = 1; + tcp_ka_cnt = 3; + tcp_ka_int = conf->tcp_keepalive; + + 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 ) { @@ -324,8 +344,8 @@ static struct http_request * uh_http_header_parse(struct client *cl, char *buffe hdrdata = &buffer[i+2]; } - /* have no name and found [A-Z], start of name */ - else if( !hdrname && isalpha(buffer[i]) && isupper(buffer[i]) ) + /* have no name and found [A-Za-z], start of name */ + else if( !hdrname && isalpha(buffer[i]) ) { hdrname = &buffer[i]; } @@ -355,7 +375,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 +390,41 @@ 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)); + + /* unexpected eof - #7904 */ + if( rlen == 0 ) + return NULL; + + 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; } @@ -552,7 +571,7 @@ static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd) if( (pin = uh_path_lookup(cl, req->url)) != NULL ) { /* auth ok? */ - if( uh_auth_check(cl, req, pin) ) + if( !pin->redirected && uh_auth_check(cl, req, pin) ) uh_dispatch_request(cl, req, pin); } @@ -605,7 +624,7 @@ static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd) int main (int argc, char **argv) { /* master file descriptor list */ - fd_set used_fds, serv_fds, read_fds; + fd_set serv_fds; /* working structs */ struct addrinfo hints; @@ -636,10 +655,7 @@ int main (int argc, char **argv) void *lib; #endif - /* clear the master and temp sets */ - FD_ZERO(&used_fds); FD_ZERO(&serv_fds); - FD_ZERO(&read_fds); /* handle SIGPIPE, SIGINT, SIGTERM, SIGCHLD */ sa.sa_flags = 0; @@ -708,7 +724,7 @@ int main (int argc, char **argv) #endif while( (opt = getopt(argc, argv, - "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:i:t:T:")) > 0 + "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:i:t:T:A:")) > 0 ) { switch(opt) { @@ -882,6 +898,11 @@ int main (int argc, char **argv) conf.network_timeout = atoi(optarg); break; + /* tcp keep-alive */ + case 'A': + conf.tcp_keepalive = atoi(optarg); + break; + /* no fork */ case 'f': nofork = 1; @@ -1075,4 +1096,3 @@ int main (int argc, char **argv) return 0; } -