diff --git a/demo/server_demo.c b/demo/server_demo.c index 5186307..9168dc5 100644 --- a/demo/server_demo.c +++ b/demo/server_demo.c @@ -29,7 +29,7 @@ httpd_cgi_state templateReplacer(HttpdConnData *conn, const char *token) if (!token) { if (conn->userData) { - httpdPlatFree(conn->userData); + httpdFree(conn->userData); conn->userData = NULL; } return HTTPD_CGI_DONE; diff --git a/spritehttpd/include/httpd-config.h b/spritehttpd/include/httpd-config.h index 76a9ade..424e175 100644 --- a/spritehttpd/include/httpd-config.h +++ b/spritehttpd/include/httpd-config.h @@ -51,3 +51,12 @@ #ifndef HTTPD_MAX_CONNECTIONS #define HTTPD_MAX_CONNECTIONS 4 #endif + +// ESPFS params + +/// EspFs CGI filename len buffer size +#define ESPFS_FILENAME_LEN 100 +/// EspFs CGI file chunk buffer size +#define ESPFS_FILE_CHUNK_LEN 512 +/// EspFs CGI header buffer (used to detect gzip) +#define ESPFS_HEADER_LEN 64 diff --git a/spritehttpd/include/httpd-types.h b/spritehttpd/include/httpd-types.h index 8ac2be3..e900085 100644 --- a/spritehttpd/include/httpd-types.h +++ b/spritehttpd/include/httpd-types.h @@ -6,6 +6,8 @@ #include #include +#include + #include "httpd-config.h" // opaque conn type struct @@ -147,4 +149,5 @@ struct HttpdConnData { uint16_t remote_port; // Remote TCP port httpd_ipaddr_t remote_ip; // IP address of client uint8_t slot; // Slot ID - index in s_connData + bool occupied; }; diff --git a/spritehttpd/src/cgi-espfs.c b/spritehttpd/src/cgi-espfs.c index bc01311..9ca515c 100644 --- a/spritehttpd/src/cgi-espfs.c +++ b/spritehttpd/src/cgi-espfs.c @@ -20,13 +20,7 @@ Connector to let httpd use the espfs filesystem to serve the files in it. #include "httpd-utils.h" #include "espfs.h" #include "espfsformat.h" - -/// EspFs CGI filename len buffer size -#define ESPFS_FILENAME_LEN 100 -/// EspFs CGI file chunk buffer size -#define ESPFS_FILE_CHUNK_LEN 512 -/// EspFs CGI header buffer (used to detect gzip) -#define ESPFS_HEADER_LEN 64 +#include "httpd-config.h" // The static files marked with FLAG_GZIP are compressed and will be served with GZIP compression. // If the client does not advertise that he accepts GZIP send following warning message (telnet users for e.g.) diff --git a/spritehttpd/src/httpd.c b/spritehttpd/src/httpd.c index 4f8cf1d..e47f9ee 100644 --- a/spritehttpd/src/httpd.c +++ b/spritehttpd/src/httpd.c @@ -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();