diff options
| author | jow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-07-09 00:08:20 +0000 | 
|---|---|---|
| committer | jow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-07-09 00:08:20 +0000 | 
| commit | 84032b177b6535804ac879c6b52a1775cdd8edc3 (patch) | |
| tree | da2e14323f1d514e1544c32b8c912cafb8c51259 /package/uhttpd/src | |
| parent | d0cba1ebd3392288d01e694c00f0fd989ae3743f (diff) | |
[package] uhttpd: various fixes
    - avoid closing descriptors before removing them from uloop (#11755, #11830)
    - do not auto-initialize ubus if no prefix is set (#11832)
    - remove extraneous client context pointer from cgi and lua states
    - code cleanups and debug message changes
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32651 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/uhttpd/src')
| -rw-r--r-- | package/uhttpd/src/uhttpd-cgi.c | 83 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-cgi.h | 3 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-lua.c | 55 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-lua.h | 3 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-utils.c | 62 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-utils.h | 6 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd.c | 78 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd.h | 3 | 
8 files changed, 152 insertions, 141 deletions
| diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c index aa7947811..e52792262 100644 --- a/package/uhttpd/src/uhttpd-cgi.c +++ b/package/uhttpd/src/uhttpd-cgi.c @@ -128,8 +128,6 @@ static char * uh_cgi_header_lookup(struct http_response *res,  static void uh_cgi_shutdown(struct uh_cgi_state *state)  { -	close(state->rfd); -	close(state->wfd);  	free(state);  } @@ -139,38 +137,36 @@ static bool uh_cgi_socket_cb(struct client *cl)  	char buf[UH_LIMIT_MSGHEAD];  	struct uh_cgi_state *state = (struct uh_cgi_state *)cl->priv; -	struct http_response *res = &state->cl->response; -	struct http_request *req = &state->cl->request; +	struct http_response *res = &cl->response; +	struct http_request *req = &cl->request;  	/* there is unread post data waiting */  	while (state->content_length > 0)  	{  		/* remaining data in http head buffer ... */ -		if (state->cl->httpbuf.len > 0) +		if (cl->httpbuf.len > 0)  		{ -			len = min(state->content_length, state->cl->httpbuf.len); +			len = min(state->content_length, cl->httpbuf.len); -			D("CGI: Child(%d) feed %d HTTP buffer bytes\n", -			  state->cl->proc.pid, len); +			D("CGI: Child(%d) feed %d HTTP buffer bytes\n", cl->proc.pid, len); -			memcpy(buf, state->cl->httpbuf.ptr, len); +			memcpy(buf, cl->httpbuf.ptr, len); -			state->cl->httpbuf.len -= len; -			state->cl->httpbuf.ptr +=len; +			cl->httpbuf.len -= len; +			cl->httpbuf.ptr +=len;  		}  		/* read it from socket ... */  		else  		{ -			len = uh_tcp_recv(state->cl, buf, +			len = uh_tcp_recv(cl, buf,  							  min(state->content_length, sizeof(buf)));  			if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))  				break;  			D("CGI: Child(%d) feed %d/%d TCP socket bytes\n", -			  state->cl->proc.pid, len, -			  min(state->content_length, sizeof(buf))); +			  cl->proc.pid, len, min(state->content_length, sizeof(buf)));  		}  		if (len) @@ -179,16 +175,16 @@ static bool uh_cgi_socket_cb(struct client *cl)  			state->content_length = 0;  		/* ... write to CGI process */ -		len = uh_raw_send(state->wfd, buf, len, +		len = uh_raw_send(cl->wpipe.fd, buf, len,  						  cl->server->conf->script_timeout);  		/* explicit EOF notification for the child */  		if (state->content_length <= 0) -			close(state->wfd); +			uh_ufd_remove(&cl->wpipe);  	}  	/* try to read data from child */ -	while ((len = uh_raw_recv(state->rfd, buf, sizeof(buf), -1)) > 0) +	while ((len = uh_raw_recv(cl->rpipe.fd, buf, sizeof(buf), -1)) > 0)  	{  		/* we have not pushed out headers yet, parse input */  		if (!state->header_sent) @@ -199,7 +195,7 @@ static bool uh_cgi_socket_cb(struct client *cl)  			if (uh_cgi_header_parse(res, state->httpbuf, len, &hdroff))  			{  				/* write status */ -				ensure_out(uh_http_sendf(state->cl, NULL, +				ensure_out(uh_http_sendf(cl, NULL,  					"HTTP/%.1f %03d %s\r\n"  					"Connection: close\r\n",  					req->version, res->statuscode, res->statusmsg)); @@ -208,7 +204,7 @@ static bool uh_cgi_socket_cb(struct client *cl)  				if (!uh_cgi_header_lookup(res, "Location") &&  					!uh_cgi_header_lookup(res, "Content-Type"))  				{ -					ensure_out(uh_http_send(state->cl, NULL, +					ensure_out(uh_http_send(cl, NULL,  						"Content-Type: text/plain\r\n", -1));  				} @@ -216,19 +212,19 @@ static bool uh_cgi_socket_cb(struct client *cl)  				if ((req->version > 1.0) &&  					!uh_cgi_header_lookup(res, "Transfer-Encoding"))  				{ -					ensure_out(uh_http_send(state->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_out(uh_http_sendf(state->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_out(uh_http_send(state->cl, NULL, "\r\n", -1)); +				ensure_out(uh_http_send(cl, NULL, "\r\n", -1));  				state->header_sent = true; @@ -236,9 +232,9 @@ static bool uh_cgi_socket_cb(struct client *cl)  				if (hdroff < len)  				{  					D("CGI: Child(%d) relaying %d rest bytes\n", -					  state->cl->proc.pid, len - hdroff); +					  cl->proc.pid, len - hdroff); -					ensure_out(uh_http_send(state->cl, req, +					ensure_out(uh_http_send(cl, req,  											&buf[hdroff], len - hdroff));  				}  			} @@ -257,7 +253,7 @@ static bool uh_cgi_socket_cb(struct client *cl)  				 * build the required headers here.  				 */ -				ensure_out(uh_http_sendf(state->cl, NULL, +				ensure_out(uh_http_sendf(cl, NULL,  										 "HTTP/%.1f 200 OK\r\n"  										 "Content-Type: text/plain\r\n"  										 "%s\r\n", @@ -268,18 +264,16 @@ static bool uh_cgi_socket_cb(struct client *cl)  				state->header_sent = true;  				D("CGI: Child(%d) relaying %d invalid bytes\n", -				  state->cl->proc.pid, len); +				  cl->proc.pid, len); -				ensure_out(uh_http_send(state->cl, req, buf, len)); +				ensure_out(uh_http_send(cl, req, buf, len));  			}  		}  		else  		{  			/* headers complete, pass through buffer to socket */ -			D("CGI: Child(%d) relaying %d normal bytes\n", -			  state->cl->proc.pid, len); - -			ensure_out(uh_http_send(state->cl, req, buf, len)); +			D("CGI: Child(%d) relaying %d normal bytes\n", cl->proc.pid, len); +			ensure_out(uh_http_send(cl, req, buf, len));  		}  	} @@ -287,8 +281,7 @@ static bool uh_cgi_socket_cb(struct client *cl)  	if ((len == 0) ||  		((errno != EAGAIN) && (errno != EWOULDBLOCK) && (len == -1)))  	{ -		D("CGI: Child(%d) presumed dead [%s]\n", -		  state->cl->proc.pid, strerror(errno)); +		D("CGI: Child(%d) presumed dead [%s]\n", cl->proc.pid, strerror(errno));  		goto out;  	} @@ -298,17 +291,17 @@ static bool uh_cgi_socket_cb(struct client *cl)  out:  	if (!state->header_sent)  	{ -		if (state->cl->timeout.pending) -			uh_http_sendhf(state->cl, 502, "Bad Gateway", +		if (cl->timeout.pending) +			uh_http_sendhf(cl, 502, "Bad Gateway",  						   "The CGI process did not produce any response\n");  		else -			uh_http_sendhf(state->cl, 504, "Gateway Timeout", +			uh_http_sendhf(cl, 504, "Gateway Timeout",  						   "The CGI process took too long to produce a "  						   "response\n");  	}  	else  	{ -		uh_http_send(state->cl, req, "", 0); +		uh_http_send(cl, req, "", 0);  	}  	uh_cgi_shutdown(state); @@ -529,9 +522,13 @@ bool uh_cgi_request(struct client *cl, struct path_info *pi,  	default:  		memset(state, 0, sizeof(*state)); -		state->cl = cl; -		state->cl->pipe.fd = rfd[0]; -		state->cl->proc.pid = child; +		cl->rpipe.fd = rfd[0]; +		cl->wpipe.fd = wfd[1]; +		cl->proc.pid = child; + +		/* make pipe non-blocking */ +		fd_nonblock(cl->rpipe.fd); +		fd_nonblock(cl->wpipe.fd);  		/* close unneeded pipe ends */  		close(rfd[1]); @@ -554,12 +551,6 @@ bool uh_cgi_request(struct client *cl, struct path_info *pi,  			}  		} -		state->rfd = rfd[0]; -		fd_nonblock(state->rfd); - -		state->wfd = wfd[1]; -		fd_nonblock(state->wfd); -  		cl->cb = uh_cgi_socket_cb;  		cl->priv = state; diff --git a/package/uhttpd/src/uhttpd-cgi.h b/package/uhttpd/src/uhttpd-cgi.h index 18816bae1..fffcc5d35 100644 --- a/package/uhttpd/src/uhttpd-cgi.h +++ b/package/uhttpd/src/uhttpd-cgi.h @@ -28,9 +28,6 @@  struct uh_cgi_state { -	int rfd; -	int wfd; -	struct client *cl;  	char httpbuf[UH_LIMIT_MSGHEAD];  	int content_length;  	bool header_sent; diff --git a/package/uhttpd/src/uhttpd-lua.c b/package/uhttpd/src/uhttpd-lua.c index 10d6de402..94626bb56 100644 --- a/package/uhttpd/src/uhttpd-lua.c +++ b/package/uhttpd/src/uhttpd-lua.c @@ -250,8 +250,6 @@ lua_State * uh_lua_init(const struct config *conf)  static void uh_lua_shutdown(struct uh_lua_state *state)  { -	close(state->rfd); -	close(state->wfd);  	free(state);  } @@ -266,31 +264,28 @@ static bool uh_lua_socket_cb(struct client *cl)  	while (state->content_length > 0)  	{  		/* remaining data in http head buffer ... */ -		if (state->cl->httpbuf.len > 0) +		if (cl->httpbuf.len > 0)  		{ -			len = min(state->content_length, state->cl->httpbuf.len); +			len = min(state->content_length, cl->httpbuf.len); -			D("Lua: Child(%d) feed %d HTTP buffer bytes\n", -			  state->cl->proc.pid, len); +			D("Lua: Child(%d) feed %d HTTP buffer bytes\n", cl->proc.pid, len); -			memcpy(buf, state->cl->httpbuf.ptr, len); +			memcpy(buf, cl->httpbuf.ptr, len); -			state->cl->httpbuf.len -= len; -			state->cl->httpbuf.ptr += len; +			cl->httpbuf.len -= len; +			cl->httpbuf.ptr += len;  		}  		/* read it from socket ... */  		else  		{ -			len = uh_tcp_recv(state->cl, buf, -							  min(state->content_length, sizeof(buf))); +			len = uh_tcp_recv(cl, buf, min(state->content_length, sizeof(buf)));  			if ((len < 0) && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))  				break;  			D("Lua: Child(%d) feed %d/%d TCP socket bytes\n", -			  state->cl->proc.pid, len, -			  min(state->content_length, sizeof(buf))); +			  cl->proc.pid, len, min(state->content_length, sizeof(buf)));  		}  		if (len) @@ -299,20 +294,20 @@ static bool uh_lua_socket_cb(struct client *cl)  			state->content_length = 0;  		/* ... write to Lua process */ -		len = uh_raw_send(state->wfd, buf, len, +		len = uh_raw_send(cl->wpipe.fd, buf, len,  						  cl->server->conf->script_timeout);  		/* explicit EOF notification for the child */  		if (state->content_length <= 0) -			close(state->wfd); +			uh_ufd_remove(&cl->wpipe);  	}  	/* try to read data from child */ -	while ((len = uh_raw_recv(state->rfd, buf, sizeof(buf), -1)) > 0) +	while ((len = uh_raw_recv(cl->rpipe.fd, buf, sizeof(buf), -1)) > 0)  	{  		/* pass through buffer to socket */ -		D("Lua: Child(%d) relaying %d normal bytes\n", state->cl->proc.pid, len); -		ensure_out(uh_tcp_send(state->cl, buf, len)); +		D("Lua: Child(%d) relaying %d normal bytes\n", cl->proc.pid, len); +		ensure_out(uh_tcp_send(cl, buf, len));  		state->data_sent = true;  	} @@ -321,7 +316,7 @@ static bool uh_lua_socket_cb(struct client *cl)  		((errno != EAGAIN) && (errno != EWOULDBLOCK) && (len == -1)))  	{  		D("Lua: Child(%d) presumed dead [%s]\n", -		  state->cl->proc.pid, strerror(errno)); +		  cl->proc.pid, strerror(errno));  		goto out;  	} @@ -331,11 +326,11 @@ static bool uh_lua_socket_cb(struct client *cl)  out:  	if (!state->data_sent)  	{ -		if (state->cl->timeout.pending) -			uh_http_sendhf(state->cl, 502, "Bad Gateway", +		if (cl->timeout.pending) +			uh_http_sendhf(cl, 502, "Bad Gateway",  						   "The Lua process did not produce any response\n");  		else -			uh_http_sendhf(state->cl, 504, "Gateway Timeout", +			uh_http_sendhf(cl, 504, "Gateway Timeout",  						   "The Lua process took too long to produce a "  						   "response\n");  	} @@ -557,9 +552,13 @@ bool uh_lua_request(struct client *cl, lua_State *L)  	default:  		memset(state, 0, sizeof(*state)); -		state->cl = cl; -		state->cl->pipe.fd = rfd[0]; -		state->cl->proc.pid = child; +		cl->rpipe.fd = rfd[0]; +		cl->wpipe.fd = wfd[1]; +		cl->proc.pid = child; + +		/* make pipe non-blocking */ +		fd_nonblock(cl->rpipe.fd); +		fd_nonblock(cl->wpipe.fd);  		/* close unneeded pipe ends */  		close(rfd[1]); @@ -582,12 +581,6 @@ bool uh_lua_request(struct client *cl, lua_State *L)  			}  		} -		state->rfd = rfd[0]; -		fd_nonblock(state->rfd); - -		state->wfd = wfd[1]; -		fd_nonblock(state->wfd); -  		cl->cb = uh_lua_socket_cb;  		cl->priv = state; diff --git a/package/uhttpd/src/uhttpd-lua.h b/package/uhttpd/src/uhttpd-lua.h index 9a10933fc..ae573a3ce 100644 --- a/package/uhttpd/src/uhttpd-lua.h +++ b/package/uhttpd/src/uhttpd-lua.h @@ -33,9 +33,6 @@  struct uh_lua_state { -	int rfd; -	int wfd; -	struct client *cl;  	char httpbuf[UH_LIMIT_MSGHEAD];  	int content_length;  	bool data_sent; diff --git a/package/uhttpd/src/uhttpd-utils.c b/package/uhttpd/src/uhttpd-utils.c index d31f756d1..50b10e605 100644 --- a/package/uhttpd/src/uhttpd-utils.c +++ b/package/uhttpd/src/uhttpd-utils.c @@ -119,7 +119,7 @@ bool uh_socket_wait(int fd, int sec, bool write)  	while (((rv = select(fd+1, write ? NULL : &fds, write ? &fds : NULL,  						 NULL, &timeout)) < 0) && (errno == EINTR))  	{ -		D("IO: Socket(%d) select interrupted: %s\n", +		D("IO: FD(%d) select interrupted: %s\n",  				fd, strerror(errno));  		continue; @@ -127,7 +127,7 @@ bool uh_socket_wait(int fd, int sec, bool write)  	if (rv <= 0)  	{ -		D("IO: Socket(%d) appears dead (rv=%d)\n", fd, rv); +		D("IO: FD(%d) appears dead (rv=%d)\n", fd, rv);  		return false;  	} @@ -146,7 +146,7 @@ static int __uh_raw_send(struct client *cl, const char *buf, int len, int sec,  		{  			if (errno == EINTR)  			{ -				D("IO: Socket(%d) interrupted\n", cl->fd.fd); +				D("IO: FD(%d) interrupted\n", cl->fd.fd);  				continue;  			}  			else if ((sec > 0) && (errno == EAGAIN || errno == EWOULDBLOCK)) @@ -156,7 +156,7 @@ static int __uh_raw_send(struct client *cl, const char *buf, int len, int sec,  			}  			else  			{ -				D("IO: Socket(%d) write error: %s\n", fd, strerror(errno)); +				D("IO: FD(%d) write error: %s\n", fd, strerror(errno));  				return -1;  			}  		} @@ -168,19 +168,19 @@ static int __uh_raw_send(struct client *cl, const char *buf, int len, int sec,  		 */  		else if (rv == 0)  		{ -			D("IO: Socket(%d) closed\n", fd); +			D("IO: FD(%d) appears closed\n", fd);  			return 0;  		}  		else if (rv < len)  		{ -			D("IO: Socket(%d) short write %d/%d bytes\n", fd, rv, len); +			D("IO: FD(%d) short write %d/%d bytes\n", fd, rv, len);  			len -= rv;  			buf += rv;  			continue;  		}  		else  		{ -			D("IO: Socket(%d) sent %d/%d bytes\n", fd, rv, len); +			D("IO: FD(%d) sent %d/%d bytes\n", fd, rv, len);  			return rv;  		}  	} @@ -230,18 +230,18 @@ static int __uh_raw_recv(struct client *cl, char *buf, int len, int sec,  			}  			else  			{ -				D("IO: Socket(%d) read error: %s\n", fd, strerror(errno)); +				D("IO: FD(%d) read error: %s\n", fd, strerror(errno));  				return -1;  			}  		}  		else if (rv == 0)  		{ -			D("IO: Socket(%d) closed\n", fd); +			D("IO: FD(%d) appears closed\n", fd);  			return 0;  		}  		else  		{ -			D("IO: Socket(%d) read %d bytes\n", fd, rv); +			D("IO: FD(%d) read %d bytes\n", fd, rv);  			return rv;  		}  	} @@ -934,6 +934,9 @@ struct client * uh_client_add(int sock, struct listener *serv)  		new->fd.fd  = sock;  		new->server = serv; +		new->rpipe.fd = -1; +		new->wpipe.fd = -1; +  		/* get remote endpoint addr */  		sl = sizeof(struct sockaddr_in6);  		memset(&(new->peeraddr), 0, sl); @@ -948,6 +951,8 @@ struct client * uh_client_add(int sock, struct listener *serv)  		uh_clients = new;  		serv->n_clients++; + +		D("IO: Client(%d) allocated\n", new->fd.fd);  	}  	return new; @@ -996,13 +1001,12 @@ void uh_client_remove(struct client *cl)  			if (cur->proc.pid)  				uloop_process_delete(&cur->proc); -			if (cur->pipe.fd) -				uloop_fd_delete(&cur->pipe); +			D("IO: Client(%d) freeing\n", cur->fd.fd); -			uloop_fd_delete(&cur->fd); -			close(cur->fd.fd); +			uh_ufd_remove(&cur->rpipe); +			uh_ufd_remove(&cur->wpipe); +			uh_ufd_remove(&cur->fd); -			D("IO: Socket(%d) closing\n", cur->fd.fd);  			cur->server->n_clients--;  			free(cur); @@ -1012,6 +1016,34 @@ void uh_client_remove(struct client *cl)  } +void uh_ufd_add(struct uloop_fd *u, uloop_fd_handler h, unsigned int ev) +{ +	if (h != NULL) +	{ +		u->cb = h; +		uloop_fd_add(u, ev); +		D("IO: FD(%d) added to uloop\n", u->fd); +	} +} + +void uh_ufd_remove(struct uloop_fd *u) +{ +	if (u->cb != NULL) +	{ +		uloop_fd_delete(u); +		D("IO: FD(%d) removed from uloop\n", u->fd); +		u->cb = NULL; +	} + +	if (u->fd > -1) +	{ +		close(u->fd); +		D("IO: FD(%d) closed\n", u->fd); +		u->fd = -1; +	} +} + +  #ifdef HAVE_CGI  static struct interpreter *uh_interpreters = NULL; diff --git a/package/uhttpd/src/uhttpd-utils.h b/package/uhttpd/src/uhttpd-utils.h index 797b07def..31047f555 100644 --- a/package/uhttpd/src/uhttpd-utils.h +++ b/package/uhttpd/src/uhttpd-utils.h @@ -23,6 +23,9 @@  #include <pwd.h>  #include <sys/stat.h> +#include <libubox/uloop.h> + +  #ifdef HAVE_SHADOW  #include <shadow.h>  #endif @@ -123,7 +126,8 @@ struct client * uh_client_lookup(int sock);  void uh_client_shutdown(struct client *cl);  void uh_client_remove(struct client *cl); -#define uh_client_gc() uh_client_remove(NULL) +void uh_ufd_add(struct uloop_fd *u, uloop_fd_handler h, unsigned int ev); +void uh_ufd_remove(struct uloop_fd *u);  #ifdef HAVE_CGI diff --git a/package/uhttpd/src/uhttpd.c b/package/uhttpd/src/uhttpd.c index 3237fbab5..9e5a57426 100644 --- a/package/uhttpd/src/uhttpd.c +++ b/package/uhttpd/src/uhttpd.c @@ -218,8 +218,7 @@ static int uh_socket_bind(fd_set *serv_fds, int *max_fd,  		fd_cloexec(sock);  		*max_fd = max(*max_fd, sock); -		l->fd.cb = uh_listener_cb; -		uloop_fd_add(&l->fd, ULOOP_READ); +		uh_ufd_add(&l->fd, uh_listener_cb, ULOOP_READ);  		bound++;  		continue; @@ -514,7 +513,7 @@ static bool uh_dispatch_request(struct client *cl, struct http_request *req)  	return false;  } -static void uh_client_cb(struct uloop_fd *u, unsigned int events); +static void uh_socket_cb(struct uloop_fd *u, unsigned int events);  static void uh_listener_cb(struct uloop_fd *u, unsigned int events)  { @@ -539,7 +538,8 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)  		if ((cl = uh_client_add(new_fd, serv)) != NULL)  		{  			/* add client socket to global fdset */ -			uloop_fd_add(&cl->fd, ULOOP_READ); +			uh_ufd_add(&cl->fd, uh_socket_cb, ULOOP_READ); +			fd_cloexec(cl->fd.fd);  #ifdef HAVE_TLS  			/* setup client tls context */ @@ -555,9 +555,6 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)  				}  			}  #endif - -			cl->fd.cb = uh_client_cb; -			fd_cloexec(new_fd);  		}  		/* insufficient resources */ @@ -569,28 +566,33 @@ static void uh_listener_cb(struct uloop_fd *u, unsigned int events)  	}  } -static void uh_pipe_cb(struct uloop_fd *u, unsigned int events) +static void uh_client_cb(struct client *cl, unsigned int events); + +static void uh_rpipe_cb(struct uloop_fd *u, unsigned int events)  { -	struct client *cl = container_of(u, struct client, pipe); +	struct client *cl = container_of(u, struct client, rpipe); -	if (!u->error) -	{ -		D("SRV: Client(%d) pipe(%d) readable\n", -		  cl->fd.fd, cl->pipe.fd); +	D("SRV: Client(%d) rpipe readable\n", cl->fd.fd); -		uh_client_cb(&cl->fd, ULOOP_WRITE); -	} +	uh_client_cb(cl, ULOOP_WRITE); +} + +static void uh_socket_cb(struct uloop_fd *u, unsigned int events) +{ +	struct client *cl = container_of(u, struct client, fd); + +	D("SRV: Client(%d) socket readable\n", cl->fd.fd); + +	uh_client_cb(cl, ULOOP_READ);  }  static void uh_child_cb(struct uloop_process *p, int rv)  {  	struct client *cl = container_of(p, struct client, proc); -	D("SRV: Client(%d) child(%d) is dead\n", cl->fd.fd, cl->proc.pid); +	D("SRV: Client(%d) child(%d) dead\n", cl->fd.fd, cl->proc.pid); -	cl->dead = true; -	cl->fd.eof = true; -	uh_client_cb(&cl->fd, ULOOP_READ | ULOOP_WRITE); +	uh_client_cb(cl, ULOOP_READ | ULOOP_WRITE);  }  static void uh_kill9_cb(struct uloop_timeout *t) @@ -624,17 +626,15 @@ static void uh_timeout_cb(struct uloop_timeout *t)  	}  } -static void uh_client_cb(struct uloop_fd *u, unsigned int events) +static void uh_client_cb(struct client *cl, unsigned int events)  {  	int i; -	struct client *cl;  	struct config *conf;  	struct http_request *req; -	cl = container_of(u, struct client, fd);  	conf = cl->server->conf; -	D("SRV: Client(%d) enter callback\n", u->fd); +	D("SRV: Client(%d) enter callback\n", cl->fd.fd);  	/* undispatched yet */  	if (!cl->dispatched) @@ -642,14 +642,14 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)  		/* we have no headers yet and this was a write event, ignore... */  		if (!(events & ULOOP_READ))  		{ -			D("SRV: Client(%d) ignoring write event before headers\n", u->fd); +			D("SRV: Client(%d) ignoring write event before headers\n", cl->fd.fd);  			return;  		}  		/* attempt to receive and parse headers */  		if (!(req = uh_http_header_recv(cl)))  		{ -			D("SRV: Client(%d) failed to receive header\n", u->fd); +			D("SRV: Client(%d) failed to receive header\n", cl->fd.fd);  			uh_client_shutdown(cl);  			return;  		} @@ -663,7 +663,7 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)  			if (strcasecmp(req->headers[i+1], "100-continue"))  			{  				D("SRV: Client(%d) unknown expect header (%s)\n", -				  u->fd, req->headers[i+1]); +				  cl->fd.fd, req->headers[i+1]);  				uh_http_response(cl, 417, "Precondition Failed");  				uh_client_shutdown(cl); @@ -671,7 +671,7 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)  			}  			else  			{ -				D("SRV: Client(%d) sending HTTP/1.1 100 Continue\n", u->fd); +				D("SRV: Client(%d) sending HTTP/1.1 100 Continue\n", cl->fd.fd);  				uh_http_sendf(cl, NULL, "HTTP/1.1 100 Continue\r\n\r\n");  				cl->httpbuf.len = 0; /* client will re-send the body */ @@ -694,24 +694,23 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)  		/* dispatch request */  		if (!uh_dispatch_request(cl, req))  		{ -			D("SRV: Client(%d) failed to dispach request\n", u->fd); +			D("SRV: Client(%d) failed to dispach request\n", cl->fd.fd);  			uh_client_shutdown(cl);  			return;  		}  		/* request handler spawned a pipe, register handler */ -		if (cl->pipe.fd) +		if (cl->rpipe.fd > -1)  		{ -			D("SRV: Client(%d) pipe(%d) spawned\n", u->fd, cl->pipe.fd); +			D("SRV: Client(%d) pipe(%d) spawned\n", cl->fd.fd, cl->rpipe.fd); -			cl->pipe.cb = uh_pipe_cb; -			uloop_fd_add(&cl->pipe, ULOOP_READ); +			uh_ufd_add(&cl->rpipe, uh_rpipe_cb, ULOOP_READ);  		}  		/* request handler spawned a child, register handler */  		if (cl->proc.pid)  		{ -			D("SRV: Client(%d) child(%d) spawned\n", u->fd, cl->proc.pid); +			D("SRV: Client(%d) child(%d) spawned\n", cl->fd.fd, cl->proc.pid);  			cl->proc.cb = uh_child_cb;  			uloop_process_add(&cl->proc); @@ -721,13 +720,13 @@ static void uh_client_cb(struct uloop_fd *u, unsigned int events)  		}  		/* header processing complete */ -		D("SRV: Client(%d) dispatched\n", u->fd); +		D("SRV: Client(%d) dispatched\n", cl->fd.fd);  		cl->dispatched = true;  	}  	if (!cl->cb(cl))  	{ -		D("SRV: Client(%d) response callback signalized EOF\n", u->fd); +		D("SRV: Client(%d) response callback signalized EOF\n", cl->fd.fd);  		uh_client_shutdown(cl);  		return;  	} @@ -1098,7 +1097,7 @@ int main (int argc, char **argv)  					"	-L file         Lua handler script, omit to disable Lua\n"  #endif  #ifdef HAVE_UBUS -					"	-u string       URL prefix for HTTP/JSON handler, default is '/ubus'\n" +					"	-u string       URL prefix for HTTP/JSON handler\n"  					"	-U file         Override ubus socket path\n"  #endif  #ifdef HAVE_CGI @@ -1210,7 +1209,7 @@ int main (int argc, char **argv)  				"Notice: Unable to load ubus plugin - disabling ubus support! "  				"(Reason: %s)\n", dlerror());  	} -	else +	else if (conf.ubus_prefix)  	{  		/* resolve functions */  		if (!(conf.ubus_init    = dlsym(lib, "uh_ubus_init"))    || @@ -1224,10 +1223,7 @@ int main (int argc, char **argv)  			exit(1);  		} -		/* default ubus prefix */ -		if (!conf.ubus_prefix) -			conf.ubus_prefix = "/ubus"; - +		/* initialize ubus */  		conf.ubus_state = conf.ubus_init(&conf);  	}  #endif diff --git a/package/uhttpd/src/uhttpd.h b/package/uhttpd/src/uhttpd.h index 69fe21a41..fe86b01d4 100644 --- a/package/uhttpd/src/uhttpd.h +++ b/package/uhttpd/src/uhttpd.h @@ -160,7 +160,8 @@ struct client {  	SSL *tls;  #endif  	struct uloop_fd fd; -	struct uloop_fd pipe; +	struct uloop_fd rpipe; +	struct uloop_fd wpipe;  	struct uloop_process proc;  	struct uloop_timeout timeout;  	bool (*cb)(struct client *); | 
