Fixed bug #50059 (httpd LWIP_HTTPD_SUPPORT_11_KEEPALIVE vs. LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED)

(cherry picked from commit 57438647442f71d47fe4986dd30bbc073b48e469)
This commit is contained in:
goldsimon 2017-02-09 13:01:37 +01:00
parent dc38e21a70
commit 3c4aec99a4

View File

@ -335,9 +335,40 @@ char *http_cgi_param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each ext
/** global list of active HTTP connections, use to kill the oldest when /** global list of active HTTP connections, use to kill the oldest when
running out of memory */ running out of memory */
static struct http_state *http_connections; static struct http_state *http_connections;
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED static void
http_add_connection(struct http_state *hs)
{
/* add the connection to the list */
if (http_connections == NULL) {
http_connections = hs;
} else {
struct http_state *last;
for(last = http_connections; last->next != NULL; last = last->next);
LWIP_ASSERT("last != NULL", last != NULL);
last->next = hs;
}
}
static void
http_remove_connection(struct http_state *hs)
{
/* take the connection off the list */
if (http_connections) {
if (http_connections == hs) {
http_connections = hs->next;
} else {
struct http_state *last;
for(last = http_connections; last->next != NULL; last = last->next) {
if (last->next == hs) {
last->next = hs->next;
break;
}
}
}
}
}
static void static void
http_kill_oldest_connection(u8_t ssi_required) http_kill_oldest_connection(u8_t ssi_required)
{ {
@ -366,6 +397,11 @@ http_kill_oldest_connection(u8_t ssi_required)
http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */ http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */
} }
} }
#else /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
#define http_add_connection(hs)
#define http_remove_connection(hs)
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ #endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
#if LWIP_HTTPD_SSI #if LWIP_HTTPD_SSI
@ -422,17 +458,7 @@ http_state_alloc(void)
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ #endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
if (ret != NULL) { if (ret != NULL) {
http_state_init(ret); http_state_init(ret);
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED http_add_connection(ret);
/* add the connection to the list */
if (http_connections == NULL) {
http_connections = ret;
} else {
struct http_state *last;
for(last = http_connections; last->next != NULL; last = last->next);
LWIP_ASSERT("last != NULL", last != NULL);
last->next = ret;
}
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
} }
return ret; return ret;
} }
@ -481,22 +507,7 @@ http_state_free(struct http_state *hs)
{ {
if (hs != NULL) { if (hs != NULL) {
http_state_eof(hs); http_state_eof(hs);
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED http_remove_connection(hs);
/* take the connection off the list */
if (http_connections) {
if (http_connections == hs) {
http_connections = hs->next;
} else {
struct http_state *last;
for(last = http_connections; last->next != NULL; last = last->next) {
if (last->next == hs) {
last->next = hs->next;
break;
}
}
}
}
#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */
HTTP_FREE_HTTP_STATE(hs); HTTP_FREE_HTTP_STATE(hs);
} }
} }
@ -638,17 +649,14 @@ http_eof(struct tcp_pcb *pcb, struct http_state *hs)
/* HTTP/1.1 persistent connection? (Not supported for SSI) */ /* HTTP/1.1 persistent connection? (Not supported for SSI) */
#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE #if LWIP_HTTPD_SUPPORT_11_KEEPALIVE
if (hs->keepalive) { if (hs->keepalive) {
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED http_remove_connection(hs);
struct http_state* next = hs->next;
#endif
http_state_eof(hs); http_state_eof(hs);
http_state_init(hs); http_state_init(hs);
/* restore state: */ /* restore state: */
#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED
hs->next = next;
#endif
hs->pcb = pcb; hs->pcb = pcb;
hs->keepalive = 1; hs->keepalive = 1;
http_add_connection(hs);
/* ensure nagle doesn't interfere with sending all data as fast as possible: */ /* ensure nagle doesn't interfere with sending all data as fast as possible: */
tcp_nagle_disable(pcb); tcp_nagle_disable(pcb);
} else } else