summaryrefslogtreecommitdiff
path: root/apps/netutils/webserver
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 23:02:58 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-17 23:02:58 +0000
commit68e8befbc94818cc60bbfd4fb3f8f556e76ecba2 (patch)
tree73190e5163186ab1028a6b26ef5b3794bc6910ba /apps/netutils/webserver
parent14f445102e0b861845ccd53a5d6777a25bc75c7e (diff)
downloadnuttx-68e8befbc94818cc60bbfd4fb3f8f556e76ecba2.tar.gz
nuttx-68e8befbc94818cc60bbfd4fb3f8f556e76ecba2.tar.bz2
nuttx-68e8befbc94818cc60bbfd4fb3f8f556e76ecba2.zip
Fix ENC28J60 Tx transmit (still a receive problem); Add HTTP 408 logic from Kate
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5158 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'apps/netutils/webserver')
-rw-r--r--apps/netutils/webserver/Kconfig18
-rw-r--r--apps/netutils/webserver/httpd.c68
2 files changed, 76 insertions, 10 deletions
diff --git a/apps/netutils/webserver/Kconfig b/apps/netutils/webserver/Kconfig
index e64fcdb73..b4c76a33f 100644
--- a/apps/netutils/webserver/Kconfig
+++ b/apps/netutils/webserver/Kconfig
@@ -13,8 +13,8 @@ config NETUTILS_WEBSERVER
if NETUTILS_WEBSERVER
-config NETUTILS_HTTPD_SINGLETHREAD
- bool "Single Threded"
+config NETUTILS_HTTPD_SINGLECONNECT
+ bool "Single Connection"
default n if !DISABLE_PTHREAD
default y if DISABLE_PTHREAD
---help---
@@ -22,9 +22,9 @@ config NETUTILS_HTTPD_SINGLETHREAD
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.
-
+ service all HTTP requests and, in this case, only a single connection
+ at a time is supported at a time.
+
config NETUTILS_HTTPD_SCRIPT_DISABLE
bool "Disable %! scripting"
default y if NETUTILS_HTTPD_SENDFILE
@@ -65,6 +65,14 @@ config NETUTILS_HTTPD_SERVERHEADER_DISABLE
---help---
This option, if selected, will elide the Server\: header
+config NETUTILS_HTTPD_TIMEOUT
+ int "Receive Timeout (sec)"
+ default 0
+ ---help---
+ Receive timeout setting (in seconds). A timeout value of zero
+ disables the timeout. An HTTP 408 error is generated if the timeout
+ expires.
+
choice
prompt "File Transfer Method"
default NETUTILS_HTTPD_CLASSIC
diff --git a/apps/netutils/webserver/httpd.c b/apps/netutils/webserver/httpd.c
index bb70e34a1..9d78a38ca 100644
--- a/apps/netutils/webserver/httpd.c
+++ b/apps/netutils/webserver/httpd.c
@@ -57,7 +57,7 @@
#include <errno.h>
#include <debug.h>
-#ifndef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
+#ifndef CONFIG_NETUTILS_HTTPD_SINGLECONNECT
# include <pthread.h>
#endif
@@ -92,6 +92,14 @@
# define CONFIG_NETUTILS_HTTPD_PATH "/mnt"
#endif
+/* The correct way to disable receive timeout errors is by setting the
+ * timeout to zero.
+ */
+
+#ifndef CONFIG_NETUTILS_HTTPD_TIMEOUT
+# define CONFIG_NETUTILS_HTTPD_TIMEOUT 0
+#endif
+
/****************************************************************************
* Private Data
****************************************************************************/
@@ -116,6 +124,9 @@ static const char g_httpextensionjpg[] = ".jpg";
static const char g_httpextensionjs[] = ".js";
static const char g_http404path[] = "/404.html";
+#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
+static const char g_http408path[] = "/408.html";
+#endif
#ifndef CONFIG_NETUTILS_HTTPD_SCRIPT_DISABLE
static const char g_httpindexpath[] = "/index.shtml";
#else
@@ -138,6 +149,15 @@ static const char g_httpheader404[] =
#endif
"Connection: close\r\n";
+#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
+static const char g_httpheader408[] =
+ "HTTP/1.0 408 Request timed out\r\n"
+#ifndef CONFIG_NETUTILS_HTTPD_SERVERHEADER_DISABLE
+ "Server: uIP/1.0 http://www.sics.se/~adam/uip/\r\n"
+#endif
+ "Connection: close\r\n";
+#endif
+
/****************************************************************************
* Private Functions
****************************************************************************/
@@ -507,6 +527,28 @@ static inline int httpd_cmd(struct httpd_state *pstate)
/* Get the next HTTP command. We will handle only GET */
recvlen = recv(pstate->ht_sockfd, pstate->ht_buffer, HTTPD_IOBUFFER_SIZE, 0);
+#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
+ if (recvlen < 0 && errno == EWOULDBLOCK)
+ {
+ ndbg("[%d] recv timeout\n");
+ strncpy(pstate->ht_filename, g_httpindexpath, strlen(g_httpindexpath));
+
+ memcpy(pstate->ht_filename, g_http408path, strlen(g_http408path));
+ if (httpd_open(g_http408path, &pstate->ht_file) != OK)
+ {
+ return ERROR;
+ }
+
+ if (send_headers(pstate, g_httpheader408, strlen(g_httpheader408)) == OK)
+ {
+#ifdef CONFIG_NETUTILS_HTTPD_SENDFILE
+ return httpd_sendfile_send(pstate->ht_sockfd, &pstate->ht_file);
+#else
+ return httpd_addchunk(pstate, pstate->ht_file.data, pstate->ht_file.len);
+#endif
+ }
+ }
+#endif
if (recvlen < 0)
{
ndbg("[%d] recv failed: %d\n", pstate->ht_sockfd, errno);
@@ -598,7 +640,7 @@ static void *httpd_handler(void *arg)
return NULL;
}
-#ifdef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
+#ifdef CONFIG_NETUTILS_HTTPD_SINGLECONNECT
static void single_server(uint16_t portno, pthread_startroutine_t handler, int stacksize)
{
struct sockaddr_in myaddr;
@@ -608,11 +650,14 @@ static void single_server(uint16_t portno, pthread_startroutine_t handler, int s
#ifdef CONFIG_NET_HAVE_SOLINGER
struct linger ling;
#endif
+#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
+ struct timeval tv;
+#endif
listensd = uip_listenon(portno);
if (listensd < 0)
{
- return ERROR;
+ return;
}
/* Begin serving connections */
@@ -643,12 +688,25 @@ static void single_server(uint16_t portno, pthread_startroutine_t handler, int s
}
#endif
+#if CONFIG_NETUTILS_HTTPD_TIMEOUT > 0
+ /* Set up a receive timeout */
+
+ tv.tv_sec = CONFIG_NETUTILS_HTTPD_TIMEOUT;
+ tv.tv_usec = 0;
+ if (setsockopt(acceptsd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(struct timeval)) < 0)
+ {
+ close(acceptsd);
+ ndbg("setsockopt SO_RCVTIMEO failure: %d\n", errno);
+ break;;
+ }
+#endif
+
/* Handle the request. This blocks until complete. */
(void) httpd_handler((void*)acceptsd);
}
- return ERROR;
+ return;
}
#endif
@@ -668,7 +726,7 @@ int httpd_listen(void)
{
/* Execute httpd_handler on each connection to port 80 */
-#ifdef CONFIG_NETUTILS_HTTPD_SINGLETHREAD
+#ifdef CONFIG_NETUTILS_HTTPD_SINGLECONNECT
single_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);
#else
uip_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);