Refactor to make all requests able to handle streaming as it makes the code much simpler
This commit is contained in:
+7
-5
@@ -50,9 +50,9 @@ int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) {
|
|||||||
|
|
||||||
|
|
||||||
//Template code for the led page.
|
//Template code for the led page.
|
||||||
void ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) {
|
int ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg) {
|
||||||
char buff[128];
|
char buff[128];
|
||||||
if (token==NULL) return;
|
if (token==NULL) return HTTPD_CGI_DONE;
|
||||||
|
|
||||||
os_strcpy(buff, "Unknown");
|
os_strcpy(buff, "Unknown");
|
||||||
if (os_strcmp(token, "ledstate")==0) {
|
if (os_strcmp(token, "ledstate")==0) {
|
||||||
@@ -63,20 +63,22 @@ void ICACHE_FLASH_ATTR tplLed(HttpdConnData *connData, char *token, void **arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
httpdSend(connData, buff, -1);
|
httpdSend(connData, buff, -1);
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long hitCounter=0;
|
static long hitCounter=0;
|
||||||
|
|
||||||
//Template code for the counter on the index page.
|
//Template code for the counter on the index page.
|
||||||
void ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg) {
|
int ICACHE_FLASH_ATTR tplCounter(HttpdConnData *connData, char *token, void **arg) {
|
||||||
char buff[128];
|
char buff[128];
|
||||||
if (token==NULL) return;
|
if (token==NULL) return HTTPD_CGI_DONE;
|
||||||
|
|
||||||
if (os_strcmp(token, "counter")==0) {
|
if (os_strcmp(token, "counter")==0) {
|
||||||
hitCounter++;
|
hitCounter++;
|
||||||
os_sprintf(buff, "%ld", hitCounter);
|
os_sprintf(buff, "%ld", hitCounter);
|
||||||
}
|
}
|
||||||
httpdSend(connData, buff, -1);
|
httpdSend(connData, buff, -1);
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -232,7 +234,7 @@ int ICACHE_FLASH_ATTR updateWeb(HttpdConnData *connData) {
|
|||||||
if (connData->cgiPrivData!=NULL) os_free(connData->cgiPrivData);
|
if (connData->cgiPrivData!=NULL) os_free(connData->cgiPrivData);
|
||||||
return HTTPD_CGI_DONE;
|
return HTTPD_CGI_DONE;
|
||||||
}else{
|
}else{
|
||||||
return HTTPD_CGI_NOTDONE;
|
return HTTPD_CGI_MORE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return HTTPD_CGI_DONE;
|
return HTTPD_CGI_DONE;
|
||||||
|
|||||||
+2
-2
@@ -4,9 +4,9 @@
|
|||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
|
|
||||||
int cgiLed(HttpdConnData *connData);
|
int cgiLed(HttpdConnData *connData);
|
||||||
void tplLed(HttpdConnData *connData, char *token, void **arg);
|
int tplLed(HttpdConnData *connData, char *token, void **arg);
|
||||||
int cgiReadFlash(HttpdConnData *connData);
|
int cgiReadFlash(HttpdConnData *connData);
|
||||||
void tplCounter(HttpdConnData *connData, char *token, void **arg);
|
int tplCounter(HttpdConnData *connData, char *token, void **arg);
|
||||||
int updateWeb(HttpdConnData *connData);
|
int updateWeb(HttpdConnData *connData);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+3
-2
@@ -231,11 +231,11 @@ int ICACHE_FLASH_ATTR cgiWifiSetMode(HttpdConnData *connData) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Template code for the WLAN page.
|
//Template code for the WLAN page.
|
||||||
void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) {
|
int ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg) {
|
||||||
char buff[1024];
|
char buff[1024];
|
||||||
int x;
|
int x;
|
||||||
static struct station_config stconf;
|
static struct station_config stconf;
|
||||||
if (token==NULL) return;
|
if (token==NULL) return HTTPD_CGI_DONE;
|
||||||
wifi_station_get_config(&stconf);
|
wifi_station_get_config(&stconf);
|
||||||
|
|
||||||
os_strcpy(buff, "Unknown");
|
os_strcpy(buff, "Unknown");
|
||||||
@@ -257,6 +257,7 @@ void ICACHE_FLASH_ATTR tplWlan(HttpdConnData *connData, char *token, void **arg)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
httpdSend(connData, buff, -1);
|
httpdSend(connData, buff, -1);
|
||||||
|
return HTTPD_CGI_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
#include "httpd.h"
|
#include "httpd.h"
|
||||||
|
|
||||||
int cgiWiFiScan(HttpdConnData *connData);
|
int cgiWiFiScan(HttpdConnData *connData);
|
||||||
void tplWlan(HttpdConnData *connData, char *token, void **arg);
|
int tplWlan(HttpdConnData *connData, char *token, void **arg);
|
||||||
int cgiWiFi(HttpdConnData *connData);
|
int cgiWiFi(HttpdConnData *connData);
|
||||||
int cgiWiFiConnect(HttpdConnData *connData);
|
int cgiWiFiConnect(HttpdConnData *connData);
|
||||||
int cgiWifiSetMode(HttpdConnData *connData);
|
int cgiWifiSetMode(HttpdConnData *connData);
|
||||||
|
|||||||
+25
-45
@@ -30,7 +30,7 @@ Esp8266 http server - core routines
|
|||||||
//Max amount of connections
|
//Max amount of connections
|
||||||
#define MAX_CONN 8
|
#define MAX_CONN 8
|
||||||
//Max post buffer len
|
//Max post buffer len
|
||||||
#define MAX_POST 1460
|
#define MAX_POST 1024
|
||||||
//Max send buffer len
|
//Max send buffer len
|
||||||
#define MAX_SENDBUFF_LEN 2048
|
#define MAX_SENDBUFF_LEN 2048
|
||||||
|
|
||||||
@@ -42,7 +42,6 @@ static HttpdBuiltInUrl *builtInUrls;
|
|||||||
struct HttpdPriv {
|
struct HttpdPriv {
|
||||||
char head[MAX_HEAD_LEN];
|
char head[MAX_HEAD_LEN];
|
||||||
int headPos;
|
int headPos;
|
||||||
int postPos;
|
|
||||||
char *sendBuff;
|
char *sendBuff;
|
||||||
int sendBuffLen;
|
int sendBuffLen;
|
||||||
};
|
};
|
||||||
@@ -287,22 +286,21 @@ static const char *httpNotFoundHeader="HTTP/1.0 404 Not Found\r\nServer: esp8266
|
|||||||
|
|
||||||
//This is called when the headers have been received and the connection is ready to send
|
//This is called when the headers have been received and the connection is ready to send
|
||||||
//the result headers and data.
|
//the result headers and data.
|
||||||
static void ICACHE_FLASH_ATTR httpdSendResp(HttpdConnData *conn) {
|
static void ICACHE_FLASH_ATTR httpdProcessRequest(HttpdConnData *conn) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
r=conn->cgi(conn);
|
r=conn->cgi(conn);
|
||||||
if (r!=HTTPD_CGI_NOTFOUND) {
|
if (r!=HTTPD_CGI_NOTFOUND) {
|
||||||
if (r==HTTPD_CGI_DONE){
|
if (r==HTTPD_CGI_DONE) conn->cgi=NULL; //If cgi finishes immediately: mark conn for destruction.
|
||||||
conn->cgi=NULL; //If cgi finishes immediately: mark conn for destruction.
|
|
||||||
xmitSendBuff(conn);
|
xmitSendBuff(conn);
|
||||||
}
|
}else{
|
||||||
return;
|
|
||||||
}
|
|
||||||
//Can't find :/
|
//Can't find :/
|
||||||
os_printf("%s not found. 404!\n", conn->url);
|
os_printf("%s not found. 404!\n", conn->url);
|
||||||
httpdSend(conn, httpNotFoundHeader, -1);
|
httpdSend(conn, httpNotFoundHeader, -1);
|
||||||
|
xmitSendBuff(conn);
|
||||||
conn->cgi=NULL; //mark for destruction
|
conn->cgi=NULL; //mark for destruction
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//Parse a line of header data and modify the connection data accordingly.
|
//Parse a line of header data and modify the connection data accordingly.
|
||||||
static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
|
static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
|
||||||
@@ -355,7 +353,6 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
|
|||||||
conn->cgiData=NULL;
|
conn->cgiData=NULL;
|
||||||
conn->cgi=builtInUrls[i].cgiCb;
|
conn->cgi=builtInUrls[i].cgiCb;
|
||||||
conn->cgiArg=builtInUrls[i].cgiArg;
|
conn->cgiArg=builtInUrls[i].cgiArg;
|
||||||
conn->stream=builtInUrls[i].stream;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
@@ -366,16 +363,17 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) {
|
|||||||
while (h[i]!=' ') i++;
|
while (h[i]!=' ') i++;
|
||||||
//Get POST data length
|
//Get POST data length
|
||||||
conn->postLen=atoi(h+i+1);
|
conn->postLen=atoi(h+i+1);
|
||||||
if(conn->stream){
|
|
||||||
conn->postBuff=(char*)os_malloc(MAX_POST+1);
|
// Allocate the buffer
|
||||||
|
if(conn->postLen > MAX_POST){
|
||||||
|
// we'll stream this in in chunks
|
||||||
|
conn->postBuffSize = MAX_POST;
|
||||||
}else{
|
}else{
|
||||||
//Clamp if too big. Hmm, maybe we should error out instead?
|
conn->postBuffSize = conn->postLen;
|
||||||
if (conn->postLen>MAX_POST) conn->postLen=MAX_POST;
|
|
||||||
os_printf("Mallocced buffer for %d bytes of post data.\n", conn->postLen);
|
|
||||||
//Alloc the memory.
|
|
||||||
conn->postBuff=(char*)os_malloc(conn->postLen+1);
|
|
||||||
}
|
}
|
||||||
conn->priv->postPos=0;
|
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;
|
||||||
} 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
|
||||||
@@ -394,7 +392,6 @@ 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;
|
||||||
int r;
|
|
||||||
char *p, *e;
|
char *p, *e;
|
||||||
char sendBuff[MAX_SENDBUFF_LEN];
|
char sendBuff[MAX_SENDBUFF_LEN];
|
||||||
HttpdConnData *conn=httpdFindConnData(arg);
|
HttpdConnData *conn=httpdFindConnData(arg);
|
||||||
@@ -424,40 +421,23 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short
|
|||||||
}
|
}
|
||||||
//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->postLen==0) {
|
||||||
httpdSendResp(conn);
|
httpdProcessRequest(conn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (conn->priv->postPos!=-1 && conn->postLen!=0 && conn->priv->postPos <= conn->postLen) {
|
} else if (conn->postLen!=0) {
|
||||||
//This byte is a POST byte.
|
//This byte is a POST byte.
|
||||||
conn->postBuff[conn->priv->postPos++]=data[x];
|
conn->postBuff[conn->postBuffLen++]=data[x];
|
||||||
conn->postReceived++;
|
conn->postReceived++;
|
||||||
if (conn->priv->postPos>=conn->postLen) {
|
if (conn->postBuffLen >= conn->postBuffSize || conn->postReceived == conn->postLen) {
|
||||||
//Received post stuff.
|
//Received a chunk of post data
|
||||||
conn->postBuff[conn->priv->postPos]=0; //zero-terminate
|
conn->postBuff[conn->postBuffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings
|
||||||
conn->postBuffLen = conn->priv->postPos;
|
//os_printf("Post data: %s\n", conn->postBuff);
|
||||||
conn->priv->postPos=-1;
|
|
||||||
os_printf("Post data: %s\n", conn->postBuff);
|
|
||||||
//Send the response.
|
//Send the response.
|
||||||
httpdSendResp(conn);
|
httpdProcessRequest(conn);
|
||||||
break;
|
conn->postBuffLen = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(conn->priv->postPos > 0 && conn->stream){
|
|
||||||
conn->postBuff[conn->priv->postPos]=0; //zero-terminate
|
|
||||||
conn->postBuffLen = conn->priv->postPos;
|
|
||||||
r=conn->cgi(conn);
|
|
||||||
if (r!=HTTPD_CGI_NOTFOUND) {
|
|
||||||
if (r==HTTPD_CGI_DONE){
|
|
||||||
conn->cgi=NULL; //If cgi finishes mark conn for destruction.
|
|
||||||
xmitSendBuff(conn);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
conn->priv->postPos = 0;
|
|
||||||
}else{
|
|
||||||
xmitSendBuff(conn);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
|
static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) {
|
||||||
@@ -510,7 +490,7 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) {
|
|||||||
connData[i].conn=conn;
|
connData[i].conn=conn;
|
||||||
connData[i].priv->headPos=0;
|
connData[i].priv->headPos=0;
|
||||||
connData[i].postBuff=NULL;
|
connData[i].postBuff=NULL;
|
||||||
connData[i].priv->postPos=0;
|
connData[i].postBuffLen=0;
|
||||||
connData[i].postLen=-1;
|
connData[i].postLen=-1;
|
||||||
|
|
||||||
espconn_regist_recvcb(conn, httpdRecvCb);
|
espconn_regist_recvcb(conn, httpdRecvCb);
|
||||||
|
|||||||
+5
-7
@@ -8,9 +8,8 @@
|
|||||||
|
|
||||||
#define HTTPD_CGI_MORE 0
|
#define HTTPD_CGI_MORE 0
|
||||||
#define HTTPD_CGI_DONE 1
|
#define HTTPD_CGI_DONE 1
|
||||||
#define HTTPD_CGI_NOTDONE 2
|
#define HTTPD_CGI_NOTFOUND 2
|
||||||
#define HTTPD_CGI_NOTFOUND 3
|
#define HTTPD_CGI_AUTHENTICATED 3 //for now
|
||||||
#define HTTPD_CGI_AUTHENTICATED 4 //for now
|
|
||||||
|
|
||||||
#define GET 1
|
#define GET 1
|
||||||
#define POST 2
|
#define POST 2
|
||||||
@@ -33,10 +32,10 @@ struct HttpdConnData {
|
|||||||
HttpdPriv *priv;
|
HttpdPriv *priv;
|
||||||
cgiSendCallback cgi;
|
cgiSendCallback cgi;
|
||||||
int postLen;
|
int postLen;
|
||||||
int postBuffLen;
|
int postBuffSize; // The maximum length of the post buffer
|
||||||
int postReceived;
|
int postBuffLen; // The amount of bytes in the current post buffer
|
||||||
|
int postReceived; // The total amount of bytes received so far
|
||||||
char *postBuff;
|
char *postBuff;
|
||||||
int stream;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//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
|
||||||
@@ -45,7 +44,6 @@ typedef struct {
|
|||||||
const char *url;
|
const char *url;
|
||||||
cgiSendCallback cgiCb;
|
cgiSendCallback cgiCb;
|
||||||
const void *cgiArg;
|
const void *cgiArg;
|
||||||
int stream;
|
|
||||||
} HttpdBuiltInUrl;
|
} HttpdBuiltInUrl;
|
||||||
|
|
||||||
int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData);
|
int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData);
|
||||||
|
|||||||
+15
-15
@@ -50,27 +50,27 @@ general ones. Authorization things (like authBasic) act as a 'barrier' and
|
|||||||
should be placed above the URLs they protect.
|
should be placed above the URLs they protect.
|
||||||
*/
|
*/
|
||||||
HttpdBuiltInUrl builtInUrls[]={
|
HttpdBuiltInUrl builtInUrls[]={
|
||||||
{"/", cgiRedirect, "/index.tpl", FALSE},
|
{"/", cgiRedirect, "/index.tpl"},
|
||||||
{"/flash.bin", cgiReadFlash, NULL, FALSE},
|
{"/flash.bin", cgiReadFlash, NULL},
|
||||||
{"/led.tpl", cgiEspFsTemplate, tplLed, FALSE},
|
{"/led.tpl", cgiEspFsTemplate, tplLed},
|
||||||
{"/index.tpl", cgiEspFsTemplate, tplCounter, FALSE},
|
{"/index.tpl", cgiEspFsTemplate, tplCounter},
|
||||||
{"/led.cgi", cgiLed, NULL, FALSE},
|
{"/led.cgi", cgiLed, NULL},
|
||||||
{"/updateweb.cgi", updateWeb, NULL, TRUE},
|
{"/updateweb.cgi", updateWeb, NULL},
|
||||||
|
|
||||||
//Routines to make the /wifi URL and everything beneath it work.
|
//Routines to make the /wifi URL and everything beneath it work.
|
||||||
|
|
||||||
//Enable the line below to protect the WiFi configuration with an username/password combo.
|
//Enable the line below to protect the WiFi configuration with an username/password combo.
|
||||||
// {"/wifi/*", authBasic, myPassFn, FALSE},
|
// {"/wifi/*", authBasic, myPassFn},
|
||||||
|
|
||||||
{"/wifi", cgiRedirect, "/wifi/wifi.tpl", FALSE},
|
{"/wifi", cgiRedirect, "/wifi/wifi.tpl"},
|
||||||
{"/wifi/", cgiRedirect, "/wifi/wifi.tpl", FALSE},
|
{"/wifi/", cgiRedirect, "/wifi/wifi.tpl"},
|
||||||
{"/wifi/wifiscan.cgi", cgiWiFiScan, NULL, FALSE},
|
{"/wifi/wifiscan.cgi", cgiWiFiScan, NULL},
|
||||||
{"/wifi/wifi.tpl", cgiEspFsTemplate, tplWlan, FALSE},
|
{"/wifi/wifi.tpl", cgiEspFsTemplate, tplWlan},
|
||||||
{"/wifi/connect.cgi", cgiWiFiConnect, NULL, FALSE},
|
{"/wifi/connect.cgi", cgiWiFiConnect, NULL},
|
||||||
{"/wifi/setmode.cgi", cgiWifiSetMode, NULL, FALSE},
|
{"/wifi/setmode.cgi", cgiWifiSetMode, NULL},
|
||||||
|
|
||||||
{"*", cgiEspFsHook, NULL, FALSE}, //Catch-all cgi function for the filesystem
|
{"*", cgiEspFsHook, NULL}, //Catch-all cgi function for the filesystem
|
||||||
{NULL, NULL, NULL, FALSE}
|
{NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user