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