diff --git a/httpd/httpd.c b/httpd/httpd.c index 73c187c..bc16649 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -366,6 +366,7 @@ static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) { if (match) { //os_printf("Is url index %d\n", i); conn->cgiData = NULL; + conn->cgiResponse = NULL; conn->cgi = builtInUrls[i].cgiCb; conn->cgiArg = builtInUrls[i].cgiArg; break; @@ -627,7 +628,8 @@ void ICACHE_FLASH_ATTR httpdInit(HttpdBuiltInUrl *fixedUrls, int port) { espconn_tcp_set_max_con_allow(&httpdConn, MAX_CONN); } -int ICACHE_FLASH_ATTR httpdNotify(uint8_t * ip, int port, const void * cgiArg) { +// looks up connection handle based on ip / port +HttpdConnData * ICACHE_FLASH_ATTR httpdLookUpConn(uint8_t * ip, int port) { int i; for (i = 0; iconn->proto.tcp->remote_ip, ip, 4) != 0) continue; - char sendBuff[MAX_SENDBUFF_LEN]; - conn->priv->sendBuff = sendBuff; - conn->priv->sendBuffLen = 0; + return conn; + } + return NULL; +} + +// this method is used for setting the response of a CGI handler outside of the HTTP callback +// this method useful at the following scenario: +// Browser -> CGI handler -> MCU request +// MCU response -> CGI handler -> browser +// when MCU response arrives, the handler looks up connection based on ip/port and call httpdSetCGIResponse with the data to transmit + +int ICACHE_FLASH_ATTR httpdSetCGIResponse(HttpdConnData * conn, void * response) { + char sendBuff[MAX_SENDBUFF_LEN]; + conn->priv->sendBuff = sendBuff; + conn->priv->sendBuffLen = 0; - conn->cgiArg = cgiArg; - httpdProcessRequest(conn); - conn->cgiArg = NULL; + conn->cgiResponse = response; + httpdProcessRequest(conn); + conn->cgiResponse = NULL; - return HTTPD_CGI_DONE; - } - return HTTPD_CGI_NOTFOUND; + return HTTPD_CGI_DONE; } diff --git a/httpd/httpd.h b/httpd/httpd.h index 1b0ed38..32d9394 100644 --- a/httpd/httpd.h +++ b/httpd/httpd.h @@ -30,6 +30,7 @@ struct HttpdConnData { const void *cgiArg; void *cgiData; void *cgiPrivData; // Used for streaming handlers storing state between requests + void *cgiResponse; // used for forwarding response to the CGI handler HttpdPriv *priv; cgiSendCallback cgi; HttpdPostData *post; @@ -66,6 +67,7 @@ void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn); int ICACHE_FLASH_ATTR httpdGetHeader(HttpdConnData *conn, char *header, char *ret, int retLen); int ICACHE_FLASH_ATTR httpdSend(HttpdConnData *conn, const char *data, int len); void ICACHE_FLASH_ATTR httpdFlush(HttpdConnData *conn); -int ICACHE_FLASH_ATTR httpdNotify(uint8_t * ip, int port, const void * cgiArg); +HttpdConnData * ICACHE_FLASH_ATTR httpdLookUpConn(uint8_t * ip, int port); +int ICACHE_FLASH_ATTR httpdSetCGIResponse(HttpdConnData * conn, void *response); #endif diff --git a/web-server/web-server.c b/web-server/web-server.c index 72ee39c..c1bfb6f 100644 --- a/web-server/web-server.c +++ b/web-server/web-server.c @@ -253,14 +253,14 @@ int ICACHE_FLASH_ATTR WEB_CgiJsonHook(HttpdConnData *connData) connData->cgiData = (void *)1; } - if( connData->cgiArg != NULL ) // arrived data from MCU + if( connData->cgiResponse != NULL ) // data from MCU { char jsonBuf[1500]; int jsonPtr = 0; jsonBuf[jsonPtr++] = '{'; - CmdRequest * req = (CmdRequest *)(connData->cgiArg); + CmdRequest * req = (CmdRequest *)(connData->cgiResponse); int c = 2; while( c++ < cmdGetArgc(req) ) @@ -378,5 +378,9 @@ void ICACHE_FLASH_ATTR WEB_Data(CmdPacket *cmd) uint16_t port; cmdPopArg(&req, &port, 2); - httpdNotify(ip, port, &req); + HttpdConnData * conn = httpdLookUpConn(ip, port); + if( conn != NULL && conn->cgi == WEB_CgiJsonHook ) // make sure that the right CGI handler will be called + httpdSetCGIResponse( conn, &req ); + else + os_printf("WEB response ignored as no valid http connection found for the request!\n"); }