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]);
			}
		}
	}
}
Beispiel #2
0
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);
}
Beispiel #4
0
//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);
}
Beispiel #5
0
// 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);
}
Beispiel #6
0
//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);
}
Beispiel #8
0
/************************************************
*	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);
}
Beispiel #9
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->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.
	}
}
Beispiel #11
0
/************************************************
*	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]);
			}
		}
	}
}
Beispiel #13
0
//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.
}
Beispiel #15
0
/************************************************
*	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;
			}
		}
	}
}