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

Moderator: igrr

User avatar
By namirda
#60428 Hi,

I asked this question in another thread a few days ago but I think I may have put it in the wrong place. Perhaps here is more appropriate...?

I am trying to retrieve data from a <textarea> on an HTML form and save it to SPIFFS. I am using the ESP8266Webserver library and am successfully reading data on the server using the function :

Code: Select allString myData=WebServer.arg("Name");


and subsequently writing the data to SPIFFS. This approach requires the String myData to be as large as the <textarea> which obviously becomes problematic as the size of the POST increases.

Is there any way to transfer the data from the client to the server in smaller blocks which could then be sequentially written to SPIFFS thereby avoiding the large String?

Thanks for your help...

n
User avatar
By mrburnette
#60470 Probably of no help to you, but it appears the LUA folks have solved the issue of large file transfers:

http://www.esp8266.com/viewtopic.php?p=39666

However, while doing some google searches trying to find a ready-made answer, I did run across this post which I thought very interesting and maybe applicable to your situation:
http://www.esp8266.com/viewtopic.php?p=26486

But, a subsequent qoogle result perhaps is an answer to your question:
http://www.esp8266.com/viewtopic.php?p=39952

I didn't want to load the whole file at once since memory is so scarce, so I wound up just looking at how the WebServer library constructs its response, and sending the data one block at a time with the client's write() method.


... and finally the above chain led me to thisSD Card webserver - both read/write.

Code: Select all/*
  SDWebServer - Example WebServer with SD Card backend for esp8266
  Copyright (c) 2015 Hristo Gochkov. All rights reserved.
  This file is part of the ESP8266WebServer library for Arduino environment.
  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.
  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.
  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  Have a FAT Formatted SD Card connected to the SPI port of the ESP8266
  The web root is the SD Card root folder
  File extensions with more than 3 charecters are not supported by the SD Library
  File Names longer than 8 charecters will be truncated by the SD library, so keep filenames shorter
  index.htm is the default index (works on subfolders as well)
  upload the contents of SdRoot to the root of the SDcard and access the editor by going to http://esp8266sd.local/edit
*/
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <SPI.h>
#include <SD.h>

#define DBG_OUTPUT_PORT Serial

const char* ssid = "**********";
const char* password = "**********";
const char* host = "esp8266sd";

ESP8266WebServer server(80);

static bool hasSD = false;
File uploadFile;


void returnOK() {
  server.send(200, "text/plain", "");
}

void returnFail(String msg) {
  server.send(500, "text/plain", msg + "\r\n");
}

bool loadFromSdCard(String path){
  String dataType = "text/plain";
  if(path.endsWith("/")) path += "index.htm";

  if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
  else if(path.endsWith(".htm")) dataType = "text/html";
  else if(path.endsWith(".css")) dataType = "text/css";
  else if(path.endsWith(".js")) dataType = "application/javascript";
  else if(path.endsWith(".png")) dataType = "image/png";
  else if(path.endsWith(".gif")) dataType = "image/gif";
  else if(path.endsWith(".jpg")) dataType = "image/jpeg";
  else if(path.endsWith(".ico")) dataType = "image/x-icon";
  else if(path.endsWith(".xml")) dataType = "text/xml";
  else if(path.endsWith(".pdf")) dataType = "application/pdf";
  else if(path.endsWith(".zip")) dataType = "application/zip";

  File dataFile = SD.open(path.c_str());
  if(dataFile.isDirectory()){
    path += "/index.htm";
    dataType = "text/html";
    dataFile = SD.open(path.c_str());
  }

  if (!dataFile)
    return false;

  if (server.hasArg("download")) dataType = "application/octet-stream";

  if (server.streamFile(dataFile, dataType) != dataFile.size()) {
    DBG_OUTPUT_PORT.println("Sent less data than expected!");
  }

  dataFile.close();
  return true;
}

void handleFileUpload(){
  if(server.uri() != "/edit") return;
  HTTPUpload& upload = server.upload();
  if(upload.status == UPLOAD_FILE_START){
    if(SD.exists((char *)upload.filename.c_str())) SD.remove((char *)upload.filename.c_str());
    uploadFile = SD.open(upload.filename.c_str(), FILE_WRITE);
    DBG_OUTPUT_PORT.print("Upload: START, filename: "); DBG_OUTPUT_PORT.println(upload.filename);
  } else if(upload.status == UPLOAD_FILE_WRITE){
    if(uploadFile) uploadFile.write(upload.buf, upload.currentSize);
    DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: "); DBG_OUTPUT_PORT.println(upload.currentSize);
  } else if(upload.status == UPLOAD_FILE_END){
    if(uploadFile) uploadFile.close();
    DBG_OUTPUT_PORT.print("Upload: END, Size: "); DBG_OUTPUT_PORT.println(upload.totalSize);
  }
}

void deleteRecursive(String path){
  File file = SD.open((char *)path.c_str());
  if(!file.isDirectory()){
    file.close();
    SD.remove((char *)path.c_str());
    return;
  }

  file.rewindDirectory();
  while(true) {
    File entry = file.openNextFile();
    if (!entry) break;
    String entryPath = path + "/" +entry.name();
    if(entry.isDirectory()){
      entry.close();
      deleteRecursive(entryPath);
    } else {
      entry.close();
      SD.remove((char *)entryPath.c_str());
    }
    yield();
  }

  SD.rmdir((char *)path.c_str());
  file.close();
}

void handleDelete(){
  if(server.args() == 0) return returnFail("BAD ARGS");
  String path = server.arg(0);
  if(path == "/" || !SD.exists((char *)path.c_str())) {
    returnFail("BAD PATH");
    return;
  }
  deleteRecursive(path);
  returnOK();
}

void handleCreate(){
  if(server.args() == 0) return returnFail("BAD ARGS");
  String path = server.arg(0);
  if(path == "/" || SD.exists((char *)path.c_str())) {
    returnFail("BAD PATH");
    return;
  }

  if(path.indexOf('.') > 0){
    File file = SD.open((char *)path.c_str(), FILE_WRITE);
    if(file){
      file.write((const char *)0);
      file.close();
    }
  } else {
    SD.mkdir((char *)path.c_str());
  }
  returnOK();
}

void printDirectory() {
  if(!server.hasArg("dir")) return returnFail("BAD ARGS");
  String path = server.arg("dir");
  if(path != "/" && !SD.exists((char *)path.c_str())) return returnFail("BAD PATH");
  File dir = SD.open((char *)path.c_str());
  path = String();
  if(!dir.isDirectory()){
    dir.close();
    return returnFail("NOT DIR");
  }
  dir.rewindDirectory();
  server.setContentLength(CONTENT_LENGTH_UNKNOWN);
  server.send(200, "text/json", "");
  WiFiClient client = server.client();

  server.sendContent("[");
  for (int cnt = 0; true; ++cnt) {
    File entry = dir.openNextFile();
    if (!entry)
    break;

    String output;
    if (cnt > 0)
      output = ',';

    output += "{\"type\":\"";
    output += (entry.isDirectory()) ? "dir" : "file";
    output += "\",\"name\":\"";
    output += entry.name();
    output += "\"";
    output += "}";
    server.sendContent(output);
    entry.close();
 }
 server.sendContent("]");
 dir.close();
}

void handleNotFound(){
  if(hasSD && loadFromSdCard(server.uri())) return;
  String message = "SDCARD Not Detected\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += (server.method() == HTTP_GET)?"GET":"POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for (uint8_t i=0; i<server.args(); i++){
    message += " NAME:"+server.argName(i) + "\n VALUE:" + server.arg(i) + "\n";
  }
  server.send(404, "text/plain", message);
  DBG_OUTPUT_PORT.print(message);
}

void setup(void){
  DBG_OUTPUT_PORT.begin(115200);
  DBG_OUTPUT_PORT.setDebugOutput(true);
  DBG_OUTPUT_PORT.print("\n");
  WiFi.begin(ssid, password);
  DBG_OUTPUT_PORT.print("Connecting to ");
  DBG_OUTPUT_PORT.println(ssid);

  // Wait for connection
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) {//wait 10 seconds
    delay(500);
  }
  if(i == 21){
    DBG_OUTPUT_PORT.print("Could not connect to");
    DBG_OUTPUT_PORT.println(ssid);
    while(1) delay(500);
  }
  DBG_OUTPUT_PORT.print("Connected! IP address: ");
  DBG_OUTPUT_PORT.println(WiFi.localIP());

  if (MDNS.begin(host)) {
    MDNS.addService("http", "tcp", 80);
    DBG_OUTPUT_PORT.println("MDNS responder started");
    DBG_OUTPUT_PORT.print("You can now connect to http://");
    DBG_OUTPUT_PORT.print(host);
    DBG_OUTPUT_PORT.println(".local");
  }


  server.on("/list", HTTP_GET, printDirectory);
  server.on("/edit", HTTP_DELETE, handleDelete);
  server.on("/edit", HTTP_PUT, handleCreate);
  server.on("/edit", HTTP_POST, [](){ returnOK(); }, handleFileUpload);
  server.onNotFound(handleNotFound);

  server.begin();
  DBG_OUTPUT_PORT.println("HTTP server started");

  if (SD.begin(SS)){
     DBG_OUTPUT_PORT.println("SD Card initialized.");
     hasSD = true;
  }
}

void loop(void){
  server.handleClient();
}
User avatar
By GengusKahn
#60499 Hi there, if you pick through the sketch here I am moving varying sizes of data files to and from different pages using this as a gateway.
If you have any questions feel free, although my presence is a little sporadic.....

Device page...http://82.5.78.180:5080/diag

Code: Select all

#include <WiFiClient.h>
#include <ESP8266WiFi.h>
#include <FS.h>
WiFiServer server(80);
WiFiClient client;
const char* ssid = "Network-SSID";
const char* password = "PassKey";


File theFile;

unsigned long ulNextWeath_ms;
unsigned long ulWMeasDelta_ms = 60000;
unsigned long Dfsize;

String tmtxt1,tmtxt2;

// needed to avoid link error on ram check
extern "C"
{
#include "user_interface.h"
}
ADC_MODE(ADC_VCC);
//format bytes
String formatBytes(size_t bytes){
  if (bytes < 1024){
    return String(bytes)+"B";
  } else if(bytes < (1024 * 1024)){
    return String(bytes/1024.0)+"KB";
  } else if(bytes < (1024 * 1024 * 1024)){
    return String(bytes/1024.0/1024.0)+"MB";
  } else {
    return String(bytes/1024.0/1024.0/1024.0)+"GB";
  }
}



void getfile() {
WiFiClient cl;
File theFile;
  Serial.println("connecting to PWS...");
  //http://82.5.78.180:5080/realtime
// The Start of the Routine to clollect the data...........

    // if you get a connection, report back via serial:
    if (cl.connect("emonitor.16mb.com", 80)) { 
    Serial.println("connected");
    // Make a HTTP request:

    // send the HTTP GET request:
    cl.println("GET /realtimegauges.txt HTTP/1.1");
    cl.println("Host: emonitor.16mb.com");
    cl.println("User-Agent: arduino-ethernet");
    cl.println("Connection: close");
    cl.println();
    }
  else {
    // didn't get a connection to the server:
    Serial.println("connection failed");
  }
  // Wait until the client sends some data
  unsigned long ultimeout = millis()+300;
  while(!cl.available() && (millis()<ultimeout) )
  {
    delay(1);
  }
  if(millis()>ultimeout)
  {
    return;
  }

    while (cl.available()) {
    char c = cl.read();
    Serial.write(c);
    if (c == '{') {  // First Tag.....
// Use a marker for self constructed formats, I am using this as it works for stripping the header and my files
// end of HTTP header, now save requested file
// open the file for writing
  theFile = SPIFFS.open("/realtime.txt", "w");  // change file name to write to here
  if (!theFile) {
    Serial.println("Could not create file");
    while (1);
  }
  theFile.print("{");   
       
      while (cl.available()) {
        // stay in this loop until the file has been received

         String linew = cl.readStringUntil('\n');  // get data
                 
          theFile.println(linew);   // save data to file   
    }
   }
  }
  // if the server's disconnected, stop the client:
    cl.flush();
    delay(10);
    cl.stop();
    theFile.close();
}


void getfile1() {
WiFiClient cli;
File theFile;
  Serial.println("connecting to PWS...");
 
// The Start of the Routine to clollect the data...........

    // if you get a connection, report back via serial:
    if (cli.connect("emonitor.16mb.com", 80)) { 
    Serial.println("connected");
    // Make a HTTP request:

    // send the HTTP GET request:
    cli.println("GET /realtime.txt HTTP/1.1");
    cli.println("Host: emonitor.16mb.com");
    cli.println("User-Agent: arduino-ethernet");
    cli.println("Connection: close");
    cli.println();
    }
  else {
    // didn't get a connection to the server:
    Serial.println("connection failed");
  }

  // Wait until the client sends some data
  unsigned long ultimeout = millis()+250;
  while(!cli.available() && (millis()<ultimeout) )
  {
    delay(1);
  }
  if(millis()>ultimeout)
  {
    return;
  }
  String LinI="";
  int llc=0;
    while (cli.available()) {
    char c = cli.read();
    Serial.write(c);
    LinI+=c;
    if(c=='\n'){
    llc++;
    if(llc<10){LinI="";}
    if (llc == 10 || llc == 11) {  // First Tag.....
// Use a marker for self constructed formats, I am using this as it works for stripping the header, text on 10th line
// end of HTTP header, now save requested file
// Here we open the file for writing, if the data is valid....
  char thisChar = LinI.charAt(0);
  if (isDigit(thisChar)) {
      llc=12;
  theFile = SPIFFS.open("/real.txt", "a");  // change file name to write to here
  if (!theFile) {
    Serial.println("Could not create file");
    while (1);
  }
          theFile.println(LinI);   // save data to file
          theFile.close(); // Close the file !!!
          delay(100);
  theFile = SPIFFS.open("/cumulus.txt", "w");  // change file name to write to here
  if (!theFile) {
    Serial.println("Could not create file");
    while (1);
  }
          theFile.println(LinI);   // save data to file
          theFile.close(); // Close the file !!!
    }
   }
      LinI="";
  }
 }
    cli.flush();
    delay(10);
    cli.stop();
}


///////////////////
// (re-)start WiFi
///////////////////
void WiFiStart()
{
  int Lc=0;
  // Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Lc++;
    if(Lc==30){
      ESP.restart();
    }
  }
  // Start the server
  server.begin();
}



void setup() {

 
  Serial.begin (9600);
  Serial.set_tx(2);
  Serial.println("");
  WiFi.begin(ssid, password);
  Serial.print("Connecting to ");
  Serial.println(ssid);

  // Wait for connection
  uint8_t i = 0;
  while (WiFi.status() != WL_CONNECTED && i++ < 20) {//wait 10 seconds
    delay(500);
  }
  if(i == 21){
    Serial.print("Could not connect to");
    Serial.println(ssid);
    while(1) delay(500);
  }
  Serial.print("Connected! IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println(F("Initializing File System..."));
  server.begin();
    SPIFFS.begin();
  {
    Dir dir = SPIFFS.openDir("/");
    while (dir.next()) {   
      String fileName = dir.fileName();
      size_t fileSize = dir.fileSize();
      Serial.printf("FS File: %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
    }
    Serial.printf("\n");
  }
     // SPIFFS.format();
delay(50); //  Setup file from weather station
File in = SPIFFS.open("/temp.txt", "w");
in.close();
delay(50);
in = SPIFFS.open("/cumulus.txt", "w");
in.close();
delay(50);
in = SPIFFS.open("/real.txt", "w");
in.close();
delay(500);
    getfile();
      delay(2500);
    getfile1();
  delay(1000); 
  ulNextWeath_ms = millis()+ulWMeasDelta_ms;
 
}

void dailyboot(){
                                int hr,mn,st;
                                st = millis() / 1000;
                                mn = st / 60;
                                hr = st / 3600;
                                st = st - mn * 60;
                                mn = mn - hr * 60;
                                if (hr==24) {ESP.restart();}
}

void loop() {

  if (millis()>=ulNextWeath_ms)
  {
    dailyboot(); 
    ulNextWeath_ms = millis()+ulWMeasDelta_ms;
    // Get the Weather data
    delay(50);   
    getfile();
    delay(2500);
    getfile1();
    delay(250);

  }

  //////////////////////////////
  // check if WLAN is connected
  //////////////////////////////
 
  if (WiFi.status() != WL_CONNECTED)
  {
    WiFiStart();
  }
 
  ///////////////////////////////////
  // Check if a client has connected
  ///////////////////////////////////
  WiFiClient client = server.available();
  if (!client)
  {
    return;
  }
 
  // Wait until the client sends some data
  unsigned long ultimeout = millis()+250;
  while(!client.available() && (millis()<ultimeout) )
  {
    delay(1);
  }
  if(millis()>ultimeout)
  {
    return;
  }
 
  /////////////////////////////////////
  // Read the first line of the request
  /////////////////////////////////////
  String sRequest = client.readStringUntil('\r');
  client.flush();
 
  // stop client, if request is empty
  if(sRequest=="")
  {
    client.stop();
    return;
  }
 
  // get path; end of path is either space or ?
  // Syntax is e.g. GET /?show=1234 HTTP/1.1
  String sPath="",sParam="", sCmd="";
  String sGetstart="GET ";
  int iStart,iEndSpace,iEndQuest;
  iStart = sRequest.indexOf(sGetstart);
  if (iStart>=0)
  {
    iStart+=+sGetstart.length();
    iEndSpace = sRequest.indexOf(" ",iStart);
    iEndQuest = sRequest.indexOf("?",iStart);
   
    // are there parameters?
    if(iEndSpace>0)
    {
      if(iEndQuest>0)
      {
        // there are parameters
        sPath  = sRequest.substring(iStart,iEndQuest);
        sParam = sRequest.substring(iEndQuest,iEndSpace);
      }
      else
      {
        // NO parameters
        sPath  = sRequest.substring(iStart,iEndSpace);
      }
    }
  }
 
if (sPath.startsWith("/index")){
   client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                       File thefile = SPIFFS.open("/index.htm", "r");        // open web page file
                            while(thefile.available()) {
                               client.print(thefile.readStringUntil('\n')); // send web page to client
                              }
                              thefile.close();                                     
                        client.println();
}
else if (sPath.startsWith("/realtime"))
  {// http://82.5.78.180:5080/realtime
   
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/plain");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                       File thefile = SPIFFS.open("/realtime.txt", "r");        // open web page file
                            while(thefile.available()) {
                               client.print(thefile.readStringUntil('\n')); // send web page to client
                              }
                              thefile.close();                                     
                        client.println();
}else if (sPath.startsWith("/txtrealtime"))
  {// http://82.5.78.180:5080/txtrealtime
   
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/plain");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                       File thefile = SPIFFS.open("/real.txt", "r");        // open web page file
                            while(thefile.available()) {
                               client.print(thefile.readStringUntil('\n')); // send web page to client
                              }
                              thefile.close();                                     
                        client.println();
}else if (sPath.startsWith("/cumulus.txt"))
  {// http://82.5.78.180:5080/txtrealtime
   
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/plain");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                       File thefile = SPIFFS.open("/cumulus.txt", "r");        // open web page file
                            while(thefile.available()) {
                               client.print(thefile.readStringUntil('\n')); // send web page to client
                              }
                              thefile.close();                                     
                        client.println();
}else if (sPath.startsWith("/read_ajax"))
  {//  The data saved by GET /ajax_inputs below....
   
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/plain");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                       File thefile = SPIFFS.open("/temp.txt", "r");        // open web page file
                            while(thefile.available()) {
                               client.print(thefile.readStringUntil('\n')); // send web page to client
                              }
                              thefile.close();                                     
                        client.println();
}
else if(sPath=="/chart0.htm")
  {
   
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                        File webFile = SPIFFS.open("/chart0.htm", "r");        // open web page file
                            while(webFile.available()) {
                                client.print(webFile.readStringUntil('\n')); // send web page to client
                              }
                              webFile.close();                                     
                        client.println();
}
else if(sPath=="/chart1.htm")
  {
       
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                        File webFile = SPIFFS.open("/chart1.htm", "r");        // open web page file
                            while(webFile.available()) {
                                client.print(webFile.readStringUntil('\n')); // send web page to client
                              }
                              webFile.close();                                     
                        client.println();
}
else if(sPath=="/chart2.htm")
  {
   
   
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                        File webFile = SPIFFS.open("/chart2.htm", "r");        // open web page file
                            while(webFile.available()) {
                                client.print(webFile.readStringUntil('\n')); // send web page to client
                              }
                              webFile.close();                                     
                        client.println();
}
else if(sPath=="/chart3.htm")
  {
       
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                        File webFile = SPIFFS.open("/chart3.htm", "r");        // open web page file
                            while(webFile.available()) {
                                client.print(webFile.readStringUntil('\n')); // send web page to client
                              }
                              webFile.close();                                     
                        client.println();
}
else if(sPath=="/chart4.htm")
  {
       
                        client.println("HTTP/1.1 200 OK");
                        client.println("Content-Type: text/html");
                        client.println("Connection: close");
                         // client.println("Connection: keep-alive");
                        client.println("Access-Control-Allow-Origin: *");
                        client.println("Access-Control-Allow-Methods: GET");
                        client.println("Access-Control-Allow-Headers: Content-Type");
                        client.println("Access-Control-Max-Age: 500");
 
                        client.println();
                        // send web page
                        File webFile = SPIFFS.open("/chart4.htm", "r");        // open web page file
                            while(webFile.available()) {
                                client.print(webFile.readStringUntil('\n')); // send web page to client
                              }
                              webFile.close();                                     
                        client.println();
}
else if(sPath=="/diag")
  {   
     float   servolt1 = ESP.getVcc();
     long int spdcount = ESP.getCycleCount();
     delay(1);
     long int spdcount1 = ESP.getCycleCount();
     long int speedcnt = spdcount1-spdcount;
     FlashMode_t ideMode = ESP.getFlashChipMode();

                         String duration1 = "";
                                int hr,mn,st;
                                st = millis() / 1000;
                                mn = st / 60;
                                hr = st / 3600;
                                st = st - mn * 60;
                                mn = mn - hr * 60;
                                if (hr<10) {duration1 += ("0");}
                                duration1 += (hr);
                                duration1 += (":");
                                if (mn<10) {duration1 += ("0");}
                                duration1 += (mn);
                                duration1 += (":");
                                if (st<10) {duration1 += ("0");}
                                duration1 += (st);     
                                client.println("HTTP/1.1 200 OK");
                                client.println("Content-Type: text/html");
                                client.println("Connection: close");
                                client.println();
                                client.println("<!DOCTYPE HTML>");
                                client.print("<html><head><title>Environment Monitor</title></head><body>");
                                client.print("<font color=\"#000000\"><body bgcolor=\"#a0dFfe\">");
                                client.print("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=yes\">");
                                client.print("<h1>Environment Monitor<BR>SDK Diagnostic Information</h1><BR><a href=\"/txtrealtime\">Open Cumulus Realtime.txt LOG</a><BR><a href=\"/cumulus.txt\">Latest Cumulus Realtime.txt</a>");
                                client.println("<BR><a href=\"/realtime\">JSON Realtime Download Page</a><BR><a href=\"/read_ajax\">Remotely Logged Data</a><BR><a href=\"/index\">Weather Gauges & Charts</a>");
                               String diagdat="";
                                diagdat+="<BR>  WiFi Station Hostname = ";
                                diagdat+=wifi_station_get_hostname();
                                diagdat+="<BR>  Free RAM = ";
                                client.print(diagdat);
                                client.println((uint32_t)system_get_free_heap_size()/1024);
                                diagdat=" KBytes<BR>";
                                diagdat+="  SDK Version = ";                                 
                                diagdat+=ESP.getSdkVersion();
                                diagdat+="<BR>  Boot Version = ";
                                diagdat+=ESP.getBootVersion();
                                diagdat+="<BR>  Free Sketch Space  = ";
                                diagdat+=ESP.getFreeSketchSpace()/1024;
                                diagdat+=" KBytes<BR>  Sketch Size  = ";
                                diagdat+=ESP.getSketchSize()/1024;
                                diagdat+=" KBytes<BR>";
                                client.println(diagdat);
                                client.printf("  Flash Chip id = %08X\n", ESP.getFlashChipId());
                                client.print("<BR>");
                                client.printf("  Flash Chip Mode = %s\n", (ideMode == FM_QIO ? "QIO" : ideMode == FM_QOUT ? "QOUT" : ideMode == FM_DIO ? "DIO" : ideMode == FM_DOUT ? "DOUT" : "UNKNOWN"));
                                diagdat="<BR>  Flash Size By ID = ";
                                diagdat+=ESP.getFlashChipRealSize()/1024;
                                diagdat+=" KBytes<BR>  Flash Size (IDE) = ";
                                diagdat+=ESP.getFlashChipSize()/1024;
                                diagdat+=" KBytes<BR>  Flash Speed = ";
                                diagdat+=ESP.getFlashChipSpeed()/1000000;
                                diagdat+=" MHz<BR>  ESP8266 CPU Speed = ";
                                diagdat+=ESP.getCpuFreqMHz();
                                diagdat+=" MHz<BR>";
                                client.print(diagdat);
                                client.printf("  ESP8266 Chip id = %08X\n", ESP.getChipId());
                                diagdat="<BR>  System Instruction Cycles Per Second = ";
                                diagdat+=speedcnt*1000;
                                diagdat+="<BR>  Last System Restart Reason = ";
                                diagdat+=ESP.getResetInfo();                               
                                diagdat+="<BR>  System VCC = ";
                                diagdat+=servolt1/1000, 3;
                                diagdat+=" V <BR>";
                                client.print(diagdat);
                                client.print(" Files in use (3MB FS): <br>");
    Dir dir = SPIFFS.openDir("/");
    while (dir.next()) {   
      String fileName = dir.fileName();
      size_t fileSize = dir.fileSize();
      client.printf("  %s, size: %s\n", fileName.c_str(), formatBytes(fileSize).c_str());
      client.print("<br>");
    }
                                diagdat="<BR>  System Uptime = ";
                                diagdat+=duration1;
                                client.print(diagdat);
                                client.print("<BR><FONT SIZE=-2>environmental.monitor.log@gmail.com<BR><FONT SIZE=-2>ESP8266<BR><FONT SIZE=-2>Compiled Using ver. 2.3.0, built October, 2016<BR>");
                                client.println("<IMG SRC=\"https://raw.githubusercontent.com/genguskahn/ESP8266-For-DUMMIES/master/SoC/DimmerDocs/organicw.gif\" WIDTH=\"250\" HEIGHT=\"151\" BORDER=\"1\"></body></html>");
                                diagdat="";
  }else if(sPath.startsWith("/ajax_inputs&L1="))
   {// Writing data to a file in spiffs, read via /read_ajax
  client.println("HTTP/1.1 304 OK");
  client.println("Connection: close");   
     tmtxt1="";
     tmtxt2="";
File in = SPIFFS.open("/temp1.txt", "w");     
  if (in) {
    in.print(sPath);
    in.close();
      }
    else {
      while(1);
    }
     in = SPIFFS.open("/temp1.txt", "r");
     in.setTimeout(0);
String Dtmtxt = in.readStringUntil('=');
       tmtxt1 += in.readStringUntil('&');
       Dtmtxt = in.readStringUntil('=');
       tmtxt2 += in.readStringUntil('&');
     in.close();
     delay(100);
in = SPIFFS.open("/temp.txt", "a");     
  if (in) {
    tmtxt1.replace("%20", " ");
    tmtxt2.replace("%20", " ");
    in.print(tmtxt1);
    in.print(",");
    in.println(tmtxt2);
    in.close();
      }
    else {
      while(1);
    }       
   }
else
////////////////////////////
// 404 for non-matching path
////////////////////////////
  {
    String sResponse="<html><head><title>404 Not Found</title></head><body><h1><img src=\"http://82.5.78.180:5050/img/flame.gif\" style=\"width:50px;position:relative;top:8px;\">Not<img src=\"http://82.5.78.180:5050/img/flame.gif\" style=\"width:50px;position:relative;top:8px;\"><BR>:-( Here )-:</h1><p>The requested URL was not found on this server, What did you ask for?.</p></body></html>";
   
    String sHeader  = F("HTTP/1.1 200 OK\r\nContent-Length: ");
    sHeader += sResponse.length();
    sHeader += F("\r\nContent-Type: text/html\r\nConnection: close\r\n\r\n");
   
    // Send the response to the client
    client.print(sHeader);
    client.print(sResponse);
  }
 
  // and stop the client
  client.stop();
    if (millis()>=Dfsize){
    Dfsize=millis()+300000;
    dailyboot();
  }
}

User avatar
By namirda
#60577 Thank you both - gave me some ideas.

After some digging I found that the main culprit as far as memory use is concerned is the _parseRequest method of the ESP8266WebServer class which assigns arguments to Strings. This is called from handleClient which is normally placed in the loop.

If I want to continue to use ESP8266WebServer I think the only way is to create a new derived class based on ESP8266WebServer and override a few base methods.

n