/*
Connector to let httpd use the espfs filesystem to serve the files in it .
*/
/*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* " THE BEER-WARE LICENSE " ( Revision 42 ) :
* Jeroen Domburg < jeroen @ spritesmods . com > wrote this file . As long as you retain
* this notice you can do whatever you want with this stuff . If we meet some day ,
* and you think this stuff is worth it , you can buy me a beer in return .
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
# include "espmissingincludes.h"
# include <string.h>
# include <osapi.h>
# include "c_types.h"
# include "user_interface.h"
# include "espconn.h"
# include "mem.h"
# include "httpd.h"
# include "espfs.h"
# include "httpdespfs.h"
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
//path in the filesystem and if it exists, passes the file through. This simulates what a normal
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook ( HttpdConnData * connData ) {
EspFsFile * file = connData - > cgiData ;
int len ;
char buff [ 1024 ] ;
if ( connData - > conn = = NULL ) {
//Connection aborted. Clean up.
espFsClose ( file ) ;
return HTTPD_CGI_DONE ;
}
if ( file = = NULL ) {
//First call to this cgi. Open the file so we can read it.
file = espFsOpen ( connData - > url ) ;
if ( file = = NULL ) {
return HTTPD_CGI_NOTFOUND ;
}
connData - > cgiData = file ;
httpdStartResponse ( connData , 200 ) ;
httpdHeader ( connData , " Content-Type " , httpdGetMimetype ( connData - > url ) ) ;
httpdEndHeaders ( connData ) ;
return HTTPD_CGI_MORE ;
}
len = espFsRead ( file , buff , 1024 ) ;
if ( len > 0 ) espconn_sent ( connData - > conn , ( uint8 * ) buff , len ) ;
if ( len ! = 1024 ) {
//We're done.
espFsClose ( file ) ;
return HTTPD_CGI_DONE ;
} else {
//Ok, till next time.
return HTTPD_CGI_MORE ;
}
}
//cgiEspFsTemplate can be used as a template.
typedef struct {
EspFsFile * file ;
void * tplArg ;
char token [ 64 ] ;
int tokenPos ;
} TplData ;
typedef void ( * TplCallback ) ( HttpdConnData * connData , char * token , void * * arg ) ;
int ICACHE_FLASH_ATTR cgiEspFsTemplate ( HttpdConnData * connData ) {
TplData * tpd = connData - > cgiData ;
int len ;
int x , sp = 0 ;
char * e = NULL ;
char buff [ 1025 ] ;
if ( connData - > conn = = NULL ) {
//Connection aborted. Clean up.
( ( TplCallback ) ( connData - > cgiArg ) ) ( connData , NULL , & tpd - > tplArg ) ;
espFsClose ( tpd - > file ) ;
os_free ( tpd ) ;
return HTTPD_CGI_DONE ;
}
if ( tpd = = NULL ) {
//First call to this cgi. Open the file so we can read it.
tpd = ( TplData * ) os_malloc ( sizeof ( TplData ) ) ;
tpd - > file = espFsOpen ( connData - > url ) ;
tpd - > tplArg = NULL ;
tpd - > tokenPos = - 1 ;
if ( tpd - > file = = NULL ) {
return HTTPD_CGI_NOTFOUND ;
}
connData - > cgiData = tpd ;
httpdStartResponse ( connData , 200 ) ;
httpdHeader ( connData , " Content-Type " , httpdGetMimetype ( connData - > url ) ) ;
httpdEndHeaders ( connData ) ;
return HTTPD_CGI_MORE ;
}
len = espFsRead ( tpd - > file , buff , 1024 ) ;
if ( len > 0 ) {
sp = 0 ;
e = buff ;
for ( x = 0 ; x < len ; x + + ) {
if ( tpd - > tokenPos = = - 1 ) {
//Inside ordinary text.
if ( buff [ x ] = = ' % ' ) {
//Send raw data up to now
if ( sp ! = 0 ) espconn_sent ( connData - > conn , ( uint8 * ) e , sp ) ;
sp = 0 ;
//Go collect token chars.
tpd - > tokenPos = 0 ;
} else {
sp + + ;
}
} else {
if ( buff [ x ] = = ' % ' ) {
if ( tpd - > tokenPos = = 0 ) {
//This is the second % of a %% escape string.
//Send a single % and resume with the normal program flow.
espconn_sent ( connData - > conn , ( uint8 * ) " % " , 1 ) ;
} else {
//This is an actual token.
tpd - > token [ tpd - > tokenPos + + ] = 0 ; //zero-terminate token
( ( TplCallback ) ( connData - > cgiArg ) ) ( connData , tpd - > token , & tpd - > tplArg ) ;
}
//Go collect normal chars again.
e = & buff [ x + 1 ] ;
tpd - > tokenPos = - 1 ;
} else {
if ( tpd - > tokenPos < ( sizeof ( tpd - > token ) - 1 ) ) tpd - > token [ tpd - > tokenPos + + ] = buff [ x ] ;
}
}
}
}
//Send remaining bit.
if ( sp ! = 0 ) espconn_sent ( connData - > conn , ( uint8 * ) e , sp ) ;
if ( len ! = 1024 ) {
//We're done.
( ( TplCallback ) ( connData - > cgiArg ) ) ( connData , NULL , & tpd - > tplArg ) ;
espFsClose ( tpd - > file ) ;
return HTTPD_CGI_DONE ;
} else {
//Ok, till next time.
return HTTPD_CGI_MORE ;
}
}