2021-12-23 22:42:19 +01:00
# include "StandWebServer.h"
# ifdef STANDARD_WEB_SERVER
2021-12-24 22:49:06 +01:00
File fsUploadFile ;
2021-12-23 22:42:19 +01:00
void standWebServerInit ( ) {
// Кэшировать файлы для быстрой работы
HTTP . serveStatic ( " /css/ " , FileFS , " /css/ " , " max-age=31536000 " ) ; // кеширование на 1 год
HTTP . serveStatic ( " /js/ " , FileFS , " /js/ " , " max-age=31536000 " ) ; // кеширование на 1 год
HTTP . serveStatic ( " /png/ " , FileFS , " /png/ " , " max-age=31536000 " ) ; // кеширование на 1 год
HTTP . on ( " /settings.json " , HTTP_GET , [ ] ( ) {
HTTP . send ( 200 , " application/json " , settingsFlashJson ) ;
} ) ;
HTTP . on ( " /restart " , HTTP_GET , [ ] ( ) {
// ESP.restart();
HTTP . send ( 200 , " text/plain " , " ok " ) ;
} ) ;
// Добавляем функцию Update для перезаписи прошивки по WiFi при 1М (256K FileFS) и выше
// httpUpdater.setup(&HTTP);
// Запускаем HTTP сервер
HTTP . begin ( ) ;
2021-12-23 22:56:45 +01:00
# ifdef REST_FILE_OPERATIONS
2021-12-23 22:42:19 +01:00
SPIFFS . begin ( ) ;
{
Dir dir = SPIFFS . openDir ( " / " ) ;
while ( dir . next ( ) ) {
String fileName = dir . fileName ( ) ;
size_t fileSize = dir . fileSize ( ) ;
}
}
// HTTP страницы для работы с FFS
// list directory
HTTP . on ( " /list " , HTTP_GET , handleFileList ) ;
//загрузка редактора editor
HTTP . on ( " /edit " , HTTP_GET , [ ] ( ) {
if ( ! handleFileRead ( " /edit.htm " ) ) HTTP . send ( 404 , " text/plain " , " FileNotFound " ) ;
} ) ;
//Создание файла
HTTP . on ( " /edit " , HTTP_PUT , handleFileCreate ) ;
//Удаление файла
HTTP . on ( " /edit " , HTTP_DELETE , handleFileDelete ) ;
// first callback is called after the request has ended with all parsed arguments
// second callback handles file uploads at that location
HTTP . on (
" /edit " , HTTP_POST , [ ] ( ) {
HTTP . send ( 200 , " text/plain " , " " ) ;
} ,
handleFileUpload ) ;
# endif
// called when the url is not defined here
// use it to load content from SPIFFS
HTTP . onNotFound ( [ ] ( ) {
if ( ! handleFileRead ( HTTP . uri ( ) ) )
HTTP . send ( 404 , " text/plain " , " FileNotFound " ) ;
} ) ;
}
bool handleFileRead ( String path ) {
if ( path . endsWith ( " / " ) ) path + = " index.html " ;
String contentType = getContentType ( path ) ;
String pathWithGz = path + " .gz " ;
if ( FileFS . exists ( pathWithGz ) | | FileFS . exists ( path ) ) {
if ( FileFS . exists ( pathWithGz ) )
path + = " .gz " ;
File file = FileFS . open ( path , " r " ) ;
2021-12-23 23:47:13 +01:00
HTTP . streamFile ( file , contentType ) ;
2021-12-23 22:42:19 +01:00
file . close ( ) ;
return true ;
}
return false ;
}
String getContentType ( String filename ) {
if ( HTTP . hasArg ( " download " ) )
return " application/octet-stream " ;
else if ( filename . endsWith ( " .htm " ) )
return " text/html " ;
else if ( filename . endsWith ( " .html " ) )
return " text/html " ;
else if ( filename . endsWith ( " .json " ) )
return " application/json " ;
else if ( filename . endsWith ( " .css " ) )
return " text/css " ;
else if ( filename . endsWith ( " .js " ) )
return " application/javascript " ;
else if ( filename . endsWith ( " .png " ) )
return " image/png " ;
else if ( filename . endsWith ( " .gif " ) )
return " image/gif " ;
else if ( filename . endsWith ( " .jpg " ) )
return " image/jpeg " ;
else if ( filename . endsWith ( " .ico " ) )
return " image/x-icon " ;
else if ( filename . endsWith ( " .xml " ) )
return " text/xml " ;
else if ( filename . endsWith ( " .pdf " ) )
return " application/x-pdf " ;
else if ( filename . endsWith ( " .zip " ) )
return " application/x-zip " ;
else if ( filename . endsWith ( " .gz " ) )
return " application/x-gzip " ;
return " text/plain " ;
}
2021-12-23 22:56:45 +01:00
# ifdef REST_FILE_OPERATIONS
2021-12-23 22:42:19 +01:00
// Здесь функции для работы с файловой системой
void handleFileUpload ( ) {
if ( HTTP . uri ( ) ! = " /edit " ) return ;
HTTPUpload & upload = HTTP . upload ( ) ;
if ( upload . status = = UPLOAD_FILE_START ) {
String filename = upload . filename ;
if ( ! filename . startsWith ( " / " ) ) filename = " / " + filename ;
fsUploadFile = FileFS . open ( filename , " w " ) ;
filename = String ( ) ;
} else if ( upload . status = = UPLOAD_FILE_WRITE ) {
// Serial.print("handleFileUpload Data: "); Serial.println(upload.currentSize);
if ( fsUploadFile )
fsUploadFile . write ( upload . buf , upload . currentSize ) ;
} else if ( upload . status = = UPLOAD_FILE_END ) {
if ( fsUploadFile )
fsUploadFile . close ( ) ;
}
}
void handleFileDelete ( ) {
if ( HTTP . args ( ) = = 0 ) return HTTP . send ( 500 , " text/plain " , " BAD ARGS " ) ;
String path = HTTP . arg ( 0 ) ;
if ( path = = " / " )
return HTTP . send ( 500 , " text/plain " , " BAD PATH " ) ;
if ( ! FileFS . exists ( path ) )
return HTTP . send ( 404 , " text/plain " , " FileNotFound " ) ;
FileFS . remove ( path ) ;
HTTP . send ( 200 , " text/plain " , " " ) ;
path = String ( ) ;
}
void handleFileCreate ( ) {
if ( HTTP . args ( ) = = 0 )
return HTTP . send ( 500 , " text/plain " , " BAD ARGS " ) ;
String path = HTTP . arg ( 0 ) ;
if ( path = = " / " )
return HTTP . send ( 500 , " text/plain " , " BAD PATH " ) ;
if ( FileFS . exists ( path ) )
return HTTP . send ( 500 , " text/plain " , " FILE EXISTS " ) ;
File file = FileFS . open ( path , " w " ) ;
if ( file )
file . close ( ) ;
else
return HTTP . send ( 500 , " text/plain " , " CREATE FAILED " ) ;
HTTP . send ( 200 , " text/plain " , " " ) ;
path = String ( ) ;
}
void handleFileList ( ) {
if ( ! HTTP . hasArg ( " dir " ) ) {
HTTP . send ( 500 , " text/plain " , " BAD ARGS " ) ;
return ;
}
String path = HTTP . arg ( " dir " ) ;
Dir dir = FileFS . openDir ( path ) ;
path = String ( ) ;
String output = " [ " ;
while ( dir . next ( ) ) {
File entry = dir . openFile ( " r " ) ;
if ( output ! = " [ " ) output + = ' , ' ;
bool isDir = false ;
output + = " { \" type \" : \" " ;
output + = ( isDir ) ? " dir " : " file " ;
output + = " \" , \" name \" : \" " ;
output + = String ( entry . name ( ) ) . substring ( 1 ) ;
output + = " \" } " ;
entry . close ( ) ;
}
output + = " ] " ;
HTTP . send ( 200 , " text/json " , output ) ;
}
# endif
# endif
2021-12-23 23:47:13 +01:00
# ifdef STANDARD_WEB_SOCKETS
void standWebSocketsInit ( ) {
standWebSocket . begin ( ) ;
standWebSocket . onEvent ( webSocketEvent ) ;
}
void webSocketEvent ( uint8_t num , WStype_t type , uint8_t * payload , size_t length ) {
switch ( type ) {
2021-12-30 23:58:56 +01:00
case WStype_ERROR : {
Serial . printf ( " [%u] Error! \n " , num ) ;
} break ;
2021-12-24 00:06:37 +01:00
case WStype_DISCONNECTED : {
2021-12-23 23:47:13 +01:00
Serial . printf ( " [%u] Disconnected! \n " , num ) ;
2021-12-24 00:06:37 +01:00
} break ;
2021-12-23 23:47:13 +01:00
case WStype_CONNECTED : {
IPAddress ip = standWebSocket . remoteIP ( num ) ;
Serial . printf ( " [%u] Connected from %d.%d.%d.%d url: %s \n " , num , ip [ 0 ] , ip [ 1 ] , ip [ 2 ] , ip [ 3 ] , payload ) ;
standWebSocket . sendTXT ( num , " Connected " ) ;
} break ;
2021-12-24 00:06:37 +01:00
case WStype_TEXT : {
2021-12-30 23:58:56 +01:00
// Serial.printf("[%u] get Text: %s\n", num, payload);
2021-12-23 23:47:13 +01:00
2021-12-24 00:44:11 +01:00
String payloadStr ;
payloadStr . reserve ( length + 1 ) ;
for ( size_t i = 0 ; i < length ; i + + ) {
payloadStr + = ( char ) payload [ i ] ;
}
2022-01-17 00:06:50 +01:00
if ( payloadStr . startsWith ( " /config " ) ) {
//если прилетел url страницы /config то отправим widgets.json и config.json
2022-01-17 00:12:03 +01:00
2022-01-20 13:36:00 +01:00
# ifdef QUEUE_FROM_STR
2022-01-21 17:34:11 +01:00
// sendFileToWs2("/widgets.json", num);
sendFileToWs4 ( " /config.json " , num ) ;
2022-01-20 13:36:00 +01:00
# endif
2021-12-24 00:44:11 +01:00
}
2022-01-10 23:37:21 +01:00
2022-01-14 15:41:39 +01:00
if ( payloadStr . startsWith ( " /gifnoc.json " ) ) { //если прилетел измененный пакет с меткой /gifnoc (config наоборот) то перепишем файл, пока переписываем целеком
2021-12-30 23:58:56 +01:00
payloadStr . replace ( " /gifnoc.json " , " " ) ;
2021-12-25 01:52:25 +01:00
writeFile ( F ( " config.json " ) , payloadStr ) ;
}
2021-12-24 00:06:37 +01:00
} break ;
2021-12-23 23:47:13 +01:00
2021-12-24 00:06:37 +01:00
case WStype_BIN : {
2021-12-23 23:47:13 +01:00
Serial . printf ( " [%u] get binary length: %u \n " , num , length ) ;
2021-12-24 22:49:06 +01:00
// hexdump(payload, length);
2021-12-23 23:47:13 +01:00
// standWebSocket.sendBIN(num, payload, length);
2021-12-24 00:06:37 +01:00
} break ;
2021-12-30 23:58:56 +01:00
case WStype_FRAGMENT_TEXT_START : {
Serial . printf ( " [%u] fragment test start: %u \n " , num , length ) ;
} break ;
case WStype_FRAGMENT_BIN_START : {
Serial . printf ( " [%u] fragment bin start: %u \n " , num , length ) ;
} break ;
case WStype_FRAGMENT : {
Serial . printf ( " [%u] fragment: %u \n " , num , length ) ;
} break ;
case WStype_FRAGMENT_FIN : {
Serial . printf ( " [%u] fragment finish: %u \n " , num , length ) ;
} break ;
case WStype_PING : {
Serial . printf ( " [%u] ping: %u \n " , num , length ) ;
} break ;
case WStype_PONG : {
Serial . printf ( " [%u] pong: %u \n " , num , length ) ;
} break ;
default : {
Serial . printf ( " [%u] not recognized: %u \n " , num , length ) ;
} break ;
2021-12-23 23:47:13 +01:00
}
}
2021-12-24 01:26:50 +01:00
# ifdef ESP32
void hexdump ( const void * mem , uint32_t len , uint8_t cols = 16 ) {
const uint8_t * src = ( const uint8_t * ) mem ;
Serial . printf ( " \n [HEXDUMP] Address: 0x%08X len: 0x%X (%d) " , ( ptrdiff_t ) src , len , len ) ;
for ( uint32_t i = 0 ; i < len ; i + + ) {
if ( i % cols = = 0 ) {
Serial . printf ( " \n [0x%08X] 0x%08X: " , ( ptrdiff_t ) src , i ) ;
}
Serial . printf ( " %02X " , * src ) ;
src + + ;
}
Serial . printf ( " \n " ) ;
}
# endif
2021-12-23 23:47:13 +01:00
# endif
2022-01-21 17:34:11 +01:00
void sendFileToWs ( const String & filename , uint8_t num ) {
String path = filepath ( filename ) ;
auto file = FileFS . open ( path , " r " ) ;
if ( ! file ) {
SerialPrint ( F ( " E " ) , F ( " FS " ) , F ( " reed file error " ) ) ;
}
size_t fileSize = file . size ( ) ;
uint8_t bufuint [ fileSize ] ;
SerialPrint ( F ( " i " ) , F ( " WS " ) , " Send file ' " + filename + " ', file size: " + String ( fileSize ) ) ;
long st = millis ( ) ;
int i = 0 ;
while ( file . available ( ) ) {
bufuint [ i ] = file . read ( ) ;
i + + ;
yield ( ) ;
}
long end = millis ( ) ;
SerialPrint ( F ( " i " ) , F ( " WS " ) , " Time ' " + String ( end - st ) ) ;
standWebSocket . sendTXT ( num , bufuint , i ) ;
}
void sendFileToWs2 ( const String & filename , uint8_t num ) {
String file = readFile ( filename , 5000 ) ;
size_t fileSize = sizeof ( file ) ;
SerialPrint ( F ( " i " ) , F ( " WS " ) , String ( fileSize ) ) ;
standWebSocket . sendTXT ( num , file ) ;
}
void sendFileToWs3 ( const String & filename , uint8_t num ) {
String path = filepath ( filename ) ;
auto file = FileFS . open ( path , " r " ) ;
if ( ! file ) {
SerialPrint ( F ( " E " ) , F ( " FS " ) , F ( " reed file error " ) ) ;
}
size_t fileSize = file . size ( ) ;
SerialPrint ( F ( " i " ) , F ( " WS " ) , " Send file ' " + filename + " ', file size: " + String ( fileSize ) ) ;
String ret ;
ret . reserve ( file . size ( ) - file . position ( ) ) ;
char temp [ 256 + 1 ] ;
int countRead = file . readBytes ( temp , sizeof ( temp ) - 1 ) ;
while ( countRead > 0 ) {
temp [ countRead ] = 0 ;
ret + = temp ;
countRead = file . readBytes ( temp , sizeof ( temp ) - 1 ) ;
}
standWebSocket . sendTXT ( num , ret ) ;
}
void sendFileToWs4 ( const String & filename , uint8_t num ) {
size_t ws_buffer = 1024 ;
String path = filepath ( filename ) ;
auto file = FileFS . open ( path , " r " ) ;
if ( ! file ) {
SerialPrint ( F ( " E " ) , F ( " FS " ) , F ( " reed file error " ) ) ;
}
size_t fileSize = file . size ( ) ;
SerialPrint ( F ( " i " ) , F ( " WS " ) , " Send file ' " + filename + " ', file size: " + String ( fileSize ) ) ;
char temp [ ws_buffer + 1 ] ;
int countRead = file . readBytes ( temp , sizeof ( temp ) - 1 ) ;
while ( countRead > 0 ) {
temp [ countRead ] = 0 ;
standWebSocket . sendTXT ( num , temp , countRead ) ;
countRead = file . readBytes ( temp , sizeof ( temp ) - 1 ) ;
}
}