From 0b393512fc8beef55e56ee22ab1872d02eef0808 Mon Sep 17 00:00:00 2001 From: Jeroen Domburg Date: Mon, 8 Jun 2015 18:09:41 +0800 Subject: [PATCH] Captive portal http functions --- httpd/httpd.c | 23 +++++++++++++++++++++++ httpd/httpd.h | 2 ++ user/user_main.c | 1 + 3 files changed, 26 insertions(+) diff --git a/httpd/httpd.c b/httpd/httpd.c index 5c76492..899e109 100644 --- a/httpd/httpd.c +++ b/httpd/httpd.c @@ -228,6 +228,23 @@ int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData) { return HTTPD_CGI_DONE; } +//This CGI function redirects to a fixed url of http://[hostname]/ if hostname field of request isn't +//already that hostname. Use this in combination with a DNS server that redirects everything to the +//ESP in order to load a HTML page as soon as a phone connects to the ESP. +int ICACHE_FLASH_ATTR cgiCheckHostname(HttpdConnData *connData) { + char buff[1024]; + if (connData->conn==NULL) { + //Connection aborted. Clean up. + return HTTPD_CGI_DONE; + } + //Check hostname; pass on if the same + if (connData->hostName==NULL || os_strcmp(connData->hostName, (char*)connData->cgiArg)==0) return HTTPD_CGI_NOTFOUND; + //Not the same. Redirect to real hostname. + os_sprintf(buff, "http://%s/", (char*)connData->cgiArg); + os_printf("Redirecting to hostname url %s\n", buff); + httpdRedirect(connData, buff); + 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. @@ -347,6 +364,10 @@ static void ICACHE_FLASH_ATTR httpdParseHeader(char *h, HttpdConnData *conn) { if (os_strncmp(h, "GET ", 4)==0) { conn->requestType = HTTPD_METHOD_GET; first_line = true; + } else if (os_strncmp(h, "Host:", 5)==0) { + i=5; + while (h[i]==' ') i++; + conn->hostName=&h[i]; } else if (os_strncmp(h, "POST ", 5)==0) { conn->requestType = HTTPD_METHOD_POST; first_line = true; @@ -453,6 +474,7 @@ static void ICACHE_FLASH_ATTR httpdRecvCb(void *arg, char *data, unsigned short //This byte is a POST byte. conn->post->buff[conn->post->buffLen++]=data[x]; conn->post->received++; + conn->hostName=NULL; if (conn->post->buffLen >= conn->post->buffSize || conn->post->received == conn->post->len) { //Received a chunk of post data conn->post->buff[conn->post->buffLen]=0; //zero-terminate, in case the cgi handler knows it can use strings @@ -511,6 +533,7 @@ static void ICACHE_FLASH_ATTR httpdConnectCb(void *arg) { connData[i].post->buffLen=0; connData[i].post->received=0; connData[i].post->len=-1; + connData[i].hostName=NULL; espconn_regist_recvcb(conn, httpdRecvCb); espconn_regist_reconcb(conn, httpdReconCb); diff --git a/httpd/httpd.h b/httpd/httpd.h index 95611bd..a2869b6 100644 --- a/httpd/httpd.h +++ b/httpd/httpd.h @@ -27,6 +27,7 @@ struct HttpdConnData { const void *cgiArg; void *cgiData; void *cgiPrivData; // Used for streaming handlers storing state between requests + char *hostName; HttpdPriv *priv; cgiSendCallback cgi; HttpdPostData *post; @@ -51,6 +52,7 @@ typedef struct { } HttpdBuiltInUrl; int ICACHE_FLASH_ATTR cgiRedirect(HttpdConnData *connData); +int ICACHE_FLASH_ATTR cgiCheckHostname(HttpdConnData *connData); 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); diff --git a/user/user_main.c b/user/user_main.c index 0940bfa..5b2ac61 100644 --- a/user/user_main.c +++ b/user/user_main.c @@ -53,6 +53,7 @@ general ones. Authorization things (like authBasic) act as a 'barrier' and should be placed above the URLs they protect. */ HttpdBuiltInUrl builtInUrls[]={ + {"*", cgiCheckHostname, "esp8266.local"}, {"/", cgiRedirect, "/index.tpl"}, {"/flash.bin", cgiReadFlash, NULL}, {"/led.tpl", cgiEspFsTemplate, tplLed},