From 14f445102e0b861845ccd53a5d6777a25bc75c7e Mon Sep 17 00:00:00 2001 From: patacongo Date: Mon, 17 Sep 2012 19:44:53 +0000 Subject: Add option for single connection web server. From Kate. git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5157 42af7a65-404d-4744-a932-0658087f49c3 --- apps/netutils/webserver/Kconfig | 12 ++++++++ apps/netutils/webserver/httpd.c | 65 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 75 insertions(+), 2 deletions(-) (limited to 'apps/netutils') 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 #include #include -#include #include #include +#ifndef CONFIG_NETUTILS_HTTPD_SINGLETHREAD +# include +#endif + #include #include #include @@ -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; } -- cgit v1.2.3