summaryrefslogtreecommitdiff
path: root/apps/netutils/webserver
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-22 20:36:36 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-09-22 20:36:36 +0000
commit14041d4dc7b60500de8ab760ca9e6cc55ccc524c (patch)
treea40c14f9154674eb752351c0b6f11bad74786306 /apps/netutils/webserver
parent8f88f77957feaf87be4b7571a420a13682a357b9 (diff)
downloadnuttx-14041d4dc7b60500de8ab760ca9e6cc55ccc524c.tar.gz
nuttx-14041d4dc7b60500de8ab760ca9e6cc55ccc524c.tar.bz2
nuttx-14041d4dc7b60500de8ab760ca9e6cc55ccc524c.zip
Adds support for keep-alive connections to webserver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5178 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.c76
2 files changed, 81 insertions, 13 deletions
diff --git a/apps/netutils/webserver/Kconfig b/apps/netutils/webserver/Kconfig
index edca8dfdd..69a39510d 100644
--- a/apps/netutils/webserver/Kconfig
+++ b/apps/netutils/webserver/Kconfig
@@ -117,4 +117,22 @@ config NETUTILS_HTTPD_MMAP
representation.
endchoice
+
+config NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ bool "Keepalive Disable"
+ default y if !NETUTILS_HTTPD_TIMEOUT
+ default n if NETUTILS_HTTPD_TIMEOUT
+ ---help---
+ Disabled HTTP keep-alive for HTTP clients. Keep-alive permits a
+ client to make multiple requests over the same connection, rather
+ than closing and opening a new socket for each request.
+
+ This depends on the content-length being known, and is automatically
+ disabled for situations where that header isn't produced (i.e.
+ scripting, CGI). Keep-alive is also disabled for certain error
+ responses.
+
+ Keep-alive should normally be disabled if timeouts are enabled,
+ otherwise a rogue HTTP client could block the httpd indefinitely.
+
endif
diff --git a/apps/netutils/webserver/httpd.c b/apps/netutils/webserver/httpd.c
index ebcf300b6..d7dae55da 100644
--- a/apps/netutils/webserver/httpd.c
+++ b/apps/netutils/webserver/httpd.c
@@ -104,6 +104,16 @@
# define CONFIG_NETUTILS_HTTPD_TIMEOUT 0
#endif
+/* If timeouts are not enabled, then keep-alive is disabled. This is to
+ * prevent a rogue HTTP client from blocking the httpd indefinitely.
+ */
+
+#if !defined(CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE)
+# if CONFIG_NETUTILS_HTTPD_TIMEOUT == 0
+# define CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+# endif
+#endif
+
#if !defined(CONFIG_NETUTILS_HTTPD_SENDFILE) && !defined(CONFIG_NETUTILS_HTTPD_MMAP)
# ifndef CONFIG_NETUTILS_HTTPD_INDEX
# ifndef CONFIG_NETUTILS_HTTPD_SCRIPT_DISABLE
@@ -372,6 +382,12 @@ static int send_headers(struct httpd_state *pstate, int status, int len)
{
(void) snprintf(cl, sizeof cl, "Content-Length: %d\r\n", len);
}
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ else
+ {
+ pstate->ht_keepalive = false;
+ }
+#endif
if (status == 413)
{
@@ -383,12 +399,17 @@ static int send_headers(struct httpd_state *pstate, int status, int len)
#ifndef CONFIG_NETUTILS_HTTPD_SERVERHEADER_DISABLE
"Server: uIP/NuttX http://nuttx.org/\r\n"
#endif
- "Connection: close\r\n"
+ "Connection: %s\r\n"
"Content-type: %s\r\n"
"%s"
"\r\n",
status,
status >= 400 ? "Error" : "OK",
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ pstate->ht_keepalive ? "keep-alive" : "close",
+#else
+ "close",
+#endif
mime,
len >= 0 ? cl : "");
@@ -407,6 +428,13 @@ static int httpd_senderror(struct httpd_state *pstate, int status)
status = 500;
}
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ if (status != 404)
+ {
+ pstate->ht_keepalive = false;
+ }
+#endif
+
(void) snprintf(pstate->ht_filename, sizeof pstate->ht_filename,
"%s/%d.html",
CONFIG_NETUTILS_HTTPD_ERRPATH, status);
@@ -456,6 +484,9 @@ static int httpd_sendfile(struct httpd_state *pstate)
f = httpd_cgi(pstate->ht_filename);
if (f != NULL)
{
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ pstate->ht_keepalive = false;
+#endif
f(pstate, pstate->ht_filename);
return OK;
@@ -474,6 +505,9 @@ static int httpd_sendfile(struct httpd_state *pstate)
if (ptr != NULL &&
strncmp(ptr, ".shtml", strlen(".shtml")) == 0)
{
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ pstate->ht_keepalive = false;
+#endif
if (send_headers(pstate, 200, -1) != OK)
{
goto done;
@@ -594,7 +628,7 @@ static inline int httpd_parse(struct httpd_state *pstate)
if (0 != strcmp(v, " HTTP/1.0") && 0 != strcmp(v, " HTTP/1.1"))
{
- ndbg("[%d] HTTP/%d.%d not supported\n", major, minor);
+ ndbg("[%d] HTTP version not supported\n");
return 505;
}
@@ -638,7 +672,12 @@ static inline int httpd_parse(struct httpd_state *pstate)
ndbg("[%d] non-zero request length\n");
return 413;
}
-
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ else if (0 == strcasecmp(start, "Connection") && 0 == strcasecmp(v, "keep-alive"))
+ {
+ pstate->ht_keepalive = true;
+ }
+#endif
break;
case STATE_BODY:
@@ -650,7 +689,7 @@ static inline int httpd_parse(struct httpd_state *pstate)
/* Shuffle down for the next block */
memmove(pstate->ht_buffer, start, o - start);
- o -= start;
+ o -= (start - pstate->ht_buffer);
}
while (state != STATE_BODY);
@@ -695,17 +734,28 @@ static void *httpd_handler(void *arg)
memset(pstate, 0, sizeof(struct httpd_state));
pstate->ht_sockfd = sockfd;
- /* Then handle the next httpd command */
-
- status = httpd_parse(pstate);
- if (status >= 400)
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
+ do
{
- ret = httpd_senderror(pstate, status);
- }
- else
- {
- ret = httpd_sendfile(pstate);
+ pstate->ht_keepalive = false;
+#endif
+
+ /* Then handle the next httpd command */
+
+ status = httpd_parse(pstate);
+ if (status >= 400)
+ {
+ ret = httpd_senderror(pstate, status);
+ }
+ else
+ {
+ ret = httpd_sendfile(pstate);
+ }
+
+#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
}
+ while (pstate->ht_keepalive);
+#endif
/* End of command processing -- Clean up and exit */