diff options
| author | jow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-07-13 17:10:56 +0000 | 
|---|---|---|
| committer | jow <jow@3c298f89-4303-0410-b956-a3cf2f4a3e73> | 2012-07-13 17:10:56 +0000 | 
| commit | d61356769c07d3cc41bca553da8a0b9924d61fd0 (patch) | |
| tree | a10b65cb7ffda97d2ca25344848cb6952b2b6ad7 /package/uhttpd/src | |
| parent | 4360ecfaa758a40ba38447a897508b1935c6f8c3 (diff) | |
[package] uhttpd: various changes
	- remove unused variables
	- simply ignore command line args which belong to not enabled features
	- resolve peer address at accept() time, should solve (#11850)
	- remove floating point operations where possible
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@32704 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'package/uhttpd/src')
| -rw-r--r-- | package/uhttpd/src/uhttpd-cgi.c | 32 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-file.c | 13 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-lua.c | 35 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-utils.c | 30 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd-utils.h | 4 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd.c | 123 | ||||
| -rw-r--r-- | package/uhttpd/src/uhttpd.h | 28 | 
7 files changed, 126 insertions, 139 deletions
| diff --git a/package/uhttpd/src/uhttpd-cgi.c b/package/uhttpd/src/uhttpd-cgi.c index b46ebf2bd..69af90db4 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 2e5914a3c..0bafc2b38 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 94626bb56..e11393739 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 50b10e605..c8d3bb40f 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 31047f555..9de919194 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 9e5a57426..1efcbf0f5 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 fe86b01d4..f6982db32 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; | 
