|
|
|
@ -40,27 +40,21 @@ static const char *s_serverName = HTTPD_SERVERNAME; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Connection pool
|
|
|
|
|
HttpdConnData *s_connData[HTTPD_MAX_CONNECTIONS]; |
|
|
|
|
HttpdConnData s_connData[HTTPD_MAX_CONNECTIONS]; |
|
|
|
|
|
|
|
|
|
void httpdInternalCloseAllSockets(void) |
|
|
|
|
{ |
|
|
|
|
httpdPlatLock(); |
|
|
|
|
/*release data connection*/ |
|
|
|
|
for (int i = 0; i < HTTPD_MAX_CONNECTIONS; i++) { |
|
|
|
|
HttpdConnData *hconn = &s_connData[i]; |
|
|
|
|
//find all valid handle
|
|
|
|
|
if (s_connData[i]->conn == NULL) { |
|
|
|
|
if (!hconn->occupied) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (s_connData[i]->cgi != NULL) { |
|
|
|
|
//flush cgi data
|
|
|
|
|
s_connData[i]->cgi(s_connData[i]); |
|
|
|
|
s_connData[i]->cgi = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
httpdConnRelease(s_connData[i]->conn); |
|
|
|
|
httpdRetireConn(s_connData[i]); |
|
|
|
|
s_connData[i] = NULL; |
|
|
|
|
httpdConnRelease(hconn->conn); |
|
|
|
|
httpdRetireConn(hconn); |
|
|
|
|
} |
|
|
|
|
httpdPlatUnlock(); |
|
|
|
|
} |
|
|
|
@ -99,10 +93,10 @@ size_t httpGetBacklogSize(const HttpdConnData *conn) |
|
|
|
|
static HttpdConnData *httpdFindConnData(ConnTypePtr conn, httpd_ipaddr_t remIp, int remPort) |
|
|
|
|
{ |
|
|
|
|
for (int i = 0; i < HTTPD_MAX_CONNECTIONS; i++) { |
|
|
|
|
if (s_connData[i] && s_connData[i]->remote_port == remPort |
|
|
|
|
&& s_connData[i]->remote_ip == remIp) { |
|
|
|
|
s_connData[i]->conn = conn; |
|
|
|
|
return s_connData[i]; |
|
|
|
|
if (s_connData[i].occupied && s_connData[i].remote_port == remPort |
|
|
|
|
&& s_connData[i].remote_ip == remIp) { |
|
|
|
|
s_connData[i].conn = conn; |
|
|
|
|
return &s_connData[i]; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
//Shouldn't happen.
|
|
|
|
@ -114,7 +108,7 @@ static HttpdConnData *httpdFindConnData(ConnTypePtr conn, httpd_ipaddr_t remIp, |
|
|
|
|
//Retires a connection for re-use
|
|
|
|
|
static void httpdRetireConn(HttpdConnData *hconn) |
|
|
|
|
{ |
|
|
|
|
if (!hconn) { |
|
|
|
|
if (!hconn || !hconn->occupied) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
http_info("Pool slot %d: socket closed.", hconn->slot); |
|
|
|
@ -123,24 +117,32 @@ static void httpdRetireConn(HttpdConnData *hconn) |
|
|
|
|
cleanupCgiAndUserData(hconn); |
|
|
|
|
|
|
|
|
|
// Free any memory allocated for backlog - walk the linked list
|
|
|
|
|
if (hconn->priv.sendBacklog != NULL) { |
|
|
|
|
HttpdSendBacklogItem *i, *j; |
|
|
|
|
i = hconn->priv.sendBacklog; |
|
|
|
|
if (hconn->priv.sendBacklog) { |
|
|
|
|
HttpdSendBacklogItem *backlog, *next; |
|
|
|
|
backlog = hconn->priv.sendBacklog; |
|
|
|
|
do { |
|
|
|
|
j = i; |
|
|
|
|
i = i->next; |
|
|
|
|
httpdFree(j); |
|
|
|
|
} while (i != NULL); |
|
|
|
|
next = backlog->next; |
|
|
|
|
httpdFree(backlog); |
|
|
|
|
backlog = next; |
|
|
|
|
} while (backlog != NULL); |
|
|
|
|
} |
|
|
|
|
if (hconn->post.buff != NULL) { |
|
|
|
|
|
|
|
|
|
// Free post data buffer
|
|
|
|
|
if (hconn->post.buff) { |
|
|
|
|
httpdFree(hconn->post.buff); |
|
|
|
|
hconn->post.buff = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Unlink from the connection list
|
|
|
|
|
s_connData[hconn->slot] = NULL; |
|
|
|
|
// release memory
|
|
|
|
|
httpdFree(hconn); |
|
|
|
|
// Free left-over queued headers - can happen if the client disconnects before headers were sent
|
|
|
|
|
HttpdQueuedHeader *hdr = hconn->priv.headersToSend; |
|
|
|
|
hconn->priv.headersToSend = NULL; |
|
|
|
|
while (hdr) { |
|
|
|
|
HttpdQueuedHeader *next = hdr->next; |
|
|
|
|
httpdFree(hdr); |
|
|
|
|
hdr = next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s_connData[hconn->slot].occupied = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
//Get the value of a certain header in the HTTP client head
|
|
|
|
@ -872,7 +874,7 @@ int httpdConnectCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort) |
|
|
|
|
|
|
|
|
|
//Find empty conndata in pool
|
|
|
|
|
for (ci = 0; ci < HTTPD_MAX_CONNECTIONS; ci++) { |
|
|
|
|
if (s_connData[ci] == NULL) { |
|
|
|
|
if (!s_connData[ci].occupied) { |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -884,22 +886,13 @@ int httpdConnectCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort) |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
s_connData[ci] = httpdMalloc(sizeof(HttpdConnData)); |
|
|
|
|
if (s_connData[ci] == NULL) { |
|
|
|
|
http_warn("Out of memory allocating connData!"); |
|
|
|
|
httpdPlatUnlock(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
memset(s_connData[ci], 0, sizeof(HttpdConnData)); |
|
|
|
|
|
|
|
|
|
memset(&s_connData[ci]->post, 0, sizeof(HttpdPostData)); |
|
|
|
|
memset(&s_connData[ci]->priv, 0, sizeof(HttpdPriv)); |
|
|
|
|
|
|
|
|
|
s_connData[ci]->conn = conn; |
|
|
|
|
s_connData[ci]->slot = ci; |
|
|
|
|
s_connData[ci]->remote_ip = remIp; |
|
|
|
|
s_connData[ci]->remote_port = remPort; |
|
|
|
|
s_connData[ci]->post.len = -1; |
|
|
|
|
memset(&s_connData[ci], 0, sizeof(HttpdConnData)); |
|
|
|
|
s_connData[ci].slot = ci; |
|
|
|
|
s_connData[ci].occupied = true; |
|
|
|
|
s_connData[ci].conn = conn; |
|
|
|
|
s_connData[ci].remote_ip = remIp; |
|
|
|
|
s_connData[ci].remote_port = remPort; |
|
|
|
|
s_connData[ci].post.len = -1; |
|
|
|
|
|
|
|
|
|
httpdPlatUnlock(); |
|
|
|
|
return 1; |
|
|
|
@ -908,11 +901,8 @@ int httpdConnectCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort) |
|
|
|
|
//Httpd initialization routine. Call this to kick off webserver functionality.
|
|
|
|
|
httpd_thread_handle_t *httpdStart(const HttpdBuiltInUrl *fixedUrls, struct httpd_init_options *options) |
|
|
|
|
{ |
|
|
|
|
int i; |
|
|
|
|
memset(s_connData, 0, sizeof(s_connData)); |
|
|
|
|
|
|
|
|
|
for (i = 0; i < HTTPD_MAX_CONNECTIONS; i++) { |
|
|
|
|
s_connData[i] = NULL; |
|
|
|
|
} |
|
|
|
|
s_builtInUrls = fixedUrls; |
|
|
|
|
|
|
|
|
|
httpdPlatInit(); |
|
|
|
|