static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) { #if 0 //Stupid esp sdk passes through wrong arg here, namely the one of the *listening* socket. //If it ever gets fixed, be sure to update the code in this snippet; it's probably out-of-date. HttpdConnData *conn=httpdFindConnData(arg); os_printf("Disconnected, conn=%p\n", conn); if (conn==NULL) return; conn->conn=NULL; if (conn->cgi!=NULL) conn->cgi(conn); //flush cgi data #endif //Just look at all the sockets and kill the slot if needed. int i; for (i=0; i<MAX_CONN; i++) { if (connData[i].conn!=NULL) { //Why the >=ESPCONN_CLOSE and not ==? Well, seems the stack sometimes de-allocates //espconns under our noses, especially when connections are interrupted. The memory //is then used for something else, and we can use that to capture *most* of the //disconnect cases. if (connData[i].conn->state==ESPCONN_NONE || connData[i].conn->state>=ESPCONN_CLOSE) { connData[i].conn=NULL; if (connData[i].cgi!=NULL) connData[i].cgi(&connData[i]); //flush cgi data httpdRetireConn(&connData[i]); } } } }
static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) { debugConn(arg, "httpdDisconCb"); HttpdConnData *conn = httpdFindConnData(arg); if (conn == NULL) return; if (conn->cgi != NULL) conn->cgi(conn); // free cgi data httpdRetireConn(conn); }
//Callback called when the data on a socket has been successfully //sent. static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { int r; HttpdConnData *conn=httpdFindConnData(arg); char sendBuff[MAX_SENDBUFF_LEN]; // os_printf("Sent callback on conn %p\n", conn); if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; if (conn->cgi==NULL) { //Marked for destruction? os_printf("Conn %p is done. Closing.\n", conn->conn); espconn_disconnect(conn->conn); httpdRetireConn(conn); return; //No need to call xmitSendBuff. } r=conn->cgi(conn); //Execute cgi fn. if (r==HTTPD_CGI_DONE) { conn->cgi=NULL; //mark for destruction. } if (r==HTTPD_CGI_NOTFOUND || r==HTTPD_CGI_AUTHENTICATED) { os_printf("ERROR! CGI fn returns code %d after sending data! Bad CGI!\n", r); conn->cgi=NULL; //mark for destruction. } xmitSendBuff(conn); }
//Callback called when the data on a socket has been successfully sent. static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { debugConn(arg, "httpdSentCb"); int r; HttpdConnData *conn=httpdFindConnData(arg); char sendBuff[MAX_SENDBUFF_LEN]; if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; if (conn->cgi==NULL) { //Marked for destruction? //os_printf("Closing 0x%p/0x%p->0x%p\n", arg, conn->conn, conn); espconn_disconnect(conn->conn); //httpdRetireConn(conn); // can't call this, we will get a diconnect callback! return; //No need to call xmitSendBuff. } r=conn->cgi(conn); //Execute cgi fn. if (r==HTTPD_CGI_DONE) { conn->cgi=NULL; //mark for destruction. } if (r==HTTPD_CGI_NOTFOUND || r==HTTPD_CGI_AUTHENTICATED) { os_printf("%s ERROR! CGI fn returns code %d after sending data! Bad CGI!\n", connStr, r); conn->cgi=NULL; //mark for destruction. } xmitSendBuff(conn); }
// Callback indicating a failure in the connection. "Recon" is probably intended in the sense // of "you need to reconnect". Sigh... static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { debugConn(arg, "httpdReconCb"); HttpdConnData *conn = httpdFindConnData(arg); os_printf("%s reset, err=%d\n", connStr, err); if (conn == NULL) return; conn->conn = NULL; // don't tr to send anything, the SDK crashes... if (conn->cgi != NULL) conn->cgi(conn); // free cgi data httpdRetireConn(conn); }
//Callback called when there's data available on a socket. static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { debugConn(arg, "httpdRecvCb"); int x; char *p, *e; char sendBuff[MAX_SENDBUFF_LEN]; HttpdConnData *conn=httpdFindConnData(arg); if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; //This is slightly evil/dirty: we abuse conn->post->len as a state variable for where in the http communications we are: //<0 (-1): Post len unknown because we're still receiving headers //==0: No post data //>0: Need to receive post data //ToDo: See if we can use something more elegant for this. for (x=0; x<len; x++) { if (conn->post->len<0) { //This byte is a header byte. if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x]; conn->priv->head[conn->priv->headPos]=0; //Scan for /r/n/r/n. Receiving this indicate the headers end. if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) { //Indicate we're done with the headers. conn->post->len=0; //Reset url data conn->url=NULL; //Iterate over all received headers and parse them. p=conn->priv->head; while(p<(&conn->priv->head[conn->priv->headPos-4])) { e=(char *)os_strstr(p, "\r\n"); //Find end of header line if (e==NULL) break; //Shouldn't happen. e[0]=0; //Zero-terminate header httpdParseHeader(p, conn); //and parse it. p=e+2; //Skip /r/n (now /0/n) } //If we don't need to receive post data, we can send the response now. if (conn->post->len==0) { httpdProcessRequest(conn); } } } else if (conn->post->len!=0) { //This byte is a POST byte. conn->post->buff[conn->post->buffLen++]=data[x]; conn->post->received++; if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) { //Received a chunk of post data conn->post->buff[conn->post->buffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings //Send the response. httpdProcessRequest(conn); conn->post->buffLen = 0; } } } }
//Callback called when there's data available on a socket. static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { int x; char *p, *e; char sendBuff[MAX_SENDBUFF_LEN]; HttpdConnData *conn=httpdFindConnData(arg); if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; for (x=0; x<len; x++) { if (conn->postLen<0) { //This byte is a header byte. if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x]; conn->priv->head[conn->priv->headPos]=0; //Scan for /r/n/r/n if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) { //Indicate we're done with the headers. conn->postLen=0; //Reset url data conn->url=NULL; //Find end of next header line p=conn->priv->head; while(p<(&conn->priv->head[conn->priv->headPos-4])) { e=(char *)os_strstr(p, "\r\n"); if (e==NULL) break; e[0]=0; httpdParseHeader(p, conn); p=e+2; } //If we don't need to receive post data, we can send the response now. if (conn->postLen==0) { httpdSendResp(conn); } } } else if (conn->priv->postPos!=-1 && conn->postLen!=0 && conn->priv->postPos <= conn->postLen) { //This byte is a POST byte. conn->postBuff[conn->priv->postPos++]=data[x]; if (conn->priv->postPos>=conn->postLen) { //Received post stuff. conn->postBuff[conn->priv->postPos]=0; //zero-terminate conn->priv->postPos=-1; os_printf("Post data: %s\n", conn->postBuff); //Send the response. httpdSendResp(conn); break; } } } xmitSendBuff(conn); }
/************************************************ * name: httpdReconCb * parameters: ptArgument - connection data * iError - error code * return value: none * purpose: callback on reconnect ************************************************/ static void ICACHE_FLASH_ATTR httpdReconCb(void * ptArgument, sint8 iError) { /* initialization */ HttpdConnection * ptConnection = NULL; ptConnection = httpdFindConnData(ptArgument); #ifdef HTTPD_DEBUG os_printf("httpdReconCb\n"); #endif UNUSED(ptConnection); }
//Callback called when there's data available on a socket. static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { int x; char *p, *e; char sendBuff[MAX_SENDBUFF_LEN]; HttpdConnData *conn=httpdFindConnData(arg); if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; for (x=0; x<len; x++) { if (conn->post->len<0) { //This byte is a header byte. if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x]; conn->priv->head[conn->priv->headPos]=0; //Scan for /r/n/r/n if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) { //Indicate we're done with the headers. conn->post->len=0; //Reset url data conn->url=NULL; //Find end of next header line p=conn->priv->head; while(p<(&conn->priv->head[conn->priv->headPos-4])) { e=(char *)os_strstr(p, "\r\n"); if (e==NULL) break; e[0]=0; httpdParseHeader(p, conn); p=e+2; } //If we don't need to receive post data, we can send the response now. if (conn->post->len==0) { httpdProcessRequest(conn); } } } else if (conn->post->len!=0) { //This byte is a POST byte. conn->post->buff[conn->post->buffLen++]=data[x]; conn->post->received++; if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) { //Received a chunk of post data conn->post->buff[conn->post->buffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings //Send the response. httpdProcessRequest(conn); conn->post->buffLen = 0; } } } }
static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { int r; HttpdConnData *conn=httpdFindConnData(arg); // os_printf("Sent callback on conn %p\n", conn); if (conn==NULL) return; if (conn->cgi==NULL) { //Marked for destruction? os_printf("Conn %p is done. Closing.\n", conn->conn); espconn_disconnect(conn->conn); httpdRetireConn(conn); return; } r=conn->cgi(conn); //Execute cgi fn. if (r==HTTPD_CGI_DONE) { conn->cgi=NULL; //mark for destruction. } }
/************************************************ * name: httpdSentCb * parameters: pArgument - connection data * return value: none * purpose: callback when data on socket has been successfully sent ************************************************/ static void ICACHE_FLASH_ATTR httpdSentCb(void * pArgument) { /* initialization */ int cgiResult = HTTPD_CGI_FAILED; char pbSendBuffer[HTTPD_MAX_SEND_BUFFER_LENGTH] = { 0 }; HttpdConnection * ptConnection = NULL; ptConnection = httpdFindConnData(pArgument); if (NULL == ptConnection) { goto lblCleanup; } ptConnection->ptPrivate->pbSendBuffer = pbSendBuffer; ptConnection->ptPrivate->cbSendBufferLength = 0; if (NULL == ptConnection->pfnCgi) { /* marked for destruction - no need to call xmitSendBuff */ #ifdef HTTPD_DEBUG os_printf("httpdSendCb: connection %p is done and closing.\n", ptConnection->ptEspConnection); #endif espconn_disconnect(ptConnection->ptEspConnection); httpdRetireConn(ptConnection); goto lblCleanup; } /* Execute cgi function */ cgiResult = ptConnection->pfnCgi(ptConnection); if (HTTPD_CGI_DONE == cgiResult) { /* mark for destruction */ ptConnection->pfnCgi = NULL; } xmitSendBuff(ptConnection); lblCleanup: return; }
static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) { #if 0 //Stupid esp sdk passes through wrong arg here, namely the one of the *listening* socket. //If it ever gets fixed, be sure to update the code in this snippet; it's probably out-of-date. HttpdConnData *conn=httpdFindConnData(arg); os_printf("Disconnected, conn=%p\n", conn); if (conn==NULL) return; conn->conn=NULL; if (conn->cgi!=NULL) conn->cgi(conn); //flush cgi data #endif //Just look at all the sockets and kill the slot if needed. int i; for (i=0; i<MAX_CONN; i++) { if (connData[i].conn!=NULL) { if (connData[i].conn->state==ESPCONN_NONE || connData[i].conn->state==ESPCONN_CLOSE) { connData[i].conn=NULL; if (connData[i].cgi!=NULL) connData[i].cgi(&connData[i]); //flush cgi data httpdRetireConn(&connData[i]); } } } }
//Callback called when the data on a socket has been successfully //sent. static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { int r; HttpdConnData *conn=httpdFindConnData(arg); char sendBuff[MAX_SENDBUFF_LEN]; // //INFO("Sent callback on conn %p\n", conn); if (conn==NULL) return; conn->priv->sendBuff=sendBuff; conn->priv->sendBuffLen=0; if (conn->cgi==NULL) { //Marked for destruction? //INFO("Conn %p is done. Closing.\n", conn->conn); espconn_disconnect(conn->conn); httpdRetireConn(conn); return; //No need to call xmitSendBuff. } r=conn->cgi(conn); //Execute cgi fn. if (r==HTTPD_CGI_DONE) { conn->cgi=NULL; //mark for destruction. } xmitSendBuff(conn); }
static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { HttpdConnData *conn=httpdFindConnData(arg); os_printf("ReconCb\n"); if (conn==NULL) return; //Yeah... No idea what to do here. ToDo: figure something out. }
/************************************************ * name: httpdRecvCb * parameters: ptArgument - connection data * pbData - data available * cbDataLength - data length * return value: none * purpose: callback when data available on a socket ************************************************/ static void ICACHE_FLASH_ATTR httpdRecvCb(void * ptArgument, char * pbData, unsigned short cbDataLength) { /* initialization */ int iIndex = 0; char * pbTmpHeader = NULL; char * pbEndOfHeader = NULL; char pbSendBuffer[HTTPD_MAX_SEND_BUFFER_LENGTH] = { 0 }; HttpdConnection * ptConnection = NULL; ptConnection = httpdFindConnData(ptArgument); if (NULL == ptConnection) { return; } ptConnection->ptPrivate->pbSendBuffer = pbSendBuffer; ptConnection->ptPrivate->cbSendBufferLength = 0; for (iIndex = 0; iIndex < cbDataLength; iIndex++) { if (0 > ptConnection->ptPost->cbPostLength) { /* header byte */ if (HTTPD_MAX_HEADER_LENGTH != ptConnection->ptPrivate->cbHeaderLength) { ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength++]=pbData[iIndex]; } ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength] = 0; /* scan for /r/n/r/n */ if (((*NEWLINE_SYMBOL_STRING) == pbData[iIndex]) && (NULL != (char *)os_strstr(ptConnection->ptPrivate->pbHeader, "\r\n\r\n"))) { /* indicate we're done with the headers */ ptConnection->ptPost->cbPostLength = 0; /* reset url data */ ptConnection->pszUrl = NULL; /* find end of next header line */ pbTmpHeader = ptConnection->ptPrivate->pbHeader; while (pbTmpHeader < (&ptConnection->ptPrivate->pbHeader[ptConnection->ptPrivate->cbHeaderLength-4])) { pbEndOfHeader = (char *)os_strstr(pbTmpHeader, "\r\n"); if (NULL == pbEndOfHeader) { break; } pbEndOfHeader[0] = 0; httpdParseHeader(pbTmpHeader, ptConnection); pbTmpHeader = pbEndOfHeader + 2; } /* if receive post data unncessary send the response */ if (0 == ptConnection->ptPost->cbPostLength) { httpdProcessRequest(ptConnection); } } } else if (0 != ptConnection->ptPost->cbPostLength) { /* this is a POST byte */ ptConnection->ptPost->pbBuffer[ptConnection->ptPost->cbBufferLength++] = pbData[iIndex]; ptConnection->ptPost->cbReceived++; if ((ptConnection->ptPost->cbBufferLength >= ptConnection->ptPost->cbMaxBufferSize) || (ptConnection->ptPost->cbReceived == ptConnection->ptPost->cbPostLength)) { /* received a chunk of post data */ /* zero-terminate, in case the cgi handler knows it can use strings */ ptConnection->ptPost->pbBuffer[ptConnection->ptPost->cbBufferLength] = 0; /* send the response */ httpdProcessRequest(ptConnection); ptConnection->ptPost->cbBufferLength = 0; } } } }