Merge pull request #5 from billprozac/streaming
Merge updates from @billprozac
This commit is contained in:
+10
-22
@@ -38,7 +38,7 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
|
|||||||
return HTTPD_CGI_DONE;
|
return HTTPD_CGI_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
len=httpdFindArg(connData->postBuff, "led", buff, sizeof(buff));
|
len=httpdFindArg(connData->post->buff, "led", buff, sizeof(buff));
|
||||||
if (len!=0) {
|
if (len!=0) {
|
||||||
currLedState=atoi(buff);
|
currLedState=atoi(buff);
|
||||||
ioLed(currLedState);
|
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;
|
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) {
|
int ICACHE_FLASH_ATTR cgiUploadEspfs(HttpdConnData *connData) {
|
||||||
if (connData->conn==NULL) {
|
if (connData->conn==NULL) {
|
||||||
//Connection aborted. Clean up.
|
//Connection aborted. Clean up.
|
||||||
@@ -114,11 +112,11 @@ int ICACHE_FLASH_ATTR cgiUploadEspfs(HttpdConnData *connData) {
|
|||||||
}
|
}
|
||||||
SpiFlashOpResult ret;
|
SpiFlashOpResult ret;
|
||||||
int x;
|
int x;
|
||||||
uint32_t flashOff = ESPFS_POS;
|
int flashOff = ESPFS_POS;
|
||||||
uint32_t flashSize = ESPFS_SIZE;
|
int flashSize = ESPFS_SIZE;
|
||||||
|
|
||||||
//If this is the first time, erase the flash sector
|
//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);
|
os_printf("Erasing flash at 0x%x...\n", flashOff);
|
||||||
// Which segment are we flashing?
|
// Which segment are we flashing?
|
||||||
for (x=0; x<flashSize; x+=4096){
|
for (x=0; x<flashSize; x+=4096){
|
||||||
@@ -127,26 +125,16 @@ int ICACHE_FLASH_ATTR cgiUploadEspfs(HttpdConnData *connData) {
|
|||||||
os_printf("Done erasing.\n");
|
os_printf("Done erasing.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Because we get sent 1k chunks until the end, if data is less than 1k, we pad it as it must be the end...right???
|
// The source should be 4byte aligned, so go ahead an flash whatever we have
|
||||||
if (connData->postBuffSize==1024){
|
ret=spi_flash_write((flashOff + connData->post->received), (uint32 *)connData->post->buff, connData->post->buffLen);
|
||||||
ret=spi_flash_write((flashOff + postCounter), (uint32 *)connData->postBuff, 1024);
|
os_printf("Flash return %d\n", ret);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count bytes for data
|
// Count bytes for data
|
||||||
postCounter = postCounter + connData->postBuffSize;//connData->postBuff);
|
connData->post->received += connData->post->buffSize;//connData->postBuff);
|
||||||
os_printf("Wrote %d bytes (%dB of %d)\n", connData->postBuffSize, postCounter, connData->postLen);//&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);
|
httpdSend(connData, "Finished uploading", -1);
|
||||||
postCounter=0;
|
|
||||||
return HTTPD_CGI_DONE;
|
return HTTPD_CGI_DONE;
|
||||||
} else {
|
} else {
|
||||||
return HTTPD_CGI_MORE;
|
return HTTPD_CGI_MORE;
|
||||||
|
|||||||
+2
-2
@@ -187,8 +187,8 @@ int ICACHE_FLASH_ATTR cgiWiFiConnect(HttpdConnData *connData) {
|
|||||||
return HTTPD_CGI_DONE;
|
return HTTPD_CGI_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
httpdFindArg(connData->postBuff, "essid", essid, sizeof(essid));
|
httpdFindArg(connData->post->buff, "essid", essid, sizeof(essid));
|
||||||
httpdFindArg(connData->postBuff, "passwd", passwd, sizeof(passwd));
|
httpdFindArg(connData->post->buff, "passwd", passwd, sizeof(passwd));
|
||||||
|
|
||||||
os_strncpy((char*)stconf.ssid, essid, 32);
|
os_strncpy((char*)stconf.ssid, essid, 32);
|
||||||
os_strncpy((char*)stconf.password, passwd, 64);
|
os_strncpy((char*)stconf.password, passwd, 64);
|
||||||
|
|||||||
+28
-26
@@ -49,6 +49,7 @@ struct HttpdPriv {
|
|||||||
//Connection pool
|
//Connection pool
|
||||||
static HttpdPriv connPrivData[MAX_CONN];
|
static HttpdPriv connPrivData[MAX_CONN];
|
||||||
static HttpdConnData connData[MAX_CONN];
|
static HttpdConnData connData[MAX_CONN];
|
||||||
|
static HttpdPostData connPostData[MAX_CONN];
|
||||||
|
|
||||||
//Listening connection data
|
//Listening connection data
|
||||||
static struct espconn httpdConn;
|
static struct espconn httpdConn;
|
||||||
@@ -99,8 +100,8 @@ static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) {
|
|||||||
|
|
||||||
//Retires a connection for re-use
|
//Retires a connection for re-use
|
||||||
static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
|
static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) {
|
||||||
if (conn->postBuff!=NULL) os_free(conn->postBuff);
|
if (conn->post->buff!=NULL) os_free(conn->post->buff);
|
||||||
conn->postBuff=NULL;
|
conn->post->buff=NULL;
|
||||||
conn->cgi=NULL;
|
conn->cgi=NULL;
|
||||||
conn->conn=NULL;
|
conn->conn=NULL;
|
||||||
}
|
}
|
||||||
@@ -362,27 +363,27 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
|
|||||||
//Skip trailing spaces
|
//Skip trailing spaces
|
||||||
while (h[i]!=' ') i++;
|
while (h[i]!=' ') i++;
|
||||||
//Get POST data length
|
//Get POST data length
|
||||||
conn->postLen=atoi(h+i+1);
|
conn->post->len=atoi(h+i+1);
|
||||||
|
|
||||||
// Allocate the buffer
|
// Allocate the buffer
|
||||||
if(conn->postLen > MAX_POST){
|
if(conn->post->len > MAX_POST){
|
||||||
// we'll stream this in in chunks
|
// we'll stream this in in chunks
|
||||||
conn->postBuffSize = MAX_POST;
|
conn->post->buffSize = MAX_POST;
|
||||||
}else{
|
}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);
|
os_printf("Mallocced buffer for %d + 1 bytes of post data.\n", conn->post->buffSize);
|
||||||
conn->postBuff=(char*)os_malloc(conn->postBuffSize + 1);
|
conn->post->buff=(char*)os_malloc(conn->post->buffSize + 1);
|
||||||
conn->postBuffLen=0;
|
conn->post->buffLen=0;
|
||||||
} else if (os_strncmp(h, "Content-Type: ", 14)==0) {
|
} else if (os_strncmp(h, "Content-Type: ", 14)==0) {
|
||||||
if(os_strstr(h, "multipart/form-data")){
|
if(os_strstr(h, "multipart/form-data")){
|
||||||
// It's multipart form data so let's pull out the boundary for future use
|
// It's multipart form data so let's pull out the boundary for future use
|
||||||
char *b;
|
char *b;
|
||||||
if((b = os_strstr(h, "boundary=")) != NULL){
|
if((b = os_strstr(h, "boundary=")) != NULL){
|
||||||
conn->multipartBoundary = b + 7; // move the pointer 2 chars before boundary then fill them with dashes
|
conn->post->multipartBoundary = b + 7; // move the pointer 2 chars before boundary then fill them with dashes
|
||||||
conn->multipartBoundary[0] = '-';
|
conn->post->multipartBoundary[0] = '-';
|
||||||
conn->multipartBoundary[1] = '-';
|
conn->post->multipartBoundary[1] = '-';
|
||||||
os_printf("boundary = %s\n", conn->multipartBoundary);
|
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;
|
conn->priv->sendBuffLen=0;
|
||||||
|
|
||||||
for (x=0; x<len; x++) {
|
for (x=0; x<len; x++) {
|
||||||
if (conn->postLen<0) {
|
if (conn->post->len<0) {
|
||||||
//This byte is a header byte.
|
//This byte is a header byte.
|
||||||
if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x];
|
if (conn->priv->headPos!=MAX_HEAD_LEN) conn->priv->head[conn->priv->headPos++]=data[x];
|
||||||
conn->priv->head[conn->priv->headPos]=0;
|
conn->priv->head[conn->priv->headPos]=0;
|
||||||
//Scan for /r/n/r/n
|
//Scan for /r/n/r/n
|
||||||
if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) {
|
if (data[x]=='\n' && (char *)os_strstr(conn->priv->head, "\r\n\r\n")!=NULL) {
|
||||||
//Indicate we're done with the headers.
|
//Indicate we're done with the headers.
|
||||||
conn->postLen=0;
|
conn->post->len=0;
|
||||||
//Reset url data
|
//Reset url data
|
||||||
conn->url=NULL;
|
conn->url=NULL;
|
||||||
//Find end of next header line
|
//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;
|
p=e+2;
|
||||||
}
|
}
|
||||||
//If we don't need to receive post data, we can send the response now.
|
//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);
|
httpdProcessRequest(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (conn->postLen!=0) {
|
} else if (conn->post->len!=0) {
|
||||||
//This byte is a POST byte.
|
//This byte is a POST byte.
|
||||||
conn->postBuff[conn->postBuffLen++]=data[x];
|
conn->post->buff[conn->post->buffLen++]=data[x];
|
||||||
conn->postReceived++;
|
conn->post->received++;
|
||||||
if (conn->postBuffLen >= conn->postBuffSize || conn->postReceived == conn->postLen) {
|
if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) {
|
||||||
//Received a chunk of post data
|
//Received a chunk of post data
|
||||||
conn->postBuff[conn->postBuffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings
|
conn->post->buff[conn->post->buffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings
|
||||||
//os_printf("Post data: %s\n", conn->postBuff);
|
|
||||||
//Send the response.
|
//Send the response.
|
||||||
httpdProcessRequest(conn);
|
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].priv=&connPrivData[i];
|
||||||
connData[i].conn=conn;
|
connData[i].conn=conn;
|
||||||
connData[i].priv->headPos=0;
|
connData[i].priv->headPos=0;
|
||||||
connData[i].postBuff=NULL;
|
connData[i].post=&connPostData[i];
|
||||||
connData[i].postBuffLen=0;
|
connData[i].post->buff=NULL;
|
||||||
connData[i].postLen=-1;
|
connData[i].post->buffLen=0;
|
||||||
|
connData[i].post->received=0;
|
||||||
|
connData[i].post->len=-1;
|
||||||
|
|
||||||
espconn_regist_recvcb(conn, httpdRecvCb);
|
espconn_regist_recvcb(conn, httpdRecvCb);
|
||||||
espconn_regist_reconcb(conn, httpdReconCb);
|
espconn_regist_reconcb(conn, httpdReconCb);
|
||||||
|
|||||||
+12
-6
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
typedef struct HttpdPriv HttpdPriv;
|
typedef struct HttpdPriv HttpdPriv;
|
||||||
typedef struct HttpdConnData HttpdConnData;
|
typedef struct HttpdConnData HttpdConnData;
|
||||||
|
typedef struct HttpdPostData HttpdPostData;
|
||||||
|
|
||||||
typedef int (* cgiSendCallback)(HttpdConnData *connData);
|
typedef int (* cgiSendCallback)(HttpdConnData *connData);
|
||||||
|
|
||||||
@@ -28,14 +29,19 @@ struct HttpdConnData {
|
|||||||
const void *cgiArg;
|
const void *cgiArg;
|
||||||
void *cgiData;
|
void *cgiData;
|
||||||
void *cgiPrivData; // Used for streaming handlers storing state between requests
|
void *cgiPrivData; // Used for streaming handlers storing state between requests
|
||||||
char *multipartBoundary;
|
|
||||||
HttpdPriv *priv;
|
HttpdPriv *priv;
|
||||||
cgiSendCallback cgi;
|
cgiSendCallback cgi;
|
||||||
int postLen;
|
HttpdPostData *post;
|
||||||
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
|
//A struct describing the POST data sent inside the http connection. This is used by the CGI functions
|
||||||
char *postBuff;
|
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
|
//A struct describing an url. This is the main struct that's used to send different URL requests to
|
||||||
|
|||||||
Reference in New Issue
Block a user