mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-22 06:14:14 +08:00
Adds support for keep-alive connections to webserver
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5178 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -338,3 +338,5 @@
|
||||
Both from Kate.
|
||||
* apps/netutils/webserver/httpd.c: Improvements to HTTP parser from
|
||||
Kate.
|
||||
* apps/netutils/webserver/httpd.c: Add support for Keep-alive connections
|
||||
(from Kate).
|
||||
|
||||
@@ -109,6 +109,9 @@ struct httpd_state
|
||||
{
|
||||
char ht_buffer[HTTPD_IOBUFFER_SIZE]; /* recv() buffer */
|
||||
char ht_filename[HTTPD_MAX_FILENAME]; /* filename from GET command */
|
||||
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||
bool ht_keepalive; /* Connection: keep-alive */
|
||||
#endif
|
||||
struct httpd_fs_file ht_file; /* Fake file data to send */
|
||||
int ht_sockfd; /* The socket descriptor from accept() */
|
||||
char *ht_scriptptr;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||
do
|
||||
{
|
||||
pstate->ht_keepalive = false;
|
||||
#endif
|
||||
|
||||
status = httpd_parse(pstate);
|
||||
if (status >= 400)
|
||||
{
|
||||
ret = httpd_senderror(pstate, status);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = httpd_sendfile(pstate);
|
||||
/* 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 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user