diff --git a/user/cgi.c b/user/cgi.c index 0b7e8ce..eaab7d3 100644 --- a/user/cgi.c +++ b/user/cgi.c @@ -38,7 +38,7 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) { return HTTPD_CGI_DONE; } - len=httpdFindArg(connData->postBuff, "led", buff, sizeof(buff)); + len=httpdFindArg(connData->post->buff, "led", buff, sizeof(buff)); if (len!=0) { currLedState=atoi(buff); ioLed(currLedState); @@ -105,8 +105,6 @@ int ICACHE_FLASH_ATTR cgiReadFlash(HttpdConnData *connData) { if (*pos>=0x40200000+(512*1024)) return HTTPD_CGI_DONE; else return HTTPD_CGI_MORE; } -uint32_t postCounter = 0; - int ICACHE_FLASH_ATTR cgiUploadEspfs(HttpdConnData *connData) { if (connData->conn==NULL) { //Connection aborted. Clean up. @@ -114,11 +112,11 @@ int ICACHE_FLASH_ATTR cgiUploadEspfs(HttpdConnData *connData) { } SpiFlashOpResult ret; int x; - uint32_t flashOff = ESPFS_POS; - uint32_t flashSize = ESPFS_SIZE; + int flashOff = ESPFS_POS; + int flashSize = ESPFS_SIZE; //If this is the first time, erase the flash sector - if (postCounter == 0){ + if (connData->post->received == 0){ os_printf("Erasing flash at 0x%x...\n", flashOff); // Which segment are we flashing? for (x=0; xpostBuffSize==1024){ - ret=spi_flash_write((flashOff + postCounter), (uint32 *)connData->postBuff, 1024); - os_printf("Flash return %d\n", ret); - } else { - // Think we can probably use postReceived to check if it's the last chunk and then pad the original postBuff to avoid allocating another 1k of memory - char *postBuff = (char*)os_zalloc(1024); - os_printf("Mallocced buffer of 1024 bytes of last chunk.\n"); - os_memcpy(postBuff, connData->postBuff, connData->postBuffSize); - ret=spi_flash_write((flashOff + postCounter), (uint32 *)postBuff, 1024); - os_printf("Flash return %d\n", ret); - } + // The source should be 4byte aligned, so go ahead an flash whatever we have + ret=spi_flash_write((flashOff + connData->post->received), (uint32 *)connData->post->buff, connData->post->buffLen); + os_printf("Flash return %d\n", ret); // Count bytes for data - postCounter = postCounter + connData->postBuffSize;//connData->postBuff); - os_printf("Wrote %d bytes (%dB of %d)\n", connData->postBuffSize, postCounter, connData->postLen);//&connData->postBuff)); + connData->post->received += connData->post->buffSize;//connData->postBuff); + os_printf("Wrote %d bytes (%dB of %d)\n", connData->post->buffSize, connData->post->received, connData->post->len);//&connData->postBuff)); - if (postCounter == connData->postLen){ + if (connData->post->received == connData->post->len){ httpdSend(connData, "Finished uploading", -1); - postCounter=0; return HTTPD_CGI_DONE; } else { return HTTPD_CGI_MORE; diff --git a/user/cgiwifi.c b/user/cgiwifi.c index fb20347..d289ba6 100644 --- a/user/cgiwifi.c +++ b/user/cgiwifi.c @@ -187,8 +187,8 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) { return HTTPD_CGI_DONE; } - httpdFindArg(connData->postBuff, "essid", essid, sizeof(essid)); - httpdFindArg(connData->postBuff, "passwd", passwd, sizeof(passwd)); + httpdFindArg(connData->post->buff, "essid", essid, sizeof(essid)); + httpdFindArg(connData->post->buff, "passwd", passwd, sizeof(passwd)); os_strncpy((char*)stconf.ssid, essid, 32); os_strncpy((char*)stconf.password, passwd, 64); diff --git a/user/httpd.c b/user/httpd.c index d068f3a..1435bca 100644 --- a/user/httpd.c +++ b/user/httpd.c @@ -49,6 +49,7 @@ struct HttpdPriv { //Connection pool static HttpdPriv connPrivData[MAX_CONN]; static HttpdConnData connData[MAX_CONN]; +static HttpdPostData connPostData[MAX_CONN]; //Listening connection data static struct espconn httpdConn; @@ -99,8 +100,8 @@ static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) { //Retires a connection for re-use static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) { - if (conn->postBuff!=NULL) os_free(conn->postBuff); - conn->postBuff=NULL; + if (conn->post->buff!=NULL) os_free(conn->post->buff); + conn->post->buff=NULL; conn->cgi=NULL; conn->conn=NULL; } @@ -362,27 +363,27 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { //Skip trailing spaces while (h[i]!=' ') i++; //Get POST data length - conn->postLen=atoi(h+i+1); + conn->post->len=atoi(h+i+1); // Allocate the buffer - if(conn->postLen > MAX_POST){ + if(conn->post->len > MAX_POST){ // we'll stream this in in chunks - conn->postBuffSize = MAX_POST; + conn->post->buffSize = MAX_POST; }else{ - conn->postBuffSize = conn->postLen; + conn->post->buffSize = conn->post->len; } - os_printf("Mallocced buffer for %d + 1 bytes of post data.\n", conn->postBuffSize); - conn->postBuff=(char*)os_malloc(conn->postBuffSize + 1); - conn->postBuffLen=0; + os_printf("Mallocced buffer for %d + 1 bytes of post data.\n", conn->post->buffSize); + conn->post->buff=(char*)os_malloc(conn->post->buffSize + 1); + conn->post->buffLen=0; } else if (os_strncmp(h, "Content-Type: ", 14)==0) { if(os_strstr(h, "multipart/form-data")){ // It's multipart form data so let's pull out the boundary for future use char *b; if((b = os_strstr(h, "boundary=")) != NULL){ - conn->multipartBoundary = b + 7; // move the pointer 2 chars before boundary then fill them with dashes - conn->multipartBoundary[0] = '-'; - conn->multipartBoundary[1] = '-'; - os_printf("boundary = %s\n", conn->multipartBoundary); + conn->post->multipartBoundary = b + 7; // move the pointer 2 chars before boundary then fill them with dashes + conn->post->multipartBoundary[0] = '-'; + conn->post->multipartBoundary[1] = '-'; + os_printf("boundary = %s\n", conn->post->multipartBoundary); } } } @@ -400,14 +401,14 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short conn->priv->sendBuffLen=0; for (x=0; xpostLen<0) { + 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->postLen=0; + conn->post->len=0; //Reset url data conn->url=NULL; //Find end of next header line @@ -420,21 +421,20 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short p=e+2; } //If we don't need to receive post data, we can send the response now. - if (conn->postLen==0) { + if (conn->post->len==0) { httpdProcessRequest(conn); } } - } else if (conn->postLen!=0) { + } else if (conn->post->len!=0) { //This byte is a POST byte. - conn->postBuff[conn->postBuffLen++]=data[x]; - conn->postReceived++; - if (conn->postBuffLen >= conn->postBuffSize || conn->postReceived == conn->postLen) { + 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->postBuff[conn->postBuffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings - //os_printf("Post data: %s\n", conn->postBuff); + 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->postBuffLen = 0; + conn->post->buffLen = 0; } } } @@ -489,9 +489,11 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) { connData[i].priv=&connPrivData[i]; connData[i].conn=conn; connData[i].priv->headPos=0; - connData[i].postBuff=NULL; - connData[i].postBuffLen=0; - connData[i].postLen=-1; + connData[i].post=&connPostData[i]; + connData[i].post->buff=NULL; + connData[i].post->buffLen=0; + connData[i].post->received=0; + connData[i].post->len=-1; espconn_regist_recvcb(conn, httpdRecvCb); espconn_regist_reconcb(conn, httpdReconCb); diff --git a/user/httpd.h b/user/httpd.h index 2dc7e66..38e75bb 100644 --- a/user/httpd.h +++ b/user/httpd.h @@ -16,6 +16,7 @@ typedef struct HttpdPriv HttpdPriv; typedef struct HttpdConnData HttpdConnData; +typedef struct HttpdPostData HttpdPostData; typedef int (* cgiSendCallback)(HttpdConnData *connData); @@ -28,14 +29,19 @@ struct HttpdConnData { const void *cgiArg; void *cgiData; void *cgiPrivData; // Used for streaming handlers storing state between requests - char *multipartBoundary; HttpdPriv *priv; cgiSendCallback cgi; - int postLen; - int postBuffSize; // The maximum length of the post buffer - int postBuffLen; // The amount of bytes in the current post buffer - int postReceived; // The total amount of bytes received so far - char *postBuff; + HttpdPostData *post; +}; + +//A struct describing the POST data sent inside the http connection. This is used by the CGI functions +struct HttpdPostData { + int len; // POST Content-Length + int buffSize; // The maximum length of the post buffer + int buffLen; // The amount of bytes in the current post buffer + int received; // The total amount of bytes received so far + char *buff; // Actual POST data buffer + char *multipartBoundary; }; //A struct describing an url. This is the main struct that's used to send different URL requests to