|  |  | @ -31,6 +31,9 @@ Esp8266 http server - core routines | 
			
		
	
		
		
			
				
					
					|  |  |  | #define MAX_CONN 8 |  |  |  | #define MAX_CONN 8 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Max post buffer len
 |  |  |  | //Max post buffer len
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #define MAX_POST 1024 |  |  |  | #define MAX_POST 1024 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //Max send buffer len
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | #define MAX_SENDBUFF_LEN 2048 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //This gets set at init time.
 |  |  |  | //This gets set at init time.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static HttpdBuiltInUrl *builtInUrls; |  |  |  | static HttpdBuiltInUrl *builtInUrls; | 
			
		
	
	
		
		
			
				
					|  |  | @ -40,6 +43,8 @@ struct HttpdPriv { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char head[MAX_HEAD_LEN]; |  |  |  | 	char head[MAX_HEAD_LEN]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int headPos; |  |  |  | 	int headPos; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int postPos; |  |  |  | 	int postPos; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char *sendBuff; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	int sendBuffLen; | 
			
		
	
		
		
			
				
					
					|  |  |  | }; |  |  |  | }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Connection pool
 |  |  |  | //Connection pool
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -194,10 +199,8 @@ int ICACHE_FLASH_ATTR httpdGetHeader(HttpdConnData *conn, char *header, char *re | 
			
		
	
		
		
			
				
					
					|  |  |  | void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) { |  |  |  | void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char buff[128]; |  |  |  | 	char buff[128]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int l; |  |  |  | 	int l; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)"Hello", 5); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)"World", 5); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	l=os_sprintf(buff, "HTTP/1.0 %d OK\r\nServer: esp8266-httpd/"HTTPDVER"\r\n", code); |  |  |  | 	l=os_sprintf(buff, "HTTP/1.0 %d OK\r\nServer: esp8266-httpd/"HTTPDVER"\r\n", code); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)buff, l); |  |  |  | 	httpdSend(conn, buff, l); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Send a http header.
 |  |  |  | //Send a http header.
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -206,12 +209,12 @@ void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int l; |  |  |  | 	int l; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	l=os_sprintf(buff, "%s: %s\r\n", field, val); |  |  |  | 	l=os_sprintf(buff, "%s: %s\r\n", field, val); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)buff, l); |  |  |  | 	httpdSend(conn, buff, l); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Finish the headers.
 |  |  |  | //Finish the headers.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) { |  |  |  | void ICACHE_FLASH_ATTR httpdEndHeaders(HttpdConnData *conn) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)"\r\n", 2); |  |  |  | 	httpdSend(conn, "\r\n", -1); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //ToDo: sprintf->snprintf everywhere... esp doesn't have snprintf tho' :/
 |  |  |  | //ToDo: sprintf->snprintf everywhere... esp doesn't have snprintf tho' :/
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -220,7 +223,7 @@ void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char buff[1024]; |  |  |  | 	char buff[1024]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int l; |  |  |  | 	int l; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	l=os_sprintf(buff, "HTTP/1.1 302 Found\r\nLocation: %s\r\n\r\nMoved to %s\r\n", newUrl, newUrl); |  |  |  | 	l=os_sprintf(buff, "HTTP/1.1 302 Found\r\nLocation: %s\r\n\r\nMoved to %s\r\n", newUrl, newUrl); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)buff, l); |  |  |  | 	httpdSend(conn, buff, l); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Use this as a cgi function to redirect one url to another.
 |  |  |  | //Use this as a cgi function to redirect one url to another.
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -229,29 +232,54 @@ int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		//Connection aborted. Clean up.
 |  |  |  | 		//Connection aborted. Clean up.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return HTTPD_CGI_DONE; |  |  |  | 		return HTTPD_CGI_DONE; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 	httpdRedirect(connData, (char*)connData->cgiArg); |  |  |  | 	httpdRedirect(connData, (char*)connData->cgiArg); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	return HTTPD_CGI_DONE; |  |  |  | 	return HTTPD_CGI_DONE; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //Add data to the send buffer. len is the length of the data. If len is -1
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //the data is seen as a C-string.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //Returns 1 for success, 0 for out-of-memory.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | int ICACHE_FLASH_ATTR httpdSend(HttpdConnData *conn, const char *data, int len) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (len<0) len=strlen(data); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (conn->priv->sendBuffLen+len>MAX_SENDBUFF_LEN) return 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	os_memcpy(conn->priv->sendBuff+conn->priv->sendBuffLen, data, len); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	conn->priv->sendBuffLen+=len; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	return 1; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | //Helper function to send any data in conn->priv->sendBuff
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | static void ICACHE_FLASH_ATTR xmitSendBuff(HttpdConnData *conn) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	if (conn->priv->sendBuffLen!=0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		espconn_sent(conn->conn, (uint8_t*)conn->priv->sendBuff, conn->priv->sendBuffLen); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 		conn->priv->sendBuffLen=0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Callback called when the data on a socket has been successfully
 |  |  |  | //Callback called when the data on a socket has been successfully
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //sent.
 |  |  |  | //sent.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { |  |  |  | static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int r; |  |  |  | 	int r; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	HttpdConnData *conn=httpdFindConnData(arg); |  |  |  | 	HttpdConnData *conn=httpdFindConnData(arg); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char sendBuff[MAX_SENDBUFF_LEN]; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //	os_printf("Sent callback on conn %p\n", conn);
 |  |  |  | //	os_printf("Sent callback on conn %p\n", conn);
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (conn==NULL) return; |  |  |  | 	if (conn==NULL) return; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	conn->priv->sendBuff=sendBuff; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	conn->priv->sendBuffLen=0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (conn->cgi==NULL) { //Marked for destruction?
 |  |  |  | 	if (conn->cgi==NULL) { //Marked for destruction?
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 		os_printf("Conn %p is done. Closing.\n", conn->conn); |  |  |  | 		os_printf("Conn %p is done. Closing.\n", conn->conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		espconn_disconnect(conn->conn); |  |  |  | 		espconn_disconnect(conn->conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		httpdRetireConn(conn); |  |  |  | 		httpdRetireConn(conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | 		return; |  |  |  | 		return; //No need to call xmitSendBuff.
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	r=conn->cgi(conn); //Execute cgi fn.
 |  |  |  | 	r=conn->cgi(conn); //Execute cgi fn.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (r==HTTPD_CGI_DONE) { |  |  |  | 	if (r==HTTPD_CGI_DONE) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		conn->cgi=NULL; //mark for destruction.
 |  |  |  | 		conn->cgi=NULL; //mark for destruction.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	xmitSendBuff(conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nServer: esp8266-httpd/0.1\r\nContent-Type: text/plain\r\n\r\nNot Found.\r\n"; |  |  |  | static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nServer: esp8266-httpd/0.1\r\nContent-Type: text/plain\r\n\r\nNot Found.\r\n"; | 
			
		
	
	
		
		
			
				
					|  |  | @ -283,7 +311,7 @@ static void ICACHE_FLASH_ATTR httpdSendResp(HttpdConnData *conn) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	//Can't find :/
 |  |  |  | 	//Can't find :/
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	os_printf("%s not found. 404!\n", conn->url); |  |  |  | 	os_printf("%s not found. 404!\n", conn->url); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	espconn_sent(conn->conn, (uint8 *)httpNotFoundHeader, os_strlen(httpNotFoundHeader)); |  |  |  | 	httpdSend(conn, httpNotFoundHeader, -1); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 	conn->cgi=NULL; //mark for destruction
 |  |  |  | 	conn->cgi=NULL; //mark for destruction
 | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -329,13 +357,16 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | //Callback called when there's data available on a socket.
 |  |  |  | //Callback called when there's data available on a socket.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { |  |  |  | static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short len) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 	int x; |  |  |  | 	int x; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	char *p, *e; |  |  |  | 	char *p, *e; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	char sendBuff[MAX_SENDBUFF_LEN]; | 
			
		
	
		
		
			
				
					
					|  |  |  | 	HttpdConnData *conn=httpdFindConnData(arg); |  |  |  | 	HttpdConnData *conn=httpdFindConnData(arg); | 
			
		
	
		
		
			
				
					
					|  |  |  | 	if (conn==NULL) return; |  |  |  | 	if (conn==NULL) return; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 	conn->priv->sendBuff=sendBuff; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	conn->priv->sendBuffLen=0; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 	for (x=0; x<len; x++) { |  |  |  | 	for (x=0; x<len; x++) { | 
			
		
	
		
		
			
				
					
					|  |  |  | 		if (conn->priv->headPos!=-1) { |  |  |  | 		if (conn->priv->headPos!=-1) { | 
			
		
	
	
		
		
			
				
					|  |  | @ -371,10 +402,11 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short | 
			
		
	
		
		
			
				
					
					|  |  |  | 				os_printf("Post data: %s\n", conn->postBuff); |  |  |  | 				os_printf("Post data: %s\n", conn->postBuff); | 
			
		
	
		
		
			
				
					
					|  |  |  | 				//Send the response.
 |  |  |  | 				//Send the response.
 | 
			
		
	
		
		
			
				
					
					|  |  |  | 				httpdSendResp(conn); |  |  |  | 				httpdSendResp(conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | 				return; |  |  |  | 				break; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | 			} |  |  |  | 			} | 
			
		
	
		
		
			
				
					
					|  |  |  | 		} |  |  |  | 		} | 
			
		
	
		
		
			
				
					
					|  |  |  | 	} |  |  |  | 	} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 	xmitSendBuff(conn); | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { |  |  |  | static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { | 
			
		
	
	
		
		
			
				
					|  |  | 
 |