Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By Mmiscool
#35542 I got this working in my basic interpreter a while back, Kind of forgot about this thread.

Here s a simple web server that you can upload files to and change settings on.


Code: Select all#include "spiffs/spiffs.h"
#include <FS.h>
#include <ESP8266mDNS.h>

#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <WiFiClient.h>
#include <WiFiServer.h>
//#include <WiFiUdp.h>
#include <ESP8266WebServer.h>
#include <ESP8266httpUpdate.h>



WiFiClient client;
ESP8266WebServer server(80);
File fsUploadFile;

bool fileOpenFail;
int LoggedIn = 0;

const String AdminBarHTML = R"=====(
<a href="./settings">[ SETTINGS ]</a>
<a href="./filemng">[ FILE MANAGER ]</a>
<hr>)=====";



const String SettingsPageHTML =  R"=====(
<form action='settings' id="usrform"><table>
*BasicVersion*
<tr><th>
Station Mode (Connect to your router):</th></tr>
<tr><th><p align="right">Name:</p></th><th><input type="text" name="staName" value="*sta name*"></th></tr>
<tr><th><p align="right">Pass:</p></th><th><input type="text" name="staPass" value="*sta pass*"></th></tr>
<tr><th>
<br><br>Ap mode (ESP brocast out its own ap):</th></tr>
<tr><th><p align="right">Name:</p></th><th><input type="text" name="apName" value="*ap name*"></th></tr>
<tr><th><p align="right">Pass:<br>Must be at least 8 characters</p></th><th><input type="text" name="apPass" value="*ap pass*"></th></tr>
<tr><th>
<br><br>Log In Key (For Security):</th></tr>
<tr><th><p align="right">Log In Key:</p></th><th><input type="text" name="LoginKey" value="*LoginKey*"></th></tr>
<tr><th><p align="right">Display menu bar on index page:</p></th><th><input type="checkbox" name="showMenueBar" value="off" **checked**> Disable<br></th></tr>
<tr><th><p align="right">OTA URL. Leave blank for default:</p></th><th><input type="text" name="otaurl" value="*otaurl*"></th></tr>
<tr><th>
<input type="submit" value="Save" name="save">
<input type="submit" value="Format" name="format">
<input type="submit" value="Update" name="update">
<input type="submit" value="Restart" name="restart">
</th></tr>
</table></form>
<br>
)=====";

const String UploadPage = R"=====(
<form method='POST' action='/filemng' enctype='multipart/form-data'>
<input type='file' name='Upload'>
<input type='submit' value='Upload'>
</form>
<form id="filelist">
<input type="submit" value="Delete" name="Delete">
<input type="submit" value="View" name="View">
</form>

<select name="fileName" size="25" form="filelist">*table*</select>
)=====";




const String LogInPage =  R"=====(
<form action='settings' id="usrform">
Log In Key
<input type="text" name="key" value="">
<input type="submit" value="login" name="login">
</form>
)=====";

void setup() {
  SPIFFS.begin();
  Serial.begin(9600);
  //Serial.setDebugOutput(true);
  WiFi.mode(WIFI_AP_STA);



  server.on("/settings", []()
  {

    if ( server.arg("key") == LoadDataFromFile("LoginKey"))
    {
      LoggedIn = millis();
    }



    String WebOut = AdminBarHTML;
    WebOut += SettingsPageHTML;
    String staName;
    String staPass;
    String apName;
    String apPass;
    String LoginKey;
    String ShowMenueBar;
    String otaUrl;
    //Serial.print("Loading Settings Files");

    staName      = LoadDataFromFile("WIFIname");
    staPass      = LoadDataFromFile("WIFIpass");
    apName       = LoadDataFromFile("APname");
    apPass       = LoadDataFromFile("APpass");
    LoginKey     = LoadDataFromFile("LoginKey");
    ShowMenueBar = LoadDataFromFile("ShowMenueBar");
    otaUrl       = LoadDataFromFile("otaUrl");

    if (millis() > LoggedIn + 600000 || LoggedIn == 0 )
    {
      WebOut = LogInPage;
    }
    else
    {

      if ( server.arg("restart") == "Restart" ) ESP.restart();


      if ( server.arg("update") == "Update" )
      {

        //        Serial.println(BasicOTAupgrade());
        if (LoadDataFromFile("otaUrl") == "")
        {
          t_httpUpdate_return  ret = ESPhttpUpdate.update("esp8266basic.smbisoft.com", 80, "/4M/ESP8266Basic.cpp.bin");
          if (ret == HTTP_UPDATE_FAILED ) Serial.println("Update failed");
        }
        else
        {
          String URLtoGet = LoadDataFromFile("otaUrl");
          String ServerToConnectTo;
          String PageToGet;
          ServerToConnectTo = URLtoGet.substring(0, URLtoGet.indexOf("/"));
          PageToGet = URLtoGet.substring(URLtoGet.indexOf("/"));
          t_httpUpdate_return  ret = ESPhttpUpdate.update(ServerToConnectTo, 80, PageToGet);
          if (ret == HTTP_UPDATE_FAILED ) Serial.println("Update failed");
        }
        //t_httpUpdate_return  ret = ESPhttpUpdate.update("cdn.rawgit.com", 80, "/esp8266/Basic/master/Flasher/Build/4M/ESP8266Basic.cpp.bin");

      }


      if ( server.arg("save") == "Save" )
      {
        staName = GetRidOfurlCharacters(server.arg("staName"));
        staPass = GetRidOfurlCharacters(server.arg("staPass"));
        apName  = GetRidOfurlCharacters(server.arg("apName"));
        apPass  = GetRidOfurlCharacters(server.arg("apPass"));
        LoginKey = GetRidOfurlCharacters(server.arg("LoginKey"));
        ShowMenueBar = GetRidOfurlCharacters(server.arg("showMenueBar"));
        otaUrl       = GetRidOfurlCharacters(server.arg("otaurl"));

        SaveDataToFile("WIFIname" , staName);
        SaveDataToFile("WIFIpass" , staPass);
        SaveDataToFile("APname" , apName);
        SaveDataToFile("APpass" , apPass);
        SaveDataToFile("LoginKey" , LoginKey);
        SaveDataToFile("ShowMenueBar" , ShowMenueBar);
        SaveDataToFile("otaUrl" , otaUrl);
      }

      if ( server.arg("format") == "Format" )
      {
        Serial.println("Formating ");
        Serial.print(SPIFFS.format());
      }

      WebOut.replace("*sta name*", staName);
      WebOut.replace("*sta pass*", staPass);
      WebOut.replace("*ap name*",  apName);
      WebOut.replace("*ap pass*",  apPass);
      WebOut.replace("*LoginKey*", LoginKey);

      WebOut.replace("*otaurl*", otaUrl);

      if ( ShowMenueBar == "off")
      {
        WebOut.replace("**checked**", "checked");
      }
      else
      {
        WebOut.replace("**checked**", "");
      }
    }

    server.send(200, "text/html", WebOut);
  });


  server.onFileUpload(handleFileUpdate);

  server.on("/filemng", []()
  {
    DoSomeFileManagerCode();
  });




  server.onNotFound ( []() {
    String fileNameToServeUp;
    fileNameToServeUp = GetRidOfurlCharacters(server.arg("file"));
    File mySuperFile = SPIFFS.open(String("uploads/" + fileNameToServeUp), "r");
    if (mySuperFile)
    {
      server.streamFile(mySuperFile, getContentType(fileNameToServeUp));
      //server.send(200, getContentType(fileNameToServeUp), mySuperFile.readString());

    }
    else
    {
      server.send(200, "text/html", AdminBarHTML);
    }
    mySuperFile.close();
  });

  if (  ConnectToTheWIFI(LoadDataFromFile("WIFIname"), LoadDataFromFile("WIFIpass"), "", "", "") == 0)
  {
    if (LoadDataFromFile("APname") == "")
    {
      CreateAP("", "");
    }
    else
    {
      CreateAP(LoadDataFromFile("APname"), LoadDataFromFile("APpass"));
    }
  }

    server.begin();
}

void loop() {
  // put your main code here, to run repeatedly:
  server.handleClient();
  delay(0);
}


String getContentType(String filename) {
  if (filename.endsWith(".htm")) return "text/html";
  else if (filename.endsWith(".html")) return "text/html";
  else if (filename.endsWith(".htm")) return "text/html";
  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";
}



void DoSomeFileManagerCode()
{
  String WholeUploadPage = UploadPage;
  String FileListForPage ;

  if (CheckIfLoggedIn())
  {
    WholeUploadPage = LogInPage;
  }
  else
  {
    if (server.arg("Delete") != "")
    {
      String FIleNameForDelete = server.arg("fileName");
      FIleNameForDelete = GetRidOfurlCharacters(FIleNameForDelete);
      Serial.println(FIleNameForDelete);
      SPIFFS.remove(FIleNameForDelete);
      //Serial.println(SPIFFS.remove("uploads/settings.png"));
    }

    Dir dir = SPIFFS.openDir(String("uploads" ));
    while (dir.next()) {
      FileListForPage += String("<option>" + dir.fileName() + "</option>");
      delay(0);
    }

    WholeUploadPage.replace("*table*", FileListForPage);

    if (server.arg("View") != "")
    {
      String FileNameToView = server.arg("fileName");
      FileNameToView = GetRidOfurlCharacters(FileNameToView);
      FileNameToView.replace("uploads/", "");
      WholeUploadPage = R"=====(  <meta http-equiv="refresh" content="0; url=./file?file=item" />)=====";
WholeUploadPage.replace("item", FileNameToView);
}

}
server.send(200, "text/html",  String( AdminBarHTML + WholeUploadPage ));
}

void handleFileUpdate()
{
  //if (server.uri() != "/edit") return;
  HTTPUpload& upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    String filename = upload.filename;
    //DBG_OUTPUT_PORT.print("Upload Name: "); DBG_OUTPUT_PORT.println(filename);
    fsUploadFile = SPIFFS.open(String("uploads/" + filename), "w");
    filename = String();
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    //DBG_OUTPUT_PORT.print("Upload Data: "); DBG_OUTPUT_PORT.println(upload.currentSize);
    if (fsUploadFile)
      fsUploadFile.write(upload.buf, upload.currentSize);
  } else if (upload.status == UPLOAD_FILE_END) {
    if (fsUploadFile)
      fsUploadFile.close();
    //DBG_OUTPUT_PORT.print("Upload Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
  }
}

//wifi code here

bool ConnectToTheWIFI(String NetworkName, String NetworkPassword, String NetworkStaticIP, String NetworkGateway, String NetworkSubnet)
{
  WiFi.mode(WIFI_STA);
  byte numberOfAtempts = 0;
  int str_len = NetworkName.length() + 1;
  char ssid[str_len];
  NetworkName.toCharArray(ssid, str_len);

  str_len = NetworkPassword.length() + 1;
  char password[str_len];
  NetworkPassword.toCharArray(password, str_len);


  // Connect to WiFi network
  WiFi.begin(ssid, password);

  // Wait for connection
  while (WiFi.status() != WL_CONNECTED) {
    numberOfAtempts = numberOfAtempts  + 1;
    delay(1000);
    Serial.println(numberOfAtempts);
    if (numberOfAtempts >= 12)
    {
      Serial.println("");
      Serial.println("Failed Wifi Connect ");
      return 0;
    }
  }






  if (WiFi.localIP().toString().endsWith(".0"))
  {
    Serial.println(WiFi.localIP());
    CreateAP("", "");
    return 0;
  }
  else
  {
    configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
    Serial.println("");
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address : ");
    Serial.println(WiFi.localIP());
    SaveDataToFile("WIFIname" ,  NetworkName);
    SaveDataToFile("WIFIpass", NetworkPassword);
    return 1;
  }


}




void CreateAP(String NetworkName, String NetworkPassword)
{
  WiFi.mode(WIFI_AP_STA);
  Serial.println("Creating WIFI access point");


  if (NetworkName == "")
  {
    NetworkName = LoadDataFromFile("APname");
    NetworkPassword = LoadDataFromFile("APpass");

    if (NetworkName == "")
    {
      NetworkName = "ESP";
      NetworkPassword = "";
    }
  }

  Serial.println(NetworkName);


  int str_len = NetworkName.length() + 1;
  char ssid[str_len];
  NetworkName.toCharArray(ssid, str_len);

  str_len = NetworkPassword.length() + 1;
  char password[str_len];
  NetworkPassword.toCharArray(password, str_len);

  WiFi.disconnect();
  delay(2000);
  if (NetworkPassword.length() < 8)
  {
    WiFi.softAP(ssid);
  }
  else
  {
    WiFi.softAP(ssid, password);
  }
  delay(2000);

  SaveDataToFile("APname" ,  NetworkName);
  SaveDataToFile("APpass", NetworkPassword);
}





//File System Stuff

void SaveDataToFile(String fileNameForSave, String DataToSave)
{
  Serial.println(fileNameForSave);
  //SPIFFS.begin();
  File f = SPIFFS.open(String(" /data/" + fileNameForSave + ".dat"), "w");
  if (!f)
  {
    Serial.println("file open failed");
  }
  else
  {
    f.println(String(DataToSave + String('\r')));
    f.close();
  }
  return;
}



String LoadDataFromFile(String fileNameForSave)
{
  String WhatIwillReturn;
  //SPIFFS.begin();
  File f = SPIFFS.open(String(" /data/" + fileNameForSave + ".dat"), "r");
  if (!f)
  {
    fileOpenFail = 1;
    //Serial.print("file open failed  :");
    //Serial.println(fileNameForSave);
  }
  else
  {
    fileOpenFail = 0;
    WhatIwillReturn =  f.readStringUntil('\r');
    WhatIwillReturn.replace("\n", "");
    f.close();
    return WhatIwillReturn;
  }
}


String GetRidOfurlCharacters(String urlChars)
{
  urlChars.replace("+",   " ");
  urlChars.replace("%2B", "+");
  urlChars.replace("%2F", "/");
  urlChars.replace("%21", "!");

  urlChars.replace("%0D%0A", String('\n'));

  urlChars.replace("%20", " ");
  urlChars.replace("%21", "!");
  urlChars.replace("%22", String(char('\"')));
  urlChars.replace("%23", "#");
  urlChars.replace("%24", "$");
  urlChars.replace("%25", "%");
  urlChars.replace("%26", "&");
  urlChars.replace("%27", String(char(39)));
  urlChars.replace("%28", "(");
  urlChars.replace("%29", ")");
  urlChars.replace("%2A", "*");
  urlChars.replace("%2B", "+");
  urlChars.replace("%2C", ",");
  urlChars.replace("%2D", "-");
  urlChars.replace("%2E", ".");
  urlChars.replace("%2F", "/");
  urlChars.replace("%30", "0");
  urlChars.replace("%31", "1");
  urlChars.replace("%32", "2");
  urlChars.replace("%33", "3");
  urlChars.replace("%34", "4");
  urlChars.replace("%35", "5");
  urlChars.replace("%36", "6");
  urlChars.replace("%37", "7");
  urlChars.replace("%38", "8");
  urlChars.replace("%39", "9");
  urlChars.replace("%3A", ":");
  urlChars.replace("%3B", ";");
  urlChars.replace("%3C", "<");
  urlChars.replace("%3D", "=");
  urlChars.replace("%3E", ">");
  urlChars.replace("%3F", "?");
  urlChars.replace("%40", "@");
  urlChars.replace("%41", "A");
  urlChars.replace("%42", "B");
  urlChars.replace("%43", "C");
  urlChars.replace("%44", "D");
  urlChars.replace("%45", "E");
  urlChars.replace("%46", "F");
  urlChars.replace("%47", "G");
  urlChars.replace("%48", "H");
  urlChars.replace("%49", "I");
  urlChars.replace("%4A", "J");
  urlChars.replace("%4B", "K");
  urlChars.replace("%4C", "L");
  urlChars.replace("%4D", "M");
  urlChars.replace("%4E", "N");
  urlChars.replace("%4F", "O");
  urlChars.replace("%50", "P");
  urlChars.replace("%51", "Q");
  urlChars.replace("%52", "R");
  urlChars.replace("%53", "S");
  urlChars.replace("%54", "T");
  urlChars.replace("%55", "U");
  urlChars.replace("%56", "V");
  urlChars.replace("%57", "W");
  urlChars.replace("%58", "X");
  urlChars.replace("%59", "Y");
  urlChars.replace("%5A", "Z");
  urlChars.replace("%5B", "[");
  urlChars.replace("%5C", String(char(65)));
  urlChars.replace("%5D", "]");
  urlChars.replace("%5E", "^");
  urlChars.replace("%5F", "_");
  urlChars.replace("%60", "`");
  urlChars.replace("%61", "a");
  urlChars.replace("%62", "b");
  urlChars.replace("%63", "c");
  urlChars.replace("%64", "d");
  urlChars.replace("%65", "e");
  urlChars.replace("%66", "f");
  urlChars.replace("%67", "g");
  urlChars.replace("%68", "h");
  urlChars.replace("%69", "i");
  urlChars.replace("%6A", "j");
  urlChars.replace("%6B", "k");
  urlChars.replace("%6C", "l");
  urlChars.replace("%6D", "m");
  urlChars.replace("%6E", "n");
  urlChars.replace("%6F", "o");
  urlChars.replace("%70", "p");
  urlChars.replace("%71", "q");
  urlChars.replace("%72", "r");
  urlChars.replace("%73", "s");
  urlChars.replace("%74", "t");
  urlChars.replace("%75", "u");
  urlChars.replace("%76", "v");
  urlChars.replace("%77", "w");
  urlChars.replace("%78", "x");
  urlChars.replace("%79", "y");
  urlChars.replace("%7A", "z");
  urlChars.replace("%7B", String(char(123)));
  urlChars.replace("%7C", "|");
  urlChars.replace("%7D", String(char(125)));
  urlChars.replace("%7E", "~");
  urlChars.replace("%7F", "Â");
  urlChars.replace("%80", "`");
  urlChars.replace("%81", "");
  urlChars.replace("%82", "‚");
  urlChars.replace("%83", "ƒ");
  urlChars.replace("%84", "„");
  urlChars.replace("%85", "…");
  urlChars.replace("%86", "â€");
  urlChars.replace("%87", "‡");
  urlChars.replace("%88", "ˆ");
  urlChars.replace("%89", "‰");
  urlChars.replace("%8A", "Å");
  urlChars.replace("%8B", "‹");
  urlChars.replace("%8C", "Œ");
  urlChars.replace("%8D", "");
  urlChars.replace("%8E", "Ž");
  urlChars.replace("%8F", "");
  urlChars.replace("%90", "");
  urlChars.replace("%91", "‘");
  urlChars.replace("%92", "’");
  urlChars.replace("%93", "“");
  urlChars.replace("%94", "”");
  urlChars.replace("%95", "•");
  urlChars.replace("%96", "–");
  urlChars.replace("%97", "—");
  urlChars.replace("%98", "˜");
  urlChars.replace("%99", "™");
  urlChars.replace("%9A", "Å¡");
  urlChars.replace("%9B", "›");
  urlChars.replace("%9C", "œ");
  urlChars.replace("%9D", "");
  urlChars.replace("%9E", "ž");
  urlChars.replace("%9F", "Ÿ");
  urlChars.replace("%A0", "Â");
  urlChars.replace("%A1", "¡");
  urlChars.replace("%A2", "¢");
  urlChars.replace("%A3", "£");
  urlChars.replace("%A4", "¤");
  urlChars.replace("%A5", "Â¥");
  urlChars.replace("%A6", "¦");
  urlChars.replace("%A7", "§");
  urlChars.replace("%A8", "¨");
  urlChars.replace("%A9", "©");
  urlChars.replace("%AA", "ª");
  urlChars.replace("%AB", "«");
  urlChars.replace("%AC", "¬");
  urlChars.replace("%AE", "®");
  urlChars.replace("%AF", "¯");
  urlChars.replace("%B0", "°");
  urlChars.replace("%B1", "±");
  urlChars.replace("%B2", "²");
  urlChars.replace("%B3", "³");
  urlChars.replace("%B4", "´");
  urlChars.replace("%B5", "µ");
  urlChars.replace("%B6", "¶");
  urlChars.replace("%B7", "·");
  urlChars.replace("%B8", "¸");
  urlChars.replace("%B9", "¹");
  urlChars.replace("%BA", "º");
  urlChars.replace("%BB", "»");
  urlChars.replace("%BC", "¼");
  urlChars.replace("%BD", "½");
  urlChars.replace("%BE", "¾");
  urlChars.replace("%BF", "¿");
  urlChars.replace("%C0", "À");
  urlChars.replace("%C1", "Á");
  urlChars.replace("%C2", "Â");
  urlChars.replace("%C3", "Ã");
  urlChars.replace("%C4", "Ä");
  urlChars.replace("%C5", "Å");
  urlChars.replace("%C6", "Æ");
  urlChars.replace("%C7", "Ç");
  urlChars.replace("%C8", "È");
  urlChars.replace("%C9", "É");
  urlChars.replace("%CA", "Ê");
  urlChars.replace("%CB", "Ë");
  urlChars.replace("%CC", "Ì");
  urlChars.replace("%CD", "Í");
  urlChars.replace("%CE", "Î");
  urlChars.replace("%CF", "Ï");
  urlChars.replace("%D0", "Ð");
  urlChars.replace("%D1", "Ñ");
  urlChars.replace("%D2", "Ò");
  urlChars.replace("%D3", "Ó");
  urlChars.replace("%D4", "Ô");
  urlChars.replace("%D5", "Õ");
  urlChars.replace("%D6", "Ö");
  urlChars.replace("%D7", "×");
  urlChars.replace("%D8", "Ø");
  urlChars.replace("%D9", "Ù");
  urlChars.replace("%DA", "Ú");
  urlChars.replace("%DB", "Û");
  urlChars.replace("%DC", "Ü");
  urlChars.replace("%DD", "Ý");
  urlChars.replace("%DE", "Þ");
  urlChars.replace("%DF", "ß");
  urlChars.replace("%E0", "Ã");
  urlChars.replace("%E1", "á");
  urlChars.replace("%E2", "â");
  urlChars.replace("%E3", "ã");
  urlChars.replace("%E4", "ä");
  urlChars.replace("%E5", "Ã¥");
  urlChars.replace("%E6", "æ");
  urlChars.replace("%E7", "ç");
  urlChars.replace("%E8", "è");
  urlChars.replace("%E9", "é");
  urlChars.replace("%EA", "ê");
  urlChars.replace("%EB", "ë");
  urlChars.replace("%EC", "ì");
  urlChars.replace("%ED", "í");
  urlChars.replace("%EE", "î");
  urlChars.replace("%EF", "ï");
  urlChars.replace("%F0", "ð");
  urlChars.replace("%F1", "ñ");
  urlChars.replace("%F2", "ò");
  urlChars.replace("%F3", "ó");
  urlChars.replace("%F4", "ô");
  urlChars.replace("%F5", "õ");
  urlChars.replace("%F6", "ö");
  urlChars.replace("%F7", "÷");
  urlChars.replace("%F8", "ø");
  urlChars.replace("%F9", "ù");
  urlChars.replace("%FA", "ú");
  urlChars.replace("%FB", "û");
  urlChars.replace("%FC", "ü");
  urlChars.replace("%FD", "ý");
  urlChars.replace("%FE", "þ");
  urlChars.replace("%FF", "ÿ");

  return urlChars;
}



bool CheckIfLoggedIn()
{
  if (LoadDataFromFile("LoginKey") != "")
  {
    if ( millis() > LoggedIn + 600000 || LoggedIn == 0 )     return 1;
  }
  return 0;
}
User avatar
By Qubit
#48078 Did you find a solution in the mean time?

here is how i solved it

Code: Select all#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include "spiffs/spiffs.h"
#include <FS.h>


const char* ssid = "...";
const char* password = "...";

ESP8266WebServer server(80);
const char* serverIndex = "<form method='POST' action='/upload' enctype='multipart/form-data'><input type='file' name='update'><input type='submit' value='Update'></form>";
File fsUploadFile;

void handleFileUpload()
{
  if(server.uri() != "/upload") return;
  HTTPUpload& upload = server.upload();
  if(upload.status == UPLOAD_FILE_START){
    String filename = upload.filename;
    if(!filename.startsWith("/")) filename = "/"+filename;
    Serial.print("handleFileUpload Name: ");
    Serial.println(filename);
    fsUploadFile = SPIFFS.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();
    Serial.print("handleFileUpload Size: ");
    Serial.println(upload.totalSize);
  }
}

void handleListFiles()
{
  String FileList = "File List:\n";
 
  Dir dir = SPIFFS.openDir("/");
  Serial.println("File List:");
  while (dir.next())
  {
    String FileName = dir.fileName();
    File f = dir.openFile("r");
    String FileSize = String(f.size());
    int whsp = 6-FileSize.length();
    while(whsp-->0)
    {
      Serial.print(" ");
      FileList += " ";
    }
    Serial.println(FileSize+" "+FileName);
    FileList += FileSize+" "+FileName+"\n";
  }     
  server.sendHeader("Connection", "close");
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "text/plain", FileList);
}

void setup(void)
{
  SPIFFS.begin();
  Serial.begin(115200);
  Serial.println("Welcome to WebServer File System");
  Serial.println("");
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() == WL_CONNECTED)
  {
    Serial.print("Local IP: ");
    Serial.println(WiFi.localIP());
    server.on("/", HTTP_GET, []() {
      server.sendHeader("Connection", "close");
      server.sendHeader("Access-Control-Allow-Origin", "*");
      server.send(200, "text/html", serverIndex);
    });
    server.on("/list", HTTP_GET, handleListFiles);
    server.onFileUpload(handleFileUpload);
    server.on("/upload", HTTP_POST, []() {
      server.sendHeader("Connection", "close");
      server.sendHeader("Access-Control-Allow-Origin", "*");
      server.send(200, "text/plain", "OK");
    });
    server.begin();
  }
}

void loop(void) {
  server.handleClient();
  delay(0);
}