diff --git a/spritehttpd/include/httpd-logging.h b/spritehttpd/include/httpd-logging.h index b3d97e9..8aee7ba 100755 --- a/spritehttpd/include/httpd-logging.h +++ b/spritehttpd/include/httpd-logging.h @@ -2,6 +2,7 @@ #include #include "httpd-platform.h" +#include "httpd-types.h" #ifndef VERBOSE_LOGGING #define VERBOSE_LOGGING 1 @@ -11,6 +12,9 @@ #define LOG_EOL "\n" #endif +// split IP for printf %d.%d.%d.%d +#define IP_SPLIT(ip) ip&0xFF, (ip>>8)&0xFF, (ip>>16)&0xFF, (ip>>24)&0xFF + /** * Print a startup banner message (printf syntax) * Uses bright green color diff --git a/spritehttpd/include/httpd-types.h b/spritehttpd/include/httpd-types.h index f3366f2..6eba210 100644 --- a/spritehttpd/include/httpd-types.h +++ b/spritehttpd/include/httpd-types.h @@ -17,6 +17,8 @@ typedef struct httpd_thread_handle httpd_thread_handle_t; struct httpd_options; +typedef uint32_t httpd_ipaddr_t; + /** * CGI handler state / return value */ @@ -96,7 +98,7 @@ struct HttpdConnData { // this should be at the end because of padding uint16_t remote_port; // Remote TCP port - uint8_t remote_ip[4]; // IP address of client + httpd_ipaddr_t remote_ip; // IP address of client uint8_t slot; // Slot ID - index in s_connData }; diff --git a/spritehttpd/include/httpd.h b/spritehttpd/include/httpd.h index d6b53cf..ee157da 100644 --- a/spritehttpd/include/httpd.h +++ b/spritehttpd/include/httpd.h @@ -282,7 +282,7 @@ void httdResponseOptions(HttpdConnData *conn, int cors); * @param remIp - remote IP (4 bytes) * @param remPort - remote port */ -void httpdSentCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort); +void httpdSentCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort); /** * Callback called when there's data available on a socket. @@ -293,7 +293,7 @@ void httpdSentCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort); * @param data - data received. This is a mutable buffer * @param len - data len */ -void httpdRecvCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort, uint8_t *data, size_t len); +void httpdRecvCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort, uint8_t *data, size_t len); /** * The platform layer should ALWAYS call this function, regardless if the connection is closed by the server @@ -303,7 +303,7 @@ void httpdRecvCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort, uint8 * @param remIp - remote IP (4 bytes) * @param remPort - remote port */ -void httpdDisconCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort); +void httpdDisconCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort); /** * Connect callback - a client connected @@ -313,7 +313,7 @@ void httpdDisconCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort); * @param remPort - remote port * @return 1 = OK, 0 = client couldn't be served */ -int httpdConnectCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort); +int httpdConnectCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort); /** * Low level function to close & release a connection diff --git a/spritehttpd/src/httpd-loop.c b/spritehttpd/src/httpd-loop.c index 9f049dd..f580e80 100644 --- a/spritehttpd/src/httpd-loop.c +++ b/spritehttpd/src/httpd-loop.c @@ -14,13 +14,14 @@ Thanks to my collague at Espressif for writing the foundations of this code. #include #include #include "httpd-logging.h" +#include "httpd-types.h" struct HttpdConnType { int fd; bool needWriteDoneNotif; bool needsClose; uint16_t port; - uint8_t ip[4]; + httpd_ipaddr_t ip; }; static HttpdConnType s_rconn[HTTPD_MAX_CONNECTIONS]; diff --git a/spritehttpd/src/httpd.c b/spritehttpd/src/httpd.c index 769d1fb..efef0d2 100644 --- a/spritehttpd/src/httpd.c +++ b/spritehttpd/src/httpd.c @@ -124,17 +124,17 @@ size_t httpGetBacklogSize(const HttpdConnData *conn) } //Looks up the connData info for a specific connection -static HttpdConnData *httpdFindConnData(ConnTypePtr conn, const uint8_t *remIp, int remPort) +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 && - memcmp(s_connData[i]->remote_ip, remIp, 4) == 0) { + 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]; } } //Shouldn't happen. - http_error("*** Unknown connection %d.%d.%d.%d:%d", remIp[0] & 0xff, remIp[1] & 0xff, remIp[2] & 0xff, remIp[3] & 0xff, remPort); + http_error("Unknown connection"); httpdConnDisconnect(conn); return NULL; } @@ -501,7 +501,7 @@ static void httpdCgiIsDone(HttpdConnData *conn) //Callback called when the data on a socket has been successfully //sent. -void httpdSentCb(ConnTypePtr rconn, const uint8_t *remIp, uint16_t remPort) +void httpdSentCb(ConnTypePtr rconn, httpd_ipaddr_t remIp, uint16_t remPort) { HttpdConnData *conn = httpdFindConnData(rconn, remIp, remPort); httpdContinue(conn); @@ -511,7 +511,6 @@ void httpdSentCb(ConnTypePtr rconn, const uint8_t *remIp, uint16_t remPort) //resume handling an open connection asynchronously void httpdContinue(HttpdConnData *conn) { - int r; httpdPlatLock(); uint8_t *sendBuff; @@ -550,7 +549,7 @@ void httpdContinue(HttpdConnData *conn) } conn->priv->sendBuff = sendBuff; conn->priv->sendBuffLen = 0; - r = conn->cgi(conn); //Execute cgi fn. + httpd_cgi_state r = conn->cgi(conn); //Execute cgi fn. if (r == HTTPD_CGI_DONE) { httpdCgiIsDone(conn); } @@ -776,7 +775,7 @@ void httpdConnSendFinish(HttpdConnData *conn) } //Callback called when there's data available on a socket. -void httpdRecvCb(ConnTypePtr rconn, const uint8_t *remIp, uint16_t remPort, uint8_t *data, size_t len) +void httpdRecvCb(ConnTypePtr rconn, httpd_ipaddr_t remIp, uint16_t remPort, uint8_t *data, size_t len) { httpd_cgi_state r; size_t x; @@ -884,7 +883,7 @@ void httpdRecvCb(ConnTypePtr rconn, const uint8_t *remIp, uint16_t remPort, uint //The platform layer should ALWAYS call this function, regardless if the connection is closed by the server //or by the client. -void httpdDisconCb(ConnTypePtr rconn, const uint8_t *remIp, uint16_t remPort) +void httpdDisconCb(ConnTypePtr rconn, httpd_ipaddr_t remIp, uint16_t remPort) { httpdPlatLock(); HttpdConnData *hconn = httpdFindConnData(rconn, remIp, remPort); @@ -917,57 +916,54 @@ static void cleanupCgiAndUserData(HttpdConnData *hconn) } -int httpdConnectCb(ConnTypePtr conn, const uint8_t *remIp, uint16_t remPort) +int httpdConnectCb(ConnTypePtr conn, httpd_ipaddr_t remIp, uint16_t remPort) { - uint8_t i; + uint8_t ci; // connection index httpdPlatLock(); + //Find empty conndata in pool - for (i = 0; i < HTTPD_MAX_CONNECTIONS; i++) { - if (s_connData[i] == NULL) { + for (ci = 0; ci < HTTPD_MAX_CONNECTIONS; ci++) { + if (s_connData[ci] == NULL) { break; } } - http_info("Conn req from %d.%d.%d.%d:%d, using pool slot %d", remIp[0], remIp[1], remIp[2], remIp[3], remPort, i); - if (i >= HTTPD_MAX_CONNECTIONS) { + + http_info("Conn req from %d.%d.%d.%d:%d, using pool slot %d", IP_SPLIT(remIp), remPort, ci); + if (ci >= HTTPD_MAX_CONNECTIONS) { http_error("Aiee, conn pool overflow!"); httpdPlatUnlock(); return 0; } - s_connData[i] = httpdPlatMalloc(sizeof(HttpdConnData)); - if (s_connData[i] == NULL) { + s_connData[ci] = httpdPlatMalloc(sizeof(HttpdConnData)); + if (s_connData[ci] == NULL) { http_warn("Out of memory allocating connData!"); httpdPlatUnlock(); return 0; } - memset(s_connData[i], 0, sizeof(HttpdConnData)); - s_connData[i]->priv = httpdPlatMalloc(sizeof(HttpdPriv)); - if (s_connData[i]->priv == NULL) { + memset(s_connData[ci], 0, sizeof(HttpdConnData)); + + 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]->priv = httpdPlatMalloc(sizeof(HttpdPriv)); + if (s_connData[ci]->priv == NULL) { http_error("Out of memory allocating connData priv struct!"); httpdPlatUnlock(); return 0; } - memset(s_connData[i]->priv, 0, sizeof(HttpdPriv)); - s_connData[i]->conn = conn; - s_connData[i]->slot = i; -// s_connData[i]->priv->headPos = 0; - s_connData[i]->post = httpdPlatMalloc(sizeof(HttpdPostData)); - if (s_connData[i]->post == NULL) { + memset(s_connData[ci]->priv, 0, sizeof(HttpdPriv)); + + s_connData[ci]->post = httpdPlatMalloc(sizeof(HttpdPostData)); + if (s_connData[ci]->post == NULL) { http_error("Out of memory allocating connData post struct!"); httpdPlatUnlock(); return 0; } - memset(s_connData[i]->post, 0, sizeof(HttpdPostData)); -// s_connData[i]->post->buff = NULL; -// s_connData[i]->post->buffLen = 0; -// s_connData[i]->post->received = 0; - s_connData[i]->post->len = -1; -// s_connData[i]->hostName = NULL; - s_connData[i]->remote_port = remPort; -// s_connData[i]->priv->sendBacklog = NULL; -// s_connData[i]->priv->headersToSend = NULL; -// s_connData[i]->priv->sendBacklogSize = 0; - memcpy(s_connData[i]->remote_ip, remIp, 4); + memset(s_connData[ci]->post, 0, sizeof(HttpdPostData)); + s_connData[ci]->post->len = -1; httpdPlatUnlock(); return 1;