static void ICACHE_FLASH_ATTR http_process_disconnect_cb(void *arg) { NODE_DBG("Disconnect conn=%p",arg); http_connection *conn = http_process_find_connection(arg); if(conn!=NULL){ //is it a client connection? if(conn->espConnection== &conn->client_connection){ //tell parser about EOF http_parser_execute( &(conn->parser), &(conn->parser_settings), NULL, 0); } if (conn->parser.upgrade) { conn->state=HTTPD_STATE_WS_CLIENT_DISCONNECT; http_execute_cgi(conn); } http_process_free_connection(conn); } else{ //find connections that should be closed int i; for(i=0;i<MAX_CONNECTIONS;i++) { struct espconn *conn = connection_poll[i].espConnection; if(conn!=NULL){ if(conn->state==ESPCONN_NONE || conn->state >=ESPCONN_CLOSE){ //should close //is it a client connection? If yes, don't free if(&connection_poll[i].client_connection != connection_poll[i].espConnection) { http_process_free_connection(&connection_poll[i]); } } } } } }
//Callback called when there's data available on a socket. static void ICACHE_FLASH_ATTR http_process_received_cb(void *arg, char *data, unsigned short len) { NODE_DBG("\nhttp_process_received_cb, len: %d",len); http_connection *conn = http_process_find_connection(arg); if(conn==NULL){ espconn_disconnect(arg); return; } //pass data to http_parser size_t nparsed = http_parser_execute( &(conn->parser), &(conn->parser_settings), data, len); if (conn->parser.upgrade) { /* handle new protocol */ on_websocket_data(&conn->parser,data,len); } else if (nparsed != len) { /* Handle error. Usually just close the connection. */ espconn_disconnect(conn->espConnection); http_process_free_connection(conn); } }
static void http_ws_handle_message(http_connection *c,ws_frame *msg){ if(c->cgi.function!=NULL){ //put frame on argument c->cgi.argument=(void *)msg; //call cgi int r = c->cgi.function(c); int sent = http_transmit(c); if(r==HTTP_WS_CGI_DONE){ //we should close the socket c->cgi.done=1; if(sent==0){ //we should active close it now as no data was sent, so there will be no further callback //TODO send close frame instead of hard closing espconn_disconnect(c->espConnection); http_process_free_connection(c); } } } }
// Called after cgi execution to flush any data void ICACHE_FLASH_ATTR http_send_response(http_connection * conn){ NODE_DBG("http_send_response"); int sent = http_transmit(conn); //any data sent? if(sent == 0){ //if there was no data sent and cgi is done, we should destroy the connection if (conn->cgi.done==1) { NODE_DBG("Conn %p is done. Closing.", conn->espConnection); espconn_disconnect(conn->espConnection); http_process_free_connection(conn); return; } } }
// Called after cgi execution to flush any data void http_send_response(http_connection * conn) { HTTP_DBG("http_send_response\n"); int sent = http_transmit(conn); //any data sent? if(sent == 0) { HTTP_DBG("\tno data sent\n"); //if there was no data sent and cgi is done, we should destroy the connection if (conn->cgi.done==1) { HTTP_DBG("\t\tConn %p is done. Closing.\n", conn->espConnection); espconn_disconnect(conn->espConnection); http_process_free_connection(conn); return; } } }
//esp conn callbacks static void ICACHE_FLASH_ATTR http_process_sent_cb(void *arg) { NODE_DBG("\nhttp_process_sent_cb, conn %p",arg); http_connection *conn = http_process_find_connection(arg); if(conn==NULL) return; if (conn->cgi.done==1) { //Marked for destruction? NODE_DBG("Conn %p is done. Closing.", conn->espConnection); espconn_disconnect(conn->espConnection); http_process_free_connection(conn); return; //No need to execute cgi again }// if(conn->parser.upgrade){ conn->state = HTTPD_STATE_WS_DATA_SENT; //set state } http_execute_cgi(conn); }