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
This commit is contained in:
parent
0e46b2be82
commit
503886bf78
@ -332,6 +332,7 @@
|
||||
* 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.
|
||||
|
||||
* apps/netutils/webserver/httpd.c: The option CONFIG_NETUTILS_HTTPD_SINGLECONNECT
|
||||
can now be used to limit the server to a single thread. Option
|
||||
CONFIG_NETUTILS_HTTPD_TIMEOUT can be used to generate HTTP 408 errors.
|
||||
Both from Kate.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user