diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/ChangeLog.txt | 2 | ||||
-rw-r--r-- | apps/netutils/webserver/Kconfig | 12 | ||||
-rw-r--r-- | apps/netutils/webserver/httpd.c | 65 |
3 files changed, 77 insertions, 2 deletions
diff --git a/apps/ChangeLog.txt b/apps/ChangeLog.txt index ced9250fa..070a78430 100644 --- a/apps/ChangeLog.txt +++ b/apps/ChangeLog.txt @@ -332,4 +332,6 @@ * apps/netutils/uip_listenon.c: Logic in uip_server.c that creates the listening socket was moved to this new file to support re-use. Contributed by Kate. + * apps/netutils/webserver/httpd.c: The option CONFIG_NETUTILS_HTTPD_SINGLETHREAD + can now be used to limit the server to a single thread. From Kate. diff --git a/apps/netutils/webserver/Kconfig b/apps/netutils/webserver/Kconfig index 6afbda4b3..e64fcdb73 100644 --- a/apps/netutils/webserver/Kconfig +++ b/apps/netutils/webserver/Kconfig @@ -13,6 +13,18 @@ config NETUTILS_WEBSERVER if NETUTILS_WEBSERVER +config NETUTILS_HTTPD_SINGLETHREAD + bool "Single Threded" + default n if !DISABLE_PTHREAD + default y if DISABLE_PTHREAD + ---help--- + By default, the uIP web server will create a new, independent thread + for each connection. This can, however, use a lot of stack space + if there are many connections and that can be a problem is RAM is + limited. If this option is selected, then a single thread will + service all HTTP requests. TCP_BACKLOG would be a good idea + in this case. + config NETUTILS_HTTPD_SCRIPT_DISABLE bool "Disable %! scripting" default y if NETUTILS_HTTPD_SENDFILE diff --git a/apps/netutils/webserver/httpd.c b/apps/netutils/webserver/httpd.c index b482b1e03..bb70e34a1 100644 --- a/apps/netutils/webserver/httpd.c +++ b/apps/netutils/webserver/httpd.c @@ -54,10 +54,13 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> -#include <pthread.h> #include <errno.h> #include <debug.h> +#ifndef CONFIG_NETUTILS_HTTPD_SINGLETHREAD +# include <pthread.h> +#endif + #include <nuttx/net/uip/uip.h> #include <apps/netutils/uiplib.h> #include <apps/netutils/httpd.h> @@ -595,6 +598,60 @@ static void *httpd_handler(void *arg) return NULL; } +#ifdef CONFIG_NETUTILS_HTTPD_SINGLETHREAD +static void single_server(uint16_t portno, pthread_startroutine_t handler, int stacksize) +{ + struct sockaddr_in myaddr; + socklen_t addrlen; + int listensd; + int acceptsd; +#ifdef CONFIG_NET_HAVE_SOLINGER + struct linger ling; +#endif + + listensd = uip_listenon(portno); + if (listensd < 0) + { + return ERROR; + } + + /* Begin serving connections */ + + for (;;) + { + addrlen = sizeof(struct sockaddr_in); + acceptsd = accept(listensd, (struct sockaddr*)&myaddr, &addrlen); + + if (acceptsd < 0) + { + ndbg("accept failure: %d\n", errno); + break;; + } + + nvdbg("Connection accepted -- serving sd=%d\n", acceptsd); + + /* Configure to "linger" until all data is sent when the socket is closed */ + +#ifdef CONFIG_NET_HAVE_SOLINGER + ling.l_onoff = 1; + ling.l_linger = 30; /* timeout is seconds */ + if (setsockopt(acceptsd, SOL_SOCKET, SO_LINGER, &ling, sizeof(struct linger)) < 0) + { + close(acceptsd); + ndbg("setsockopt SO_LINGER failure: %d\n", errno); + break;; + } +#endif + + /* Handle the request. This blocks until complete. */ + + (void) httpd_handler((void*)acceptsd); + } + + return ERROR; +} +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -611,9 +668,13 @@ int httpd_listen(void) { /* Execute httpd_handler on each connection to port 80 */ +#ifdef CONFIG_NETUTILS_HTTPD_SINGLETHREAD + single_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE); +#else uip_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE); +#endif - /* uip_server only returns on errors */ + /* the server accept loop only returns on errors */ return ERROR; } |