mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-01 19:07:45 +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.
|
Both from Kate.
|
||||||
* apps/netutils/webserver/httpd.c: Improvements to HTTP parser from
|
* apps/netutils/webserver/httpd.c: Improvements to HTTP parser from
|
||||||
Kate.
|
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_buffer[HTTPD_IOBUFFER_SIZE]; /* recv() buffer */
|
||||||
char ht_filename[HTTPD_MAX_FILENAME]; /* filename from GET command */
|
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 */
|
struct httpd_fs_file ht_file; /* Fake file data to send */
|
||||||
int ht_sockfd; /* The socket descriptor from accept() */
|
int ht_sockfd; /* The socket descriptor from accept() */
|
||||||
char *ht_scriptptr;
|
char *ht_scriptptr;
|
||||||
|
|||||||
@@ -117,4 +117,22 @@ config NETUTILS_HTTPD_MMAP
|
|||||||
representation.
|
representation.
|
||||||
|
|
||||||
endchoice
|
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
|
endif
|
||||||
|
|||||||
@@ -104,6 +104,16 @@
|
|||||||
# define CONFIG_NETUTILS_HTTPD_TIMEOUT 0
|
# define CONFIG_NETUTILS_HTTPD_TIMEOUT 0
|
||||||
#endif
|
#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)
|
#if !defined(CONFIG_NETUTILS_HTTPD_SENDFILE) && !defined(CONFIG_NETUTILS_HTTPD_MMAP)
|
||||||
# ifndef CONFIG_NETUTILS_HTTPD_INDEX
|
# ifndef CONFIG_NETUTILS_HTTPD_INDEX
|
||||||
# ifndef CONFIG_NETUTILS_HTTPD_SCRIPT_DISABLE
|
# 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);
|
(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)
|
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
|
#ifndef CONFIG_NETUTILS_HTTPD_SERVERHEADER_DISABLE
|
||||||
"Server: uIP/NuttX http://nuttx.org/\r\n"
|
"Server: uIP/NuttX http://nuttx.org/\r\n"
|
||||||
#endif
|
#endif
|
||||||
"Connection: close\r\n"
|
"Connection: %s\r\n"
|
||||||
"Content-type: %s\r\n"
|
"Content-type: %s\r\n"
|
||||||
"%s"
|
"%s"
|
||||||
"\r\n",
|
"\r\n",
|
||||||
status,
|
status,
|
||||||
status >= 400 ? "Error" : "OK",
|
status >= 400 ? "Error" : "OK",
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||||
|
pstate->ht_keepalive ? "keep-alive" : "close",
|
||||||
|
#else
|
||||||
|
"close",
|
||||||
|
#endif
|
||||||
mime,
|
mime,
|
||||||
len >= 0 ? cl : "");
|
len >= 0 ? cl : "");
|
||||||
|
|
||||||
@@ -407,6 +428,13 @@ static int httpd_senderror(struct httpd_state *pstate, int status)
|
|||||||
status = 500;
|
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,
|
(void) snprintf(pstate->ht_filename, sizeof pstate->ht_filename,
|
||||||
"%s/%d.html",
|
"%s/%d.html",
|
||||||
CONFIG_NETUTILS_HTTPD_ERRPATH, status);
|
CONFIG_NETUTILS_HTTPD_ERRPATH, status);
|
||||||
@@ -456,6 +484,9 @@ static int httpd_sendfile(struct httpd_state *pstate)
|
|||||||
f = httpd_cgi(pstate->ht_filename);
|
f = httpd_cgi(pstate->ht_filename);
|
||||||
if (f != NULL)
|
if (f != NULL)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||||
|
pstate->ht_keepalive = false;
|
||||||
|
#endif
|
||||||
f(pstate, pstate->ht_filename);
|
f(pstate, pstate->ht_filename);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
@@ -474,6 +505,9 @@ static int httpd_sendfile(struct httpd_state *pstate)
|
|||||||
if (ptr != NULL &&
|
if (ptr != NULL &&
|
||||||
strncmp(ptr, ".shtml", strlen(".shtml")) == 0)
|
strncmp(ptr, ".shtml", strlen(".shtml")) == 0)
|
||||||
{
|
{
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||||
|
pstate->ht_keepalive = false;
|
||||||
|
#endif
|
||||||
if (send_headers(pstate, 200, -1) != OK)
|
if (send_headers(pstate, 200, -1) != OK)
|
||||||
{
|
{
|
||||||
goto done;
|
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"))
|
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;
|
return 505;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -638,7 +672,12 @@ static inline int httpd_parse(struct httpd_state *pstate)
|
|||||||
ndbg("[%d] non-zero request length\n");
|
ndbg("[%d] non-zero request length\n");
|
||||||
return 413;
|
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;
|
break;
|
||||||
|
|
||||||
case STATE_BODY:
|
case STATE_BODY:
|
||||||
@@ -650,7 +689,7 @@ static inline int httpd_parse(struct httpd_state *pstate)
|
|||||||
/* Shuffle down for the next block */
|
/* Shuffle down for the next block */
|
||||||
|
|
||||||
memmove(pstate->ht_buffer, start, o - start);
|
memmove(pstate->ht_buffer, start, o - start);
|
||||||
o -= start;
|
o -= (start - pstate->ht_buffer);
|
||||||
}
|
}
|
||||||
while (state != STATE_BODY);
|
while (state != STATE_BODY);
|
||||||
|
|
||||||
@@ -695,6 +734,12 @@ static void *httpd_handler(void *arg)
|
|||||||
memset(pstate, 0, sizeof(struct httpd_state));
|
memset(pstate, 0, sizeof(struct httpd_state));
|
||||||
pstate->ht_sockfd = sockfd;
|
pstate->ht_sockfd = sockfd;
|
||||||
|
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pstate->ht_keepalive = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Then handle the next httpd command */
|
/* Then handle the next httpd command */
|
||||||
|
|
||||||
status = httpd_parse(pstate);
|
status = httpd_parse(pstate);
|
||||||
@@ -707,6 +752,11 @@ static void *httpd_handler(void *arg)
|
|||||||
ret = httpd_sendfile(pstate);
|
ret = httpd_sendfile(pstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_NETUTILS_HTTPD_KEEPALIVE_DISABLE
|
||||||
|
}
|
||||||
|
while (pstate->ht_keepalive);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* End of command processing -- Clean up and exit */
|
/* End of command processing -- Clean up and exit */
|
||||||
|
|
||||||
free(pstate);
|
free(pstate);
|
||||||
|
|||||||
Reference in New Issue
Block a user