Add option for single connection web server. From Kate.

git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5157 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2012-09-17 19:44:53 +00:00
parent 1550be3df3
commit 77b8e554f8
3 changed files with 77 additions and 2 deletions

View File

@ -332,4 +332,6 @@
* apps/netutils/uip_listenon.c: Logic in uip_server.c that creates * 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. the listening socket was moved to this new file to support re-use.
Contributed by Kate. 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.

View File

@ -13,6 +13,18 @@ config NETUTILS_WEBSERVER
if 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 config NETUTILS_HTTPD_SCRIPT_DISABLE
bool "Disable %! scripting" bool "Disable %! scripting"
default y if NETUTILS_HTTPD_SENDFILE default y if NETUTILS_HTTPD_SENDFILE

View File

@ -54,10 +54,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <string.h> #include <string.h>
#include <pthread.h>
#include <errno.h> #include <errno.h>
#include <debug.h> #include <debug.h>
#ifndef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
# include <pthread.h>
#endif
#include <nuttx/net/uip/uip.h> #include <nuttx/net/uip/uip.h>
#include <apps/netutils/uiplib.h> #include <apps/netutils/uiplib.h>
#include <apps/netutils/httpd.h> #include <apps/netutils/httpd.h>
@ -595,6 +598,60 @@ static void *httpd_handler(void *arg)
return NULL; 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 * Public Functions
****************************************************************************/ ****************************************************************************/
@ -611,9 +668,13 @@ int httpd_listen(void)
{ {
/* Execute httpd_handler on each connection to port 80 */ /* 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); 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; return ERROR;
} }