diff --git a/README b/README index c109840..d681591 100644 --- a/README +++ b/README @@ -76,3 +76,12 @@ WRITING CODE FOR THE WEBSERVER the SDK works, this shouldn't be too hard :P +CHANGE FROM SDK 0.9.3 (and earlier) TO SDK 0.9.4: +Change all occurences of +espconn_sent(connData->conn, (uint8 *)buff, len); +to +httpdSend(connData, buff, len) +please. The reason for this is that you can't do multiple espconn_sent calls serially anymore, so +httpd needs to buffer the writes now. + + diff --git a/user/auth.c b/user/auth.c index dbe00e3..5948805 100644 --- a/user/auth.c +++ b/user/auth.c @@ -62,7 +62,7 @@ int ICACHE_FLASH_ATTR authBasic(HttpdConnData *connData) { httpdHeader(connData, "Content-Type", "text/plain"); httpdHeader(connData, "WWW-Authenticate", "Basic realm=\""HTTP_AUTH_REALM"\""); httpdEndHeaders(connData); - espconn_sent(connData->conn, (uint8 *)forbidden, os_strlen(forbidden)); + httpdSend(connData, forbidden, -1); //Okay, all done. return HTTPD_CGI_DONE; } diff --git a/user/cgi.c b/user/cgi.c index 083f92b..3587cc7 100644 --- a/user/cgi.c +++ b/user/cgi.c @@ -62,7 +62,7 @@ void ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) os_strcpy(buff, "off"); } } - espconn_sent(connData->conn, (uint8 *)buff, os_strlen(buff)); + httpdSend(connData, buff, -1); } static long hitCounter=0; @@ -76,7 +76,7 @@ void ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **a hitCounter++; os_sprintf(buff, "%ld", hitCounter); } - espconn_sent(connData->conn, (uint8 *)buff, os_strlen(buff)); + httpdSend(connData, buff, -1); } diff --git a/user/cgiwifi.c b/user/cgiwifi.c index 3744e21..f67f6c4 100644 --- a/user/cgiwifi.c +++ b/user/cgiwifi.c @@ -115,21 +115,21 @@ int ICACHE_FLASH_ATTR cgiWiFiScan(HttpdConnData *connData) { if (cgiWifiAps.scanInProgress==1) { //We're still scanning. Tell Javascript code that. len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"1\"\n }\n}\n"); - espconn_sent(connData->conn, (uint8 *)buff, len); + httpdSend(connData, buff, len); } else { //We have a scan result. Pass it on. len=os_sprintf(buff, "{\n \"result\": { \n\"inProgress\": \"0\", \n\"APs\": [\n"); - espconn_sent(connData->conn, (uint8 *)buff, len); + httpdSend(connData, buff, len); if (cgiWifiAps.apData==NULL) cgiWifiAps.noAps=0; for (i=0; issid, cgiWifiAps.apData[i]->rssi, cgiWifiAps.apData[i]->enc, (i==cgiWifiAps.noAps-1)?"":","); - espconn_sent(connData->conn, (uint8 *)buff, len); + httpdSend(connData, buff, len); } len=os_sprintf(buff, "]\n}\n}\n"); - espconn_sent(connData->conn, (uint8 *)buff, len); + httpdSend(connData, buff, len); //Also start a new scan. wifiStartScan(); } @@ -256,7 +256,7 @@ void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) os_strcpy(buff, "Click here to go to standalone AP mode."); } } - espconn_sent(connData->conn, (uint8 *)buff, os_strlen(buff)); + httpdSend(connData, buff, -1); } diff --git a/user/httpd.c b/user/httpd.c index 4d050ed..58b6d17 100644 --- a/user/httpd.c +++ b/user/httpd.c @@ -31,6 +31,9 @@ Esp8266 http server - core routines #define MAX_CONN 8 //Max post buffer len #define MAX_POST 1024 +//Max send buffer len +#define MAX_SENDBUFF_LEN 2048 + //This gets set at init time. static HttpdBuiltInUrl *builtInUrls; @@ -40,6 +43,8 @@ struct HttpdPriv { char head[MAX_HEAD_LEN]; int headPos; int postPos; + char *sendBuff; + int sendBuffLen; }; //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) { char buff[128]; 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); - espconn_sent(conn->conn, (uint8 *)buff, l); + httpdSend(conn, buff, l); } //Send a http header. @@ -206,12 +209,12 @@ void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const int l; l=os_sprintf(buff, "%s: %s\r\n", field, val); - espconn_sent(conn->conn, (uint8 *)buff, l); + httpdSend(conn, buff, l); } //Finish the headers. 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' :/ @@ -220,7 +223,7 @@ void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl) { char buff[1024]; int l; 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. @@ -229,29 +232,54 @@ int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData) { //Connection aborted. Clean up. return HTTPD_CGI_DONE; } - httpdRedirect(connData, (char*)connData->cgiArg); 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 //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; + 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 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 :/ 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 } @@ -329,13 +357,16 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { } } + //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; xpriv->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); //Send the response. httpdSendResp(conn); - return; + break; } } } + xmitSendBuff(conn); } static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { diff --git a/user/httpd.h b/user/httpd.h index 5371bce..0e929c4 100644 --- a/user/httpd.h +++ b/user/httpd.h @@ -47,5 +47,6 @@ void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code); void ICACHE_FLASH_ATTR httpdHeader(HttpdConnData *conn, const char *field, const char *val); 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); #endif \ No newline at end of file diff --git a/user/httpdespfs.c b/user/httpdespfs.c index 27c6c86..7b01130 100644 --- a/user/httpdespfs.c +++ b/user/httpdespfs.c @@ -115,7 +115,7 @@ int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) { //Inside ordinary text. if (buff[x]=='%') { //Send raw data up to now - if (sp!=0) espconn_sent(connData->conn, (uint8 *)e, sp); + if (sp!=0) httpdSend(connData, e, sp); sp=0; //Go collect token chars. tpd->tokenPos=0; @@ -127,7 +127,7 @@ int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) { if (tpd->tokenPos==0) { //This is the second % of a %% escape string. //Send a single % and resume with the normal program flow. - espconn_sent(connData->conn, (uint8 *)"%", 1); + httpdSend(connData, "%", 1); } else { //This is an actual token. tpd->token[tpd->tokenPos++]=0; //zero-terminate token @@ -143,7 +143,7 @@ int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) { } } //Send remaining bit. - if (sp!=0) espconn_sent(connData->conn, (uint8 *)e, sp); + if (sp!=0) httpdSend(connData, e, sp); if (len!=1024) { //We're done. ((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);