diff --git a/html/led.html b/html/led.html new file mode 100644 index 0000000..8dea97d --- /dev/null +++ b/html/led.html @@ -0,0 +1,13 @@ +Test + + +

+There's a LED. You can't see it, so it's no use clicking any of the buttons below. The buttons +do, however, turn the LED on and off. +

+
+ + +
+ + diff --git a/html/test2.html b/html/test2.html index 81c3ffd..c6b2cc3 100644 --- a/html/test2.html +++ b/html/test2.html @@ -2,9 +2,11 @@ Test

Test2!

+

New!You can also control the LED...

Here's an image of a cat (hopefully...)




+ diff --git a/html/test3.html b/html/test3.html new file mode 100644 index 0000000..b4e8fdf --- /dev/null +++ b/html/test3.html @@ -0,0 +1,10 @@ +Test + + +
+ + + +
+ + diff --git a/user/cgi.c b/user/cgi.c new file mode 100644 index 0000000..6aa3e4c --- /dev/null +++ b/user/cgi.c @@ -0,0 +1,50 @@ +/* +Some random cgi routines. +*/ + +#include +#include +#include "httpd.h" +#include "cgi.h" +#include "io.h" + +int ICACHE_FLASH_ATTR cgiLed(HttpdConnData *connData) { + int len; + char buff[1024]; + + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + len=httpdFindArg(connData->postBuff, "led", buff, sizeof(buff)); + ioLed(atoi(buff)); + + httpdRedirect(connData, "led.html"); + return HTTPD_CGI_DONE; +} + +int ICACHE_FLASH_ATTR cgiTest(HttpdConnData *connData) { + int len; + char val1[128]; + char val2[128]; + char buff[1024]; + + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + + httpdStartResponse(connData, 200); + httpdHeader(connData, "Content-Type", "text/plain"); + httpdEndHeaders(connData); + + + httpdFindArg(connData->postBuff, "Test1", val1, sizeof(val1)); + httpdFindArg(connData->postBuff, "Test2", val2, sizeof(val2)); + len=os_sprintf(buff, "Field 1: %s\nField 2: %s\n", val1, val2); + espconn_sent(connData->conn, (uint8 *)buff, len); + + return HTTPD_CGI_DONE; +} + diff --git a/user/cgi.h b/user/cgi.h new file mode 100644 index 0000000..5fd6826 --- /dev/null +++ b/user/cgi.h @@ -0,0 +1,9 @@ +#ifndef CGI_H +#define CGI_H + +#include "httpd.h" + +int cgiLed(HttpdConnData *connData); +int cgiTest(HttpdConnData *connData); + +#endif \ No newline at end of file diff --git a/user/httpd.c b/user/httpd.c index 64d8119..72d0fad 100644 --- a/user/httpd.c +++ b/user/httpd.c @@ -24,9 +24,7 @@ static HttpdBuiltInUrl *builtInUrls; struct HttpdPriv { char head[MAX_HEAD_LEN]; int headPos; - int postLen; int postPos; - char *postBuff; }; //Connection pool @@ -75,33 +73,62 @@ static HttpdConnData ICACHE_FLASH_ATTR *httpdFindConnData(void *arg) { static void ICACHE_FLASH_ATTR httpdRetireConn(HttpdConnData *conn) { - if (conn->priv->postBuff!=NULL) os_free(conn->priv->postBuff); - conn->priv->postBuff=NULL; + if (conn->postBuff!=NULL) os_free(conn->postBuff); + conn->postBuff=NULL; conn->cgi=NULL; conn->conn=NULL; } -//Find a specific arg in a string of get- or post-data. -static char *ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg) { - char *p; - int al; - if (line==NULL) return NULL; - - p=line; - al=os_strlen(arg); - os_printf("Finding %s in %s\n", arg, line); +static int httpdHexVal(char c) { + if (c>='0' && c<='9') return c-'0'; + if (c>='A' && c<='F') return c-'A'+10; + if (c>='a' && c<='f') return c-'a'+10; +} - while (p[0]!=0) { - if (os_strncmp(p, arg, al)==0 && p[al]=='=') { - //Gotcha. - return &p[al+1]; +//Decode a percent-encoded value +int httpdUrlDecode(char *val, int valLen, char *ret, int retLen) { + int s=0, d=0; + int esced=0, escVal=0; + while (sconn, "\r\n", 2); } +//ToDo: sprintf->snprintf everywhere +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, buff, l); +} static void ICACHE_FLASH_ATTR httpdSentCb(void *arg) { int r; @@ -192,21 +226,16 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { *conn->getArgs=0; conn->getArgs++; os_printf("GET args = %s\n", conn->getArgs); - l=os_strlen(conn->getArgs); - for (x=0; xgetArgs[x]=='&') conn->getArgs[x]=0; - //End with double-zero - conn->getArgs[l]=0; - conn->getArgs[l+1]=0; } else { conn->getArgs=NULL; } } else if (os_strncmp(h, "Content-Length: ", 16)==0) { i=0; while (h[i]!=' ') i++; - conn->priv->postLen=atoi(h+i+1); - if (conn->priv->postLen>MAX_POST) conn->priv->postLen=MAX_POST; - os_printf("Mallocced buffer for %d bytes of post data.\n", conn->priv->postLen); - conn->priv->postBuff=(char*)os_malloc(conn->priv->postLen+1); + conn->postLen=atoi(h+i+1); + if (conn->postLen>MAX_POST) conn->postLen=MAX_POST; + os_printf("Mallocced buffer for %d bytes of post data.\n", conn->postLen); + conn->postBuff=(char*)os_malloc(conn->postLen+1); conn->priv->postPos=0; } } @@ -238,19 +267,19 @@ 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->priv->postLen==0) { + if (conn->postLen==0) { httpdSendResp(conn); } conn->priv->headPos=-1; //Indicate we're done with the headers. } - } else if (conn->priv->postPos!=-1 && conn->priv->postLen!=0 && conn->priv->postPos <= conn->priv->postLen) { + } else if (conn->priv->postPos!=-1 && conn->postLen!=0 && conn->priv->postPos <= conn->postLen) { //This byte is a POST byte. - conn->priv->postBuff[conn->priv->postPos++]=data[x]; - if (conn->priv->postPos>=conn->priv->postLen) { + conn->postBuff[conn->priv->postPos++]=data[x]; + if (conn->priv->postPos>=conn->postLen) { //Received post stuff. - conn->priv->postBuff[conn->priv->postPos]=0; //zero-terminate + conn->postBuff[conn->priv->postPos]=0; //zero-terminate conn->priv->postPos=-1; - os_printf("Post data: %s\n", conn->priv->postBuff); + os_printf("Post data: %s\n", conn->postBuff); //Send the response. httpdSendResp(conn); return; @@ -269,6 +298,7 @@ static void ICACHE_FLASH_ATTR httpdReconCb(void *arg, sint8 err) { static void ICACHE_FLASH_ATTR httpdDisconCb(void *arg) { #if 0 //Stupid esp sdk passes through wrong arg here, namely the one of the *listening* socket. + //If it ever gets fixed, be sure to update the code in this snippet; it's probably out-of-date. HttpdConnData *conn=httpdFindConnData(arg); os_printf("Disconnected, conn=%p\n", conn); if (conn==NULL) return; @@ -304,9 +334,9 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) { } connData[i].conn=conn; connData[i].priv->headPos=0; - connData[i].priv->postBuff=NULL; + connData[i].postBuff=NULL; connData[i].priv->postPos=0; - connData[i].priv->postLen=0; + connData[i].postLen=0; espconn_regist_recvcb(conn, httpdRecvCb); espconn_regist_reconcb(conn, httpdReconCb); diff --git a/user/httpd.h b/user/httpd.h index 66b0a4d..e3ac04e 100644 --- a/user/httpd.h +++ b/user/httpd.h @@ -22,6 +22,8 @@ struct HttpdConnData { void *cgiData; HttpdPriv *priv; cgiSendCallback cgi; + int postLen; + char *postBuff; }; @@ -34,7 +36,9 @@ typedef struct { const void *cgiArg; } HttpdBuiltInUrl; - +void ICACHE_FLASH_ATTR httpdRedirect(HttpdConnData *conn, char *newUrl); +int httpdUrlDecode(char *val, int valLen, char *ret, int retLen); +int ICACHE_FLASH_ATTR httpdFindArg(char *line, char *arg, char *buff, int buffLen); void ICACHE_FLASH_ATTR httpdInit(HttpdBuiltInUrl *fixedUrls, int port); const char *httpdGetMimetype(char *url); void ICACHE_FLASH_ATTR httpdStartResponse(HttpdConnData *conn, int code); diff --git a/user/user_main.c b/user/user_main.c index 58b1b67..4983daa 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -4,9 +4,12 @@ #include "httpd.h" #include "io.h" #include "httpdespfs.h" +#include "cgi.h" HttpdBuiltInUrl builtInUrls[]={ // {"/", cgiLiteral, "Lalala etc"}, + {"/led.cgi", cgiLed, NULL}, + {"/test.cgi", cgiTest, NULL}, {"*", cgiEspFsHook, NULL}, {NULL, NULL, NULL} };